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_EH_RETURN 37)
105 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
106 (UNSPEC_TRUNC_NOOP 39)
108 ; For SSE/MMX support:
109 (UNSPEC_FIX_NOTRUNC 40)
126 (UNSPEC_MS_TO_SYSV_CALL 48)
128 ; Generic math support
130 (UNSPEC_IEEE_MIN 51) ; not commutative
131 (UNSPEC_IEEE_MAX 52) ; not commutative
146 (UNSPEC_FRNDINT_FLOOR 70)
147 (UNSPEC_FRNDINT_CEIL 71)
148 (UNSPEC_FRNDINT_TRUNC 72)
149 (UNSPEC_FRNDINT_MASK_PM 73)
150 (UNSPEC_FIST_FLOOR 74)
151 (UNSPEC_FIST_CEIL 75)
153 ; x87 Double output FP
154 (UNSPEC_SINCOS_COS 80)
155 (UNSPEC_SINCOS_SIN 81)
156 (UNSPEC_XTRACT_FRACT 84)
157 (UNSPEC_XTRACT_EXP 85)
158 (UNSPEC_FSCALE_FRACT 86)
159 (UNSPEC_FSCALE_EXP 87)
171 (UNSPEC_SP_TLS_SET 102)
172 (UNSPEC_SP_TLS_TEST 103)
182 (UNSPEC_INSERTQI 132)
187 (UNSPEC_INSERTPS 135)
189 (UNSPEC_MOVNTDQA 137)
191 (UNSPEC_PHMINPOSUW 139)
197 (UNSPEC_PCMPESTR 144)
198 (UNSPEC_PCMPISTR 145)
201 (UNSPEC_SSE5_INTRINSIC 150)
202 (UNSPEC_SSE5_UNSIGNED_CMP 151)
203 (UNSPEC_SSE5_TRUEFALSE 152)
204 (UNSPEC_SSE5_PERMUTE 153)
206 (UNSPEC_CVTPH2PS 155)
207 (UNSPEC_CVTPS2PH 156)
211 (UNSPEC_AESENCLAST 160)
213 (UNSPEC_AESDECLAST 162)
215 (UNSPEC_AESKEYGENASSIST 164)
223 (UNSPEC_VPERMIL2F128 168)
224 (UNSPEC_MASKLOAD 169)
225 (UNSPEC_MASKSTORE 170)
231 [(UNSPECV_BLOCKAGE 0)
232 (UNSPECV_STACK_PROBE 1)
244 (UNSPECV_PROLOGUE_USE 14)
246 (UNSPECV_VZEROALL 16)
247 (UNSPECV_VZEROUPPER 17)
250 ;; Constants to represent pcomtrue/pcomfalse variants
260 ;; Constants used in the SSE5 pperm instruction
262 [(PPERM_SRC 0x00) /* copy source */
263 (PPERM_INVERT 0x20) /* invert source */
264 (PPERM_REVERSE 0x40) /* bit reverse source */
265 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
266 (PPERM_ZERO 0x80) /* all 0's */
267 (PPERM_ONES 0xa0) /* all 1's */
268 (PPERM_SIGN 0xc0) /* propagate sign bit */
269 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
270 (PPERM_SRC1 0x00) /* use first source byte */
271 (PPERM_SRC2 0x10) /* use second source byte */
274 ;; 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 (if_then_else (ior (eq_attr "mode" "HI")
419 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
423 ;; Set when string REP prefix is used.
424 (define_attr "prefix_rep" ""
425 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
429 ;; Set when 0f opcode prefix is used.
430 (define_attr "prefix_0f" ""
432 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
433 (eq_attr "unit" "sse,mmx"))
437 ;; Set when REX opcode prefix is used.
438 (define_attr "prefix_rex" ""
439 (cond [(and (eq_attr "mode" "DI")
440 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
442 (and (eq_attr "mode" "QI")
443 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
446 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
452 ;; There are also additional prefixes in SSSE3.
453 (define_attr "prefix_extra" "" (const_int 0))
455 ;; Prefix used: original, VEX or maybe VEX.
456 (define_attr "prefix" "orig,vex,maybe_vex"
457 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
459 (const_string "orig")))
461 ;; There is a 8bit immediate for VEX.
462 (define_attr "prefix_vex_imm8" "" (const_int 0))
464 ;; VEX W bit is used.
465 (define_attr "prefix_vex_w" "" (const_int 0))
467 ;; The length of VEX prefix
468 (define_attr "length_vex" ""
469 (if_then_else (eq_attr "prefix_0f" "1")
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
473 (if_then_else (eq_attr "prefix_vex_w" "1")
474 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
475 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
477 ;; Set when modrm byte is used.
478 (define_attr "modrm" ""
479 (cond [(eq_attr "type" "str,leave")
481 (eq_attr "unit" "i387")
483 (and (eq_attr "type" "incdec")
484 (ior (match_operand:SI 1 "register_operand" "")
485 (match_operand:HI 1 "register_operand" "")))
487 (and (eq_attr "type" "push")
488 (not (match_operand 1 "memory_operand" "")))
490 (and (eq_attr "type" "pop")
491 (not (match_operand 0 "memory_operand" "")))
493 (and (eq_attr "type" "imov")
494 (ior (and (match_operand 0 "register_operand" "")
495 (match_operand 1 "immediate_operand" ""))
496 (ior (and (match_operand 0 "ax_reg_operand" "")
497 (match_operand 1 "memory_displacement_only_operand" ""))
498 (and (match_operand 0 "memory_displacement_only_operand" "")
499 (match_operand 1 "ax_reg_operand" "")))))
501 (and (eq_attr "type" "call")
502 (match_operand 0 "constant_call_address_operand" ""))
504 (and (eq_attr "type" "callv")
505 (match_operand 1 "constant_call_address_operand" ""))
510 ;; The (bounding maximum) length of an instruction in bytes.
511 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
512 ;; Later we may want to split them and compute proper length as for
514 (define_attr "length" ""
515 (cond [(eq_attr "type" "other,multi,fistp,frndint")
517 (eq_attr "type" "fcmp")
519 (eq_attr "unit" "i387")
521 (plus (attr "prefix_data16")
522 (attr "length_address")))
523 (ior (eq_attr "prefix" "vex")
524 (and (eq_attr "prefix" "maybe_vex")
525 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
526 (plus (attr "length_vex")
527 (plus (attr "prefix_vex_imm8")
529 (attr "length_address"))))]
530 (plus (plus (attr "modrm")
531 (plus (attr "prefix_0f")
532 (plus (attr "prefix_rex")
533 (plus (attr "prefix_extra")
535 (plus (attr "prefix_rep")
536 (plus (attr "prefix_data16")
537 (plus (attr "length_immediate")
538 (attr "length_address")))))))
540 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
541 ;; `store' if there is a simple memory reference therein, or `unknown'
542 ;; if the instruction is complex.
544 (define_attr "memory" "none,load,store,both,unknown"
545 (cond [(eq_attr "type" "other,multi,str")
546 (const_string "unknown")
547 (eq_attr "type" "lea,fcmov,fpspc")
548 (const_string "none")
549 (eq_attr "type" "fistp,leave")
550 (const_string "both")
551 (eq_attr "type" "frndint")
552 (const_string "load")
553 (eq_attr "type" "push")
554 (if_then_else (match_operand 1 "memory_operand" "")
555 (const_string "both")
556 (const_string "store"))
557 (eq_attr "type" "pop")
558 (if_then_else (match_operand 0 "memory_operand" "")
559 (const_string "both")
560 (const_string "load"))
561 (eq_attr "type" "setcc")
562 (if_then_else (match_operand 0 "memory_operand" "")
563 (const_string "store")
564 (const_string "none"))
565 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
566 (if_then_else (ior (match_operand 0 "memory_operand" "")
567 (match_operand 1 "memory_operand" ""))
568 (const_string "load")
569 (const_string "none"))
570 (eq_attr "type" "ibr")
571 (if_then_else (match_operand 0 "memory_operand" "")
572 (const_string "load")
573 (const_string "none"))
574 (eq_attr "type" "call")
575 (if_then_else (match_operand 0 "constant_call_address_operand" "")
576 (const_string "none")
577 (const_string "load"))
578 (eq_attr "type" "callv")
579 (if_then_else (match_operand 1 "constant_call_address_operand" "")
580 (const_string "none")
581 (const_string "load"))
582 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
583 (match_operand 1 "memory_operand" ""))
584 (const_string "both")
585 (and (match_operand 0 "memory_operand" "")
586 (match_operand 1 "memory_operand" ""))
587 (const_string "both")
588 (match_operand 0 "memory_operand" "")
589 (const_string "store")
590 (match_operand 1 "memory_operand" "")
591 (const_string "load")
593 "!alu1,negnot,ishift1,
594 imov,imovx,icmp,test,bitmanip,
596 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
597 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
598 (match_operand 2 "memory_operand" ""))
599 (const_string "load")
600 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
601 (match_operand 3 "memory_operand" ""))
602 (const_string "load")
604 (const_string "none")))
606 ;; Indicates if an instruction has both an immediate and a displacement.
608 (define_attr "imm_disp" "false,true,unknown"
609 (cond [(eq_attr "type" "other,multi")
610 (const_string "unknown")
611 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
612 (and (match_operand 0 "memory_displacement_operand" "")
613 (match_operand 1 "immediate_operand" "")))
614 (const_string "true")
615 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
616 (and (match_operand 0 "memory_displacement_operand" "")
617 (match_operand 2 "immediate_operand" "")))
618 (const_string "true")
620 (const_string "false")))
622 ;; Indicates if an FP operation has an integer source.
624 (define_attr "fp_int_src" "false,true"
625 (const_string "false"))
627 ;; Defines rounding mode of an FP operation.
629 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
630 (const_string "any"))
632 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
633 (define_attr "use_carry" "0,1" (const_string "0"))
635 ;; Define attribute to indicate unaligned ssemov insns
636 (define_attr "movu" "0,1" (const_string "0"))
638 ;; Describe a user's asm statement.
639 (define_asm_attributes
640 [(set_attr "length" "128")
641 (set_attr "type" "multi")])
643 ;; All integer comparison codes.
644 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
646 ;; All floating-point comparison codes.
647 (define_code_iterator fp_cond [unordered ordered
648 uneq unge ungt unle unlt ltgt ])
650 (define_code_iterator plusminus [plus minus])
652 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
654 ;; Base name for define_insn
655 (define_code_attr plusminus_insn
656 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
657 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
659 ;; Base name for insn mnemonic.
660 (define_code_attr plusminus_mnemonic
661 [(plus "add") (ss_plus "adds") (us_plus "addus")
662 (minus "sub") (ss_minus "subs") (us_minus "subus")])
664 ;; Mark commutative operators as such in constraints.
665 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
666 (minus "") (ss_minus "") (us_minus "")])
668 ;; Mapping of signed max and min
669 (define_code_iterator smaxmin [smax smin])
671 ;; Mapping of unsigned max and min
672 (define_code_iterator umaxmin [umax umin])
674 ;; Mapping of signed/unsigned max and min
675 (define_code_iterator maxmin [smax smin umax umin])
677 ;; Base name for integer and FP insn mnemonic
678 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
679 (umax "maxu") (umin "minu")])
680 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
682 ;; Mapping of parallel logic operators
683 (define_code_iterator plogic [and ior xor])
685 ;; Base name for insn mnemonic.
686 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
688 ;; Mapping of abs neg operators
689 (define_code_iterator absneg [abs neg])
691 ;; Base name for x87 insn mnemonic.
692 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
694 ;; All single word integer modes.
695 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
697 ;; Single word integer modes without QImode.
698 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
700 ;; Instruction suffix for integer modes.
701 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
703 ;; Register class for integer modes.
704 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
706 ;; Immediate operand constraint for integer modes.
707 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
709 ;; General operand predicate for integer modes.
710 (define_mode_attr general_operand
711 [(QI "general_operand")
712 (HI "general_operand")
713 (SI "general_operand")
714 (DI "x86_64_general_operand")])
716 ;; SSE and x87 SFmode and DFmode floating point modes
717 (define_mode_iterator MODEF [SF DF])
719 ;; All x87 floating point modes
720 (define_mode_iterator X87MODEF [SF DF XF])
722 ;; All integer modes handled by x87 fisttp operator.
723 (define_mode_iterator X87MODEI [HI SI DI])
725 ;; All integer modes handled by integer x87 operators.
726 (define_mode_iterator X87MODEI12 [HI SI])
728 ;; All integer modes handled by SSE cvtts?2si* operators.
729 (define_mode_iterator SSEMODEI24 [SI DI])
731 ;; SSE asm suffix for floating point modes
732 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
734 ;; SSE vector mode corresponding to a scalar mode
735 (define_mode_attr ssevecmode
736 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
738 ;; Instruction suffix for REX 64bit operators.
739 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
741 ;; This mode iterator allows :P to be used for patterns that operate on
742 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
743 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
746 ;; Scheduling descriptions
748 (include "pentium.md")
751 (include "athlon.md")
756 ;; Operand and operator predicates and constraints
758 (include "predicates.md")
759 (include "constraints.md")
762 ;; Compare instructions.
764 ;; All compare insns have expanders that save the operands away without
765 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
766 ;; after the cmp) will actually emit the cmpM.
768 (define_expand "cmpti"
769 [(set (reg:CC FLAGS_REG)
770 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
771 (match_operand:TI 1 "x86_64_general_operand" "")))]
774 if (MEM_P (operands[0]) && MEM_P (operands[1]))
775 operands[0] = force_reg (TImode, operands[0]);
776 ix86_compare_op0 = operands[0];
777 ix86_compare_op1 = operands[1];
781 (define_expand "cmpdi"
782 [(set (reg:CC FLAGS_REG)
783 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
784 (match_operand:DI 1 "x86_64_general_operand" "")))]
787 if (MEM_P (operands[0]) && MEM_P (operands[1]))
788 operands[0] = force_reg (DImode, operands[0]);
789 ix86_compare_op0 = operands[0];
790 ix86_compare_op1 = operands[1];
794 (define_expand "cmpsi"
795 [(set (reg:CC FLAGS_REG)
796 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
797 (match_operand:SI 1 "general_operand" "")))]
800 if (MEM_P (operands[0]) && MEM_P (operands[1]))
801 operands[0] = force_reg (SImode, operands[0]);
802 ix86_compare_op0 = operands[0];
803 ix86_compare_op1 = operands[1];
807 (define_expand "cmphi"
808 [(set (reg:CC FLAGS_REG)
809 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
810 (match_operand:HI 1 "general_operand" "")))]
813 if (MEM_P (operands[0]) && MEM_P (operands[1]))
814 operands[0] = force_reg (HImode, operands[0]);
815 ix86_compare_op0 = operands[0];
816 ix86_compare_op1 = operands[1];
820 (define_expand "cmpqi"
821 [(set (reg:CC FLAGS_REG)
822 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
823 (match_operand:QI 1 "general_operand" "")))]
826 if (MEM_P (operands[0]) && MEM_P (operands[1]))
827 operands[0] = force_reg (QImode, operands[0]);
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
833 (define_insn "cmpdi_ccno_1_rex64"
834 [(set (reg FLAGS_REG)
835 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
836 (match_operand:DI 1 "const0_operand" "")))]
837 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
840 cmp{q}\t{%1, %0|%0, %1}"
841 [(set_attr "type" "test,icmp")
842 (set_attr "length_immediate" "0,1")
843 (set_attr "mode" "DI")])
845 (define_insn "*cmpdi_minus_1_rex64"
846 [(set (reg FLAGS_REG)
847 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
848 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
850 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
851 "cmp{q}\t{%1, %0|%0, %1}"
852 [(set_attr "type" "icmp")
853 (set_attr "mode" "DI")])
855 (define_expand "cmpdi_1_rex64"
856 [(set (reg:CC FLAGS_REG)
857 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
858 (match_operand:DI 1 "general_operand" "")))]
862 (define_insn "cmpdi_1_insn_rex64"
863 [(set (reg FLAGS_REG)
864 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
865 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
866 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
867 "cmp{q}\t{%1, %0|%0, %1}"
868 [(set_attr "type" "icmp")
869 (set_attr "mode" "DI")])
872 (define_insn "*cmpsi_ccno_1"
873 [(set (reg FLAGS_REG)
874 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
875 (match_operand:SI 1 "const0_operand" "")))]
876 "ix86_match_ccmode (insn, CCNOmode)"
879 cmp{l}\t{%1, %0|%0, %1}"
880 [(set_attr "type" "test,icmp")
881 (set_attr "length_immediate" "0,1")
882 (set_attr "mode" "SI")])
884 (define_insn "*cmpsi_minus_1"
885 [(set (reg FLAGS_REG)
886 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
887 (match_operand:SI 1 "general_operand" "ri,mr"))
889 "ix86_match_ccmode (insn, CCGOCmode)"
890 "cmp{l}\t{%1, %0|%0, %1}"
891 [(set_attr "type" "icmp")
892 (set_attr "mode" "SI")])
894 (define_expand "cmpsi_1"
895 [(set (reg:CC FLAGS_REG)
896 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
897 (match_operand:SI 1 "general_operand" "")))]
901 (define_insn "*cmpsi_1_insn"
902 [(set (reg FLAGS_REG)
903 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
904 (match_operand:SI 1 "general_operand" "ri,mr")))]
905 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
906 && ix86_match_ccmode (insn, CCmode)"
907 "cmp{l}\t{%1, %0|%0, %1}"
908 [(set_attr "type" "icmp")
909 (set_attr "mode" "SI")])
911 (define_insn "*cmphi_ccno_1"
912 [(set (reg FLAGS_REG)
913 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
914 (match_operand:HI 1 "const0_operand" "")))]
915 "ix86_match_ccmode (insn, CCNOmode)"
918 cmp{w}\t{%1, %0|%0, %1}"
919 [(set_attr "type" "test,icmp")
920 (set_attr "length_immediate" "0,1")
921 (set_attr "mode" "HI")])
923 (define_insn "*cmphi_minus_1"
924 [(set (reg FLAGS_REG)
925 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
926 (match_operand:HI 1 "general_operand" "rn,mr"))
928 "ix86_match_ccmode (insn, CCGOCmode)"
929 "cmp{w}\t{%1, %0|%0, %1}"
930 [(set_attr "type" "icmp")
931 (set_attr "mode" "HI")])
933 (define_insn "*cmphi_1"
934 [(set (reg FLAGS_REG)
935 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
936 (match_operand:HI 1 "general_operand" "rn,mr")))]
937 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
938 && ix86_match_ccmode (insn, CCmode)"
939 "cmp{w}\t{%1, %0|%0, %1}"
940 [(set_attr "type" "icmp")
941 (set_attr "mode" "HI")])
943 (define_insn "*cmpqi_ccno_1"
944 [(set (reg FLAGS_REG)
945 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
946 (match_operand:QI 1 "const0_operand" "")))]
947 "ix86_match_ccmode (insn, CCNOmode)"
950 cmp{b}\t{$0, %0|%0, 0}"
951 [(set_attr "type" "test,icmp")
952 (set_attr "length_immediate" "0,1")
953 (set_attr "mode" "QI")])
955 (define_insn "*cmpqi_1"
956 [(set (reg FLAGS_REG)
957 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
958 (match_operand:QI 1 "general_operand" "qn,mq")))]
959 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
960 && ix86_match_ccmode (insn, CCmode)"
961 "cmp{b}\t{%1, %0|%0, %1}"
962 [(set_attr "type" "icmp")
963 (set_attr "mode" "QI")])
965 (define_insn "*cmpqi_minus_1"
966 [(set (reg FLAGS_REG)
967 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
968 (match_operand:QI 1 "general_operand" "qn,mq"))
970 "ix86_match_ccmode (insn, CCGOCmode)"
971 "cmp{b}\t{%1, %0|%0, %1}"
972 [(set_attr "type" "icmp")
973 (set_attr "mode" "QI")])
975 (define_insn "*cmpqi_ext_1"
976 [(set (reg FLAGS_REG)
978 (match_operand:QI 0 "general_operand" "Qm")
981 (match_operand 1 "ext_register_operand" "Q")
984 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
985 "cmp{b}\t{%h1, %0|%0, %h1}"
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "QI")])
989 (define_insn "*cmpqi_ext_1_rex64"
990 [(set (reg FLAGS_REG)
992 (match_operand:QI 0 "register_operand" "Q")
995 (match_operand 1 "ext_register_operand" "Q")
998 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999 "cmp{b}\t{%h1, %0|%0, %h1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "QI")])
1003 (define_insn "*cmpqi_ext_2"
1004 [(set (reg FLAGS_REG)
1008 (match_operand 0 "ext_register_operand" "Q")
1011 (match_operand:QI 1 "const0_operand" "")))]
1012 "ix86_match_ccmode (insn, CCNOmode)"
1014 [(set_attr "type" "test")
1015 (set_attr "length_immediate" "0")
1016 (set_attr "mode" "QI")])
1018 (define_expand "cmpqi_ext_3"
1019 [(set (reg:CC FLAGS_REG)
1023 (match_operand 0 "ext_register_operand" "")
1026 (match_operand:QI 1 "general_operand" "")))]
1030 (define_insn "cmpqi_ext_3_insn"
1031 [(set (reg FLAGS_REG)
1035 (match_operand 0 "ext_register_operand" "Q")
1038 (match_operand:QI 1 "general_operand" "Qmn")))]
1039 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1040 "cmp{b}\t{%1, %h0|%h0, %1}"
1041 [(set_attr "type" "icmp")
1042 (set_attr "mode" "QI")])
1044 (define_insn "cmpqi_ext_3_insn_rex64"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1053 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "mode" "QI")])
1058 (define_insn "*cmpqi_ext_4"
1059 [(set (reg FLAGS_REG)
1063 (match_operand 0 "ext_register_operand" "Q")
1068 (match_operand 1 "ext_register_operand" "Q")
1070 (const_int 8)) 0)))]
1071 "ix86_match_ccmode (insn, CCmode)"
1072 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1073 [(set_attr "type" "icmp")
1074 (set_attr "mode" "QI")])
1076 ;; These implement float point compares.
1077 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1078 ;; which would allow mix and match FP modes on the compares. Which is what
1079 ;; the old patterns did, but with many more of them.
1081 (define_expand "cmpxf"
1082 [(set (reg:CC FLAGS_REG)
1083 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1084 (match_operand:XF 1 "nonmemory_operand" "")))]
1087 ix86_compare_op0 = operands[0];
1088 ix86_compare_op1 = operands[1];
1092 (define_expand "cmp<mode>"
1093 [(set (reg:CC FLAGS_REG)
1094 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1095 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1096 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1098 ix86_compare_op0 = operands[0];
1099 ix86_compare_op1 = operands[1];
1103 (define_expand "cmpcc"
1104 [(set (reg:CC FLAGS_REG)
1105 (compare:CC (match_operand 0 "flags_reg_operand" "")
1106 (match_operand 1 "general_operand" "")))]
1109 ix86_compare_op0 = operands[0];
1110 ix86_compare_op1 = operands[1];
1114 ;; FP compares, step 1:
1115 ;; Set the FP condition codes.
1117 ;; CCFPmode compare with exceptions
1118 ;; CCFPUmode compare with no exceptions
1120 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1121 ;; used to manage the reg stack popping would not be preserved.
1123 (define_insn "*cmpfp_0"
1124 [(set (match_operand:HI 0 "register_operand" "=a")
1127 (match_operand 1 "register_operand" "f")
1128 (match_operand 2 "const0_operand" ""))]
1130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1131 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1132 "* return output_fp_compare (insn, operands, 0, 0);"
1133 [(set_attr "type" "multi")
1134 (set_attr "unit" "i387")
1136 (cond [(match_operand:SF 1 "" "")
1138 (match_operand:DF 1 "" "")
1141 (const_string "XF")))])
1143 (define_insn_and_split "*cmpfp_0_cc"
1144 [(set (reg:CCFP FLAGS_REG)
1146 (match_operand 1 "register_operand" "f")
1147 (match_operand 2 "const0_operand" "")))
1148 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1149 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1150 && TARGET_SAHF && !TARGET_CMOVE
1151 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1153 "&& reload_completed"
1156 [(compare:CCFP (match_dup 1)(match_dup 2))]
1158 (set (reg:CC FLAGS_REG)
1159 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1161 [(set_attr "type" "multi")
1162 (set_attr "unit" "i387")
1164 (cond [(match_operand:SF 1 "" "")
1166 (match_operand:DF 1 "" "")
1169 (const_string "XF")))])
1171 (define_insn "*cmpfp_xf"
1172 [(set (match_operand:HI 0 "register_operand" "=a")
1175 (match_operand:XF 1 "register_operand" "f")
1176 (match_operand:XF 2 "register_operand" "f"))]
1179 "* return output_fp_compare (insn, operands, 0, 0);"
1180 [(set_attr "type" "multi")
1181 (set_attr "unit" "i387")
1182 (set_attr "mode" "XF")])
1184 (define_insn_and_split "*cmpfp_xf_cc"
1185 [(set (reg:CCFP FLAGS_REG)
1187 (match_operand:XF 1 "register_operand" "f")
1188 (match_operand:XF 2 "register_operand" "f")))
1189 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1191 && TARGET_SAHF && !TARGET_CMOVE"
1193 "&& reload_completed"
1196 [(compare:CCFP (match_dup 1)(match_dup 2))]
1198 (set (reg:CC FLAGS_REG)
1199 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1201 [(set_attr "type" "multi")
1202 (set_attr "unit" "i387")
1203 (set_attr "mode" "XF")])
1205 (define_insn "*cmpfp_<mode>"
1206 [(set (match_operand:HI 0 "register_operand" "=a")
1209 (match_operand:MODEF 1 "register_operand" "f")
1210 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1213 "* return output_fp_compare (insn, operands, 0, 0);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1216 (set_attr "mode" "<MODE>")])
1218 (define_insn_and_split "*cmpfp_<mode>_cc"
1219 [(set (reg:CCFP FLAGS_REG)
1221 (match_operand:MODEF 1 "register_operand" "f")
1222 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1223 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1225 && TARGET_SAHF && !TARGET_CMOVE"
1227 "&& reload_completed"
1230 [(compare:CCFP (match_dup 1)(match_dup 2))]
1232 (set (reg:CC FLAGS_REG)
1233 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1237 (set_attr "mode" "<MODE>")])
1239 (define_insn "*cmpfp_u"
1240 [(set (match_operand:HI 0 "register_operand" "=a")
1243 (match_operand 1 "register_operand" "f")
1244 (match_operand 2 "register_operand" "f"))]
1246 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1247 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248 "* return output_fp_compare (insn, operands, 0, 1);"
1249 [(set_attr "type" "multi")
1250 (set_attr "unit" "i387")
1252 (cond [(match_operand:SF 1 "" "")
1254 (match_operand:DF 1 "" "")
1257 (const_string "XF")))])
1259 (define_insn_and_split "*cmpfp_u_cc"
1260 [(set (reg:CCFPU FLAGS_REG)
1262 (match_operand 1 "register_operand" "f")
1263 (match_operand 2 "register_operand" "f")))
1264 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1266 && TARGET_SAHF && !TARGET_CMOVE
1267 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1269 "&& reload_completed"
1272 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1274 (set (reg:CC FLAGS_REG)
1275 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277 [(set_attr "type" "multi")
1278 (set_attr "unit" "i387")
1280 (cond [(match_operand:SF 1 "" "")
1282 (match_operand:DF 1 "" "")
1285 (const_string "XF")))])
1287 (define_insn "*cmpfp_<mode>"
1288 [(set (match_operand:HI 0 "register_operand" "=a")
1291 (match_operand 1 "register_operand" "f")
1292 (match_operator 3 "float_operator"
1293 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1295 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1296 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1297 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1298 "* return output_fp_compare (insn, operands, 0, 0);"
1299 [(set_attr "type" "multi")
1300 (set_attr "unit" "i387")
1301 (set_attr "fp_int_src" "true")
1302 (set_attr "mode" "<MODE>")])
1304 (define_insn_and_split "*cmpfp_<mode>_cc"
1305 [(set (reg:CCFP FLAGS_REG)
1307 (match_operand 1 "register_operand" "f")
1308 (match_operator 3 "float_operator"
1309 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1310 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1311 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1312 && TARGET_SAHF && !TARGET_CMOVE
1313 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1314 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1316 "&& reload_completed"
1321 (match_op_dup 3 [(match_dup 2)]))]
1323 (set (reg:CC FLAGS_REG)
1324 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1326 [(set_attr "type" "multi")
1327 (set_attr "unit" "i387")
1328 (set_attr "fp_int_src" "true")
1329 (set_attr "mode" "<MODE>")])
1331 ;; FP compares, step 2
1332 ;; Move the fpsw to ax.
1334 (define_insn "x86_fnstsw_1"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1339 [(set_attr "length" "2")
1340 (set_attr "mode" "SI")
1341 (set_attr "unit" "i387")])
1343 ;; FP compares, step 3
1344 ;; Get ax into flags, general case.
1346 (define_insn "x86_sahf_1"
1347 [(set (reg:CC FLAGS_REG)
1348 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1352 #ifdef HAVE_AS_IX86_SAHF
1355 return ".byte\t0x9e";
1358 [(set_attr "length" "1")
1359 (set_attr "athlon_decode" "vector")
1360 (set_attr "amdfam10_decode" "direct")
1361 (set_attr "mode" "SI")])
1363 ;; Pentium Pro can do steps 1 through 3 in one go.
1364 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1365 (define_insn "*cmpfp_i_mixed"
1366 [(set (reg:CCFP FLAGS_REG)
1367 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1368 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369 "TARGET_MIX_SSE_I387
1370 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372 "* return output_fp_compare (insn, operands, 1, 0);"
1373 [(set_attr "type" "fcmp,ssecomi")
1374 (set_attr "prefix" "orig,maybe_vex")
1376 (if_then_else (match_operand:SF 1 "" "")
1378 (const_string "DF")))
1379 (set_attr "athlon_decode" "vector")
1380 (set_attr "amdfam10_decode" "direct")])
1382 (define_insn "*cmpfp_i_sse"
1383 [(set (reg:CCFP FLAGS_REG)
1384 (compare:CCFP (match_operand 0 "register_operand" "x")
1385 (match_operand 1 "nonimmediate_operand" "xm")))]
1387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389 "* return output_fp_compare (insn, operands, 1, 0);"
1390 [(set_attr "type" "ssecomi")
1391 (set_attr "prefix" "maybe_vex")
1393 (if_then_else (match_operand:SF 1 "" "")
1395 (const_string "DF")))
1396 (set_attr "athlon_decode" "vector")
1397 (set_attr "amdfam10_decode" "direct")])
1399 (define_insn "*cmpfp_i_i387"
1400 [(set (reg:CCFP FLAGS_REG)
1401 (compare:CCFP (match_operand 0 "register_operand" "f")
1402 (match_operand 1 "register_operand" "f")))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1405 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407 "* return output_fp_compare (insn, operands, 1, 0);"
1408 [(set_attr "type" "fcmp")
1410 (cond [(match_operand:SF 1 "" "")
1412 (match_operand:DF 1 "" "")
1415 (const_string "XF")))
1416 (set_attr "athlon_decode" "vector")
1417 (set_attr "amdfam10_decode" "direct")])
1419 (define_insn "*cmpfp_iu_mixed"
1420 [(set (reg:CCFPU FLAGS_REG)
1421 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1422 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1423 "TARGET_MIX_SSE_I387
1424 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1425 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426 "* return output_fp_compare (insn, operands, 1, 1);"
1427 [(set_attr "type" "fcmp,ssecomi")
1428 (set_attr "prefix" "orig,maybe_vex")
1430 (if_then_else (match_operand:SF 1 "" "")
1432 (const_string "DF")))
1433 (set_attr "athlon_decode" "vector")
1434 (set_attr "amdfam10_decode" "direct")])
1436 (define_insn "*cmpfp_iu_sse"
1437 [(set (reg:CCFPU FLAGS_REG)
1438 (compare:CCFPU (match_operand 0 "register_operand" "x")
1439 (match_operand 1 "nonimmediate_operand" "xm")))]
1441 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1442 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1443 "* return output_fp_compare (insn, operands, 1, 1);"
1444 [(set_attr "type" "ssecomi")
1445 (set_attr "prefix" "maybe_vex")
1447 (if_then_else (match_operand:SF 1 "" "")
1449 (const_string "DF")))
1450 (set_attr "athlon_decode" "vector")
1451 (set_attr "amdfam10_decode" "direct")])
1453 (define_insn "*cmpfp_iu_387"
1454 [(set (reg:CCFPU FLAGS_REG)
1455 (compare:CCFPU (match_operand 0 "register_operand" "f")
1456 (match_operand 1 "register_operand" "f")))]
1457 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1459 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1460 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1461 "* return output_fp_compare (insn, operands, 1, 1);"
1462 [(set_attr "type" "fcmp")
1464 (cond [(match_operand:SF 1 "" "")
1466 (match_operand:DF 1 "" "")
1469 (const_string "XF")))
1470 (set_attr "athlon_decode" "vector")
1471 (set_attr "amdfam10_decode" "direct")])
1473 ;; Move instructions.
1475 ;; General case of fullword move.
1477 (define_expand "movsi"
1478 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1479 (match_operand:SI 1 "general_operand" ""))]
1481 "ix86_expand_move (SImode, operands); DONE;")
1483 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1486 ;; %%% We don't use a post-inc memory reference because x86 is not a
1487 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1488 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1489 ;; targets without our curiosities, and it is just as easy to represent
1490 ;; this differently.
1492 (define_insn "*pushsi2"
1493 [(set (match_operand:SI 0 "push_operand" "=<")
1494 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1497 [(set_attr "type" "push")
1498 (set_attr "mode" "SI")])
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushsi2_rex64"
1502 [(set (match_operand:SI 0 "push_operand" "=X")
1503 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1506 [(set_attr "type" "push")
1507 (set_attr "mode" "SI")])
1509 (define_insn "*pushsi2_prologue"
1510 [(set (match_operand:SI 0 "push_operand" "=<")
1511 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1512 (clobber (mem:BLK (scratch)))]
1515 [(set_attr "type" "push")
1516 (set_attr "mode" "SI")])
1518 (define_insn "*popsi1_epilogue"
1519 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1520 (mem:SI (reg:SI SP_REG)))
1521 (set (reg:SI SP_REG)
1522 (plus:SI (reg:SI SP_REG) (const_int 4)))
1523 (clobber (mem:BLK (scratch)))]
1526 [(set_attr "type" "pop")
1527 (set_attr "mode" "SI")])
1529 (define_insn "popsi1"
1530 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1531 (mem:SI (reg:SI SP_REG)))
1532 (set (reg:SI SP_REG)
1533 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1536 [(set_attr "type" "pop")
1537 (set_attr "mode" "SI")])
1539 (define_insn "*movsi_xor"
1540 [(set (match_operand:SI 0 "register_operand" "=r")
1541 (match_operand:SI 1 "const0_operand" ""))
1542 (clobber (reg:CC FLAGS_REG))]
1545 [(set_attr "type" "alu1")
1546 (set_attr "mode" "SI")
1547 (set_attr "length_immediate" "0")])
1549 (define_insn "*movsi_or"
1550 [(set (match_operand:SI 0 "register_operand" "=r")
1551 (match_operand:SI 1 "immediate_operand" "i"))
1552 (clobber (reg:CC FLAGS_REG))]
1554 && operands[1] == constm1_rtx"
1556 operands[1] = constm1_rtx;
1557 return "or{l}\t{%1, %0|%0, %1}";
1559 [(set_attr "type" "alu1")
1560 (set_attr "mode" "SI")
1561 (set_attr "length_immediate" "1")])
1563 (define_insn "*movsi_1"
1564 [(set (match_operand:SI 0 "nonimmediate_operand"
1565 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1566 (match_operand:SI 1 "general_operand"
1567 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1568 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1570 switch (get_attr_type (insn))
1573 if (get_attr_mode (insn) == MODE_TI)
1574 return "%vpxor\t%0, %d0";
1575 return "%vxorps\t%0, %d0";
1578 switch (get_attr_mode (insn))
1581 return "%vmovdqa\t{%1, %0|%0, %1}";
1583 return "%vmovaps\t{%1, %0|%0, %1}";
1585 return "%vmovd\t{%1, %0|%0, %1}";
1587 return "%vmovss\t{%1, %0|%0, %1}";
1593 return "pxor\t%0, %0";
1596 if (get_attr_mode (insn) == MODE_DI)
1597 return "movq\t{%1, %0|%0, %1}";
1598 return "movd\t{%1, %0|%0, %1}";
1601 return "lea{l}\t{%1, %0|%0, %1}";
1604 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1605 return "mov{l}\t{%1, %0|%0, %1}";
1609 (cond [(eq_attr "alternative" "2")
1610 (const_string "mmx")
1611 (eq_attr "alternative" "3,4,5")
1612 (const_string "mmxmov")
1613 (eq_attr "alternative" "6")
1614 (const_string "sselog1")
1615 (eq_attr "alternative" "7,8,9,10,11")
1616 (const_string "ssemov")
1617 (match_operand:DI 1 "pic_32bit_operand" "")
1618 (const_string "lea")
1620 (const_string "imov")))
1621 (set (attr "prefix")
1622 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1623 (const_string "orig")
1624 (const_string "maybe_vex")))
1626 (cond [(eq_attr "alternative" "2,3")
1628 (eq_attr "alternative" "6,7")
1630 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1631 (const_string "V4SF")
1632 (const_string "TI"))
1633 (and (eq_attr "alternative" "8,9,10,11")
1634 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1637 (const_string "SI")))])
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabssi_1_rex64"
1643 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1645 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1647 movabs{l}\t{%1, %P0|%P0, %1}
1648 mov{l}\t{%1, %a0|%a0, %1}"
1649 [(set_attr "type" "imov")
1650 (set_attr "modrm" "0,*")
1651 (set_attr "length_address" "8,0")
1652 (set_attr "length_immediate" "0,*")
1653 (set_attr "memory" "store")
1654 (set_attr "mode" "SI")])
1656 (define_insn "*movabssi_2_rex64"
1657 [(set (match_operand:SI 0 "register_operand" "=a,r")
1658 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1661 movabs{l}\t{%P1, %0|%0, %P1}
1662 mov{l}\t{%a1, %0|%0, %a1}"
1663 [(set_attr "type" "imov")
1664 (set_attr "modrm" "0,*")
1665 (set_attr "length_address" "8,0")
1666 (set_attr "length_immediate" "0")
1667 (set_attr "memory" "load")
1668 (set_attr "mode" "SI")])
1670 (define_insn "*swapsi"
1671 [(set (match_operand:SI 0 "register_operand" "+r")
1672 (match_operand:SI 1 "register_operand" "+r"))
1677 [(set_attr "type" "imov")
1678 (set_attr "mode" "SI")
1679 (set_attr "pent_pair" "np")
1680 (set_attr "athlon_decode" "vector")
1681 (set_attr "amdfam10_decode" "double")])
1683 (define_expand "movhi"
1684 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1685 (match_operand:HI 1 "general_operand" ""))]
1687 "ix86_expand_move (HImode, operands); DONE;")
1689 (define_insn "*pushhi2"
1690 [(set (match_operand:HI 0 "push_operand" "=X")
1691 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "SI")])
1697 ;; For 64BIT abi we always round up to 8 bytes.
1698 (define_insn "*pushhi2_rex64"
1699 [(set (match_operand:HI 0 "push_operand" "=X")
1700 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1703 [(set_attr "type" "push")
1704 (set_attr "mode" "DI")])
1706 (define_insn "*movhi_1"
1707 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1708 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1709 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1711 switch (get_attr_type (insn))
1714 /* movzwl is faster than movw on p2 due to partial word stalls,
1715 though not as fast as an aligned movl. */
1716 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1718 if (get_attr_mode (insn) == MODE_SI)
1719 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1721 return "mov{w}\t{%1, %0|%0, %1}";
1725 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1726 (const_string "imov")
1727 (and (eq_attr "alternative" "0")
1728 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1730 (eq (symbol_ref "TARGET_HIMODE_MATH")
1732 (const_string "imov")
1733 (and (eq_attr "alternative" "1,2")
1734 (match_operand:HI 1 "aligned_operand" ""))
1735 (const_string "imov")
1736 (and (ne (symbol_ref "TARGET_MOVX")
1738 (eq_attr "alternative" "0,2"))
1739 (const_string "imovx")
1741 (const_string "imov")))
1743 (cond [(eq_attr "type" "imovx")
1745 (and (eq_attr "alternative" "1,2")
1746 (match_operand:HI 1 "aligned_operand" ""))
1748 (and (eq_attr "alternative" "0")
1749 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1751 (eq (symbol_ref "TARGET_HIMODE_MATH")
1755 (const_string "HI")))])
1757 ;; Stores and loads of ax to arbitrary constant address.
1758 ;; We fake an second form of instruction to force reload to load address
1759 ;; into register when rax is not available
1760 (define_insn "*movabshi_1_rex64"
1761 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1762 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1763 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1765 movabs{w}\t{%1, %P0|%P0, %1}
1766 mov{w}\t{%1, %a0|%a0, %1}"
1767 [(set_attr "type" "imov")
1768 (set_attr "modrm" "0,*")
1769 (set_attr "length_address" "8,0")
1770 (set_attr "length_immediate" "0,*")
1771 (set_attr "memory" "store")
1772 (set_attr "mode" "HI")])
1774 (define_insn "*movabshi_2_rex64"
1775 [(set (match_operand:HI 0 "register_operand" "=a,r")
1776 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1777 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1779 movabs{w}\t{%P1, %0|%0, %P1}
1780 mov{w}\t{%a1, %0|%0, %a1}"
1781 [(set_attr "type" "imov")
1782 (set_attr "modrm" "0,*")
1783 (set_attr "length_address" "8,0")
1784 (set_attr "length_immediate" "0")
1785 (set_attr "memory" "load")
1786 (set_attr "mode" "HI")])
1788 (define_insn "*swaphi_1"
1789 [(set (match_operand:HI 0 "register_operand" "+r")
1790 (match_operand:HI 1 "register_operand" "+r"))
1793 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1795 [(set_attr "type" "imov")
1796 (set_attr "mode" "SI")
1797 (set_attr "pent_pair" "np")
1798 (set_attr "athlon_decode" "vector")
1799 (set_attr "amdfam10_decode" "double")])
1801 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1802 (define_insn "*swaphi_2"
1803 [(set (match_operand:HI 0 "register_operand" "+r")
1804 (match_operand:HI 1 "register_operand" "+r"))
1807 "TARGET_PARTIAL_REG_STALL"
1809 [(set_attr "type" "imov")
1810 (set_attr "mode" "HI")
1811 (set_attr "pent_pair" "np")
1812 (set_attr "athlon_decode" "vector")])
1814 (define_expand "movstricthi"
1815 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1816 (match_operand:HI 1 "general_operand" ""))]
1819 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1821 /* Don't generate memory->memory moves, go through a register */
1822 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1823 operands[1] = force_reg (HImode, operands[1]);
1826 (define_insn "*movstricthi_1"
1827 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1828 (match_operand:HI 1 "general_operand" "rn,m"))]
1829 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1830 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 "mov{w}\t{%1, %0|%0, %1}"
1832 [(set_attr "type" "imov")
1833 (set_attr "mode" "HI")])
1835 (define_insn "*movstricthi_xor"
1836 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1837 (match_operand:HI 1 "const0_operand" ""))
1838 (clobber (reg:CC FLAGS_REG))]
1841 [(set_attr "type" "alu1")
1842 (set_attr "mode" "HI")
1843 (set_attr "length_immediate" "0")])
1845 (define_expand "movqi"
1846 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1847 (match_operand:QI 1 "general_operand" ""))]
1849 "ix86_expand_move (QImode, operands); DONE;")
1851 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1852 ;; "push a byte". But actually we use pushl, which has the effect
1853 ;; of rounding the amount pushed up to a word.
1855 (define_insn "*pushqi2"
1856 [(set (match_operand:QI 0 "push_operand" "=X")
1857 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1860 [(set_attr "type" "push")
1861 (set_attr "mode" "SI")])
1863 ;; For 64BIT abi we always round up to 8 bytes.
1864 (define_insn "*pushqi2_rex64"
1865 [(set (match_operand:QI 0 "push_operand" "=X")
1866 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1869 [(set_attr "type" "push")
1870 (set_attr "mode" "DI")])
1872 ;; Situation is quite tricky about when to choose full sized (SImode) move
1873 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1874 ;; partial register dependency machines (such as AMD Athlon), where QImode
1875 ;; moves issue extra dependency and for partial register stalls machines
1876 ;; that don't use QImode patterns (and QImode move cause stall on the next
1879 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1880 ;; register stall machines with, where we use QImode instructions, since
1881 ;; partial register stall can be caused there. Then we use movzx.
1882 (define_insn "*movqi_1"
1883 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1884 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1885 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1887 switch (get_attr_type (insn))
1890 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1891 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1893 if (get_attr_mode (insn) == MODE_SI)
1894 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1896 return "mov{b}\t{%1, %0|%0, %1}";
1900 (cond [(and (eq_attr "alternative" "5")
1901 (not (match_operand:QI 1 "aligned_operand" "")))
1902 (const_string "imovx")
1903 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1904 (const_string "imov")
1905 (and (eq_attr "alternative" "3")
1906 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1908 (eq (symbol_ref "TARGET_QIMODE_MATH")
1910 (const_string "imov")
1911 (eq_attr "alternative" "3,5")
1912 (const_string "imovx")
1913 (and (ne (symbol_ref "TARGET_MOVX")
1915 (eq_attr "alternative" "2"))
1916 (const_string "imovx")
1918 (const_string "imov")))
1920 (cond [(eq_attr "alternative" "3,4,5")
1922 (eq_attr "alternative" "6")
1924 (eq_attr "type" "imovx")
1926 (and (eq_attr "type" "imov")
1927 (and (eq_attr "alternative" "0,1")
1928 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1930 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1932 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1935 ;; Avoid partial register stalls when not using QImode arithmetic
1936 (and (eq_attr "type" "imov")
1937 (and (eq_attr "alternative" "0,1")
1938 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1940 (eq (symbol_ref "TARGET_QIMODE_MATH")
1944 (const_string "QI")))])
1946 (define_insn "*swapqi_1"
1947 [(set (match_operand:QI 0 "register_operand" "+r")
1948 (match_operand:QI 1 "register_operand" "+r"))
1951 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1953 [(set_attr "type" "imov")
1954 (set_attr "mode" "SI")
1955 (set_attr "pent_pair" "np")
1956 (set_attr "athlon_decode" "vector")
1957 (set_attr "amdfam10_decode" "vector")])
1959 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1960 (define_insn "*swapqi_2"
1961 [(set (match_operand:QI 0 "register_operand" "+q")
1962 (match_operand:QI 1 "register_operand" "+q"))
1965 "TARGET_PARTIAL_REG_STALL"
1967 [(set_attr "type" "imov")
1968 (set_attr "mode" "QI")
1969 (set_attr "pent_pair" "np")
1970 (set_attr "athlon_decode" "vector")])
1972 (define_expand "movstrictqi"
1973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1974 (match_operand:QI 1 "general_operand" ""))]
1977 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1979 /* Don't generate memory->memory moves, go through a register. */
1980 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1981 operands[1] = force_reg (QImode, operands[1]);
1984 (define_insn "*movstrictqi_1"
1985 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1986 (match_operand:QI 1 "general_operand" "*qn,m"))]
1987 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1988 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 "mov{b}\t{%1, %0|%0, %1}"
1990 [(set_attr "type" "imov")
1991 (set_attr "mode" "QI")])
1993 (define_insn "*movstrictqi_xor"
1994 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1995 (match_operand:QI 1 "const0_operand" ""))
1996 (clobber (reg:CC FLAGS_REG))]
1999 [(set_attr "type" "alu1")
2000 (set_attr "mode" "QI")
2001 (set_attr "length_immediate" "0")])
2003 (define_insn "*movsi_extv_1"
2004 [(set (match_operand:SI 0 "register_operand" "=R")
2005 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2009 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2010 [(set_attr "type" "imovx")
2011 (set_attr "mode" "SI")])
2013 (define_insn "*movhi_extv_1"
2014 [(set (match_operand:HI 0 "register_operand" "=R")
2015 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2019 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2020 [(set_attr "type" "imovx")
2021 (set_attr "mode" "SI")])
2023 (define_insn "*movqi_extv_1"
2024 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2025 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2030 switch (get_attr_type (insn))
2033 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2035 return "mov{b}\t{%h1, %0|%0, %h1}";
2039 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2040 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2041 (ne (symbol_ref "TARGET_MOVX")
2043 (const_string "imovx")
2044 (const_string "imov")))
2046 (if_then_else (eq_attr "type" "imovx")
2048 (const_string "QI")))])
2050 (define_insn "*movqi_extv_1_rex64"
2051 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2052 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2057 switch (get_attr_type (insn))
2060 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2062 return "mov{b}\t{%h1, %0|%0, %h1}";
2066 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2067 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2068 (ne (symbol_ref "TARGET_MOVX")
2070 (const_string "imovx")
2071 (const_string "imov")))
2073 (if_then_else (eq_attr "type" "imovx")
2075 (const_string "QI")))])
2077 ;; Stores and loads of ax to arbitrary constant address.
2078 ;; We fake an second form of instruction to force reload to load address
2079 ;; into register when rax is not available
2080 (define_insn "*movabsqi_1_rex64"
2081 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2082 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2083 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2085 movabs{b}\t{%1, %P0|%P0, %1}
2086 mov{b}\t{%1, %a0|%a0, %1}"
2087 [(set_attr "type" "imov")
2088 (set_attr "modrm" "0,*")
2089 (set_attr "length_address" "8,0")
2090 (set_attr "length_immediate" "0,*")
2091 (set_attr "memory" "store")
2092 (set_attr "mode" "QI")])
2094 (define_insn "*movabsqi_2_rex64"
2095 [(set (match_operand:QI 0 "register_operand" "=a,r")
2096 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2099 movabs{b}\t{%P1, %0|%0, %P1}
2100 mov{b}\t{%a1, %0|%0, %a1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0")
2105 (set_attr "memory" "load")
2106 (set_attr "mode" "QI")])
2108 (define_insn "*movdi_extzv_1"
2109 [(set (match_operand:DI 0 "register_operand" "=R")
2110 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2114 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2115 [(set_attr "type" "imovx")
2116 (set_attr "mode" "DI")])
2118 (define_insn "*movsi_extzv_1"
2119 [(set (match_operand:SI 0 "register_operand" "=R")
2120 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2124 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2125 [(set_attr "type" "imovx")
2126 (set_attr "mode" "SI")])
2128 (define_insn "*movqi_extzv_2"
2129 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2130 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2135 switch (get_attr_type (insn))
2138 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2140 return "mov{b}\t{%h1, %0|%0, %h1}";
2144 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2145 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2146 (ne (symbol_ref "TARGET_MOVX")
2148 (const_string "imovx")
2149 (const_string "imov")))
2151 (if_then_else (eq_attr "type" "imovx")
2153 (const_string "QI")))])
2155 (define_insn "*movqi_extzv_2_rex64"
2156 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2157 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2162 switch (get_attr_type (insn))
2165 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2167 return "mov{b}\t{%h1, %0|%0, %h1}";
2171 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2172 (ne (symbol_ref "TARGET_MOVX")
2174 (const_string "imovx")
2175 (const_string "imov")))
2177 (if_then_else (eq_attr "type" "imovx")
2179 (const_string "QI")))])
2181 (define_insn "movsi_insv_1"
2182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2185 (match_operand:SI 1 "general_operand" "Qmn"))]
2187 "mov{b}\t{%b1, %h0|%h0, %b1}"
2188 [(set_attr "type" "imov")
2189 (set_attr "mode" "QI")])
2191 (define_insn "*movsi_insv_1_rex64"
2192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2195 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2197 "mov{b}\t{%b1, %h0|%h0, %b1}"
2198 [(set_attr "type" "imov")
2199 (set_attr "mode" "QI")])
2201 (define_insn "movdi_insv_1_rex64"
2202 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2205 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2207 "mov{b}\t{%b1, %h0|%h0, %b1}"
2208 [(set_attr "type" "imov")
2209 (set_attr "mode" "QI")])
2211 (define_insn "*movqi_insv_2"
2212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2215 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2218 "mov{b}\t{%h1, %h0|%h0, %h1}"
2219 [(set_attr "type" "imov")
2220 (set_attr "mode" "QI")])
2222 (define_expand "movdi"
2223 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2224 (match_operand:DI 1 "general_operand" ""))]
2226 "ix86_expand_move (DImode, operands); DONE;")
2228 (define_insn "*pushdi"
2229 [(set (match_operand:DI 0 "push_operand" "=<")
2230 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2234 (define_insn "*pushdi2_rex64"
2235 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2236 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2241 [(set_attr "type" "push,multi")
2242 (set_attr "mode" "DI")])
2244 ;; Convert impossible pushes of immediate to existing instructions.
2245 ;; First try to get scratch register and go through it. In case this
2246 ;; fails, push sign extended lower part first and then overwrite
2247 ;; upper part by 32bit move.
2249 [(match_scratch:DI 2 "r")
2250 (set (match_operand:DI 0 "push_operand" "")
2251 (match_operand:DI 1 "immediate_operand" ""))]
2252 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2253 && !x86_64_immediate_operand (operands[1], DImode)"
2254 [(set (match_dup 2) (match_dup 1))
2255 (set (match_dup 0) (match_dup 2))]
2258 ;; We need to define this as both peepholer and splitter for case
2259 ;; peephole2 pass is not run.
2260 ;; "&& 1" is needed to keep it from matching the previous pattern.
2262 [(set (match_operand:DI 0 "push_operand" "")
2263 (match_operand:DI 1 "immediate_operand" ""))]
2264 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2265 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2266 [(set (match_dup 0) (match_dup 1))
2267 (set (match_dup 2) (match_dup 3))]
2268 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2269 operands[1] = gen_lowpart (DImode, operands[2]);
2270 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2275 [(set (match_operand:DI 0 "push_operand" "")
2276 (match_operand:DI 1 "immediate_operand" ""))]
2277 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2278 ? epilogue_completed : reload_completed)
2279 && !symbolic_operand (operands[1], DImode)
2280 && !x86_64_immediate_operand (operands[1], DImode)"
2281 [(set (match_dup 0) (match_dup 1))
2282 (set (match_dup 2) (match_dup 3))]
2283 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2284 operands[1] = gen_lowpart (DImode, operands[2]);
2285 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2289 (define_insn "*pushdi2_prologue_rex64"
2290 [(set (match_operand:DI 0 "push_operand" "=<")
2291 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2292 (clobber (mem:BLK (scratch)))]
2295 [(set_attr "type" "push")
2296 (set_attr "mode" "DI")])
2298 (define_insn "*popdi1_epilogue_rex64"
2299 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2300 (mem:DI (reg:DI SP_REG)))
2301 (set (reg:DI SP_REG)
2302 (plus:DI (reg:DI SP_REG) (const_int 8)))
2303 (clobber (mem:BLK (scratch)))]
2306 [(set_attr "type" "pop")
2307 (set_attr "mode" "DI")])
2309 (define_insn "popdi1"
2310 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2311 (mem:DI (reg:DI SP_REG)))
2312 (set (reg:DI SP_REG)
2313 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2316 [(set_attr "type" "pop")
2317 (set_attr "mode" "DI")])
2319 (define_insn "*movdi_xor_rex64"
2320 [(set (match_operand:DI 0 "register_operand" "=r")
2321 (match_operand:DI 1 "const0_operand" ""))
2322 (clobber (reg:CC FLAGS_REG))]
2324 && reload_completed"
2326 [(set_attr "type" "alu1")
2327 (set_attr "mode" "SI")
2328 (set_attr "length_immediate" "0")])
2330 (define_insn "*movdi_or_rex64"
2331 [(set (match_operand:DI 0 "register_operand" "=r")
2332 (match_operand:DI 1 "const_int_operand" "i"))
2333 (clobber (reg:CC FLAGS_REG))]
2336 && operands[1] == constm1_rtx"
2338 operands[1] = constm1_rtx;
2339 return "or{q}\t{%1, %0|%0, %1}";
2341 [(set_attr "type" "alu1")
2342 (set_attr "mode" "DI")
2343 (set_attr "length_immediate" "1")])
2345 (define_insn "*movdi_2"
2346 [(set (match_operand:DI 0 "nonimmediate_operand"
2347 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2348 (match_operand:DI 1 "general_operand"
2349 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2350 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2355 movq\t{%1, %0|%0, %1}
2356 movq\t{%1, %0|%0, %1}
2358 %vmovq\t{%1, %0|%0, %1}
2359 %vmovdqa\t{%1, %0|%0, %1}
2360 %vmovq\t{%1, %0|%0, %1}
2362 movlps\t{%1, %0|%0, %1}
2363 movaps\t{%1, %0|%0, %1}
2364 movlps\t{%1, %0|%0, %1}"
2365 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2366 (set (attr "prefix")
2367 (if_then_else (eq_attr "alternative" "5,6,7,8")
2368 (const_string "vex")
2369 (const_string "orig")))
2370 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2373 [(set (match_operand:DI 0 "push_operand" "")
2374 (match_operand:DI 1 "general_operand" ""))]
2375 "!TARGET_64BIT && reload_completed
2376 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2378 "ix86_split_long_move (operands); DONE;")
2380 ;; %%% This multiword shite has got to go.
2382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2383 (match_operand:DI 1 "general_operand" ""))]
2384 "!TARGET_64BIT && reload_completed
2385 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2386 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2388 "ix86_split_long_move (operands); DONE;")
2390 (define_insn "*movdi_1_rex64"
2391 [(set (match_operand:DI 0 "nonimmediate_operand"
2392 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2393 (match_operand:DI 1 "general_operand"
2394 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2395 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2397 switch (get_attr_type (insn))
2400 if (SSE_REG_P (operands[0]))
2401 return "movq2dq\t{%1, %0|%0, %1}";
2403 return "movdq2q\t{%1, %0|%0, %1}";
2408 if (get_attr_mode (insn) == MODE_TI)
2409 return "vmovdqa\t{%1, %0|%0, %1}";
2411 return "vmovq\t{%1, %0|%0, %1}";
2414 if (get_attr_mode (insn) == MODE_TI)
2415 return "movdqa\t{%1, %0|%0, %1}";
2419 /* Moves from and into integer register is done using movd
2420 opcode with REX prefix. */
2421 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2422 return "movd\t{%1, %0|%0, %1}";
2423 return "movq\t{%1, %0|%0, %1}";
2426 return "%vpxor\t%0, %d0";
2429 return "pxor\t%0, %0";
2435 return "lea{q}\t{%a1, %0|%0, %a1}";
2438 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2439 if (get_attr_mode (insn) == MODE_SI)
2440 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2441 else if (which_alternative == 2)
2442 return "movabs{q}\t{%1, %0|%0, %1}";
2444 return "mov{q}\t{%1, %0|%0, %1}";
2448 (cond [(eq_attr "alternative" "5")
2449 (const_string "mmx")
2450 (eq_attr "alternative" "6,7,8,9,10")
2451 (const_string "mmxmov")
2452 (eq_attr "alternative" "11")
2453 (const_string "sselog1")
2454 (eq_attr "alternative" "12,13,14,15,16")
2455 (const_string "ssemov")
2456 (eq_attr "alternative" "17,18")
2457 (const_string "ssecvt")
2458 (eq_attr "alternative" "4")
2459 (const_string "multi")
2460 (match_operand:DI 1 "pic_32bit_operand" "")
2461 (const_string "lea")
2463 (const_string "imov")))
2464 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2465 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2466 (set (attr "prefix")
2467 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2468 (const_string "maybe_vex")
2469 (const_string "orig")))
2470 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2472 ;; Stores and loads of ax to arbitrary constant address.
2473 ;; We fake an second form of instruction to force reload to load address
2474 ;; into register when rax is not available
2475 (define_insn "*movabsdi_1_rex64"
2476 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2477 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2478 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2480 movabs{q}\t{%1, %P0|%P0, %1}
2481 mov{q}\t{%1, %a0|%a0, %1}"
2482 [(set_attr "type" "imov")
2483 (set_attr "modrm" "0,*")
2484 (set_attr "length_address" "8,0")
2485 (set_attr "length_immediate" "0,*")
2486 (set_attr "memory" "store")
2487 (set_attr "mode" "DI")])
2489 (define_insn "*movabsdi_2_rex64"
2490 [(set (match_operand:DI 0 "register_operand" "=a,r")
2491 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2492 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2494 movabs{q}\t{%P1, %0|%0, %P1}
2495 mov{q}\t{%a1, %0|%0, %a1}"
2496 [(set_attr "type" "imov")
2497 (set_attr "modrm" "0,*")
2498 (set_attr "length_address" "8,0")
2499 (set_attr "length_immediate" "0")
2500 (set_attr "memory" "load")
2501 (set_attr "mode" "DI")])
2503 ;; Convert impossible stores of immediate to existing instructions.
2504 ;; First try to get scratch register and go through it. In case this
2505 ;; fails, move by 32bit parts.
2507 [(match_scratch:DI 2 "r")
2508 (set (match_operand:DI 0 "memory_operand" "")
2509 (match_operand:DI 1 "immediate_operand" ""))]
2510 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2511 && !x86_64_immediate_operand (operands[1], DImode)"
2512 [(set (match_dup 2) (match_dup 1))
2513 (set (match_dup 0) (match_dup 2))]
2516 ;; We need to define this as both peepholer and splitter for case
2517 ;; peephole2 pass is not run.
2518 ;; "&& 1" is needed to keep it from matching the previous pattern.
2520 [(set (match_operand:DI 0 "memory_operand" "")
2521 (match_operand:DI 1 "immediate_operand" ""))]
2522 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2523 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2524 [(set (match_dup 2) (match_dup 3))
2525 (set (match_dup 4) (match_dup 5))]
2526 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2529 [(set (match_operand:DI 0 "memory_operand" "")
2530 (match_operand:DI 1 "immediate_operand" ""))]
2531 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2532 ? epilogue_completed : reload_completed)
2533 && !symbolic_operand (operands[1], DImode)
2534 && !x86_64_immediate_operand (operands[1], DImode)"
2535 [(set (match_dup 2) (match_dup 3))
2536 (set (match_dup 4) (match_dup 5))]
2537 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2539 (define_insn "*swapdi_rex64"
2540 [(set (match_operand:DI 0 "register_operand" "+r")
2541 (match_operand:DI 1 "register_operand" "+r"))
2546 [(set_attr "type" "imov")
2547 (set_attr "mode" "DI")
2548 (set_attr "pent_pair" "np")
2549 (set_attr "athlon_decode" "vector")
2550 (set_attr "amdfam10_decode" "double")])
2552 (define_expand "movoi"
2553 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2554 (match_operand:OI 1 "general_operand" ""))]
2556 "ix86_expand_move (OImode, operands); DONE;")
2558 (define_insn "*movoi_internal"
2559 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2560 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2564 switch (which_alternative)
2567 return "vxorps\t%0, %0, %0";
2570 if (misaligned_operand (operands[0], OImode)
2571 || misaligned_operand (operands[1], OImode))
2572 return "vmovdqu\t{%1, %0|%0, %1}";
2574 return "vmovdqa\t{%1, %0|%0, %1}";
2579 [(set_attr "type" "sselog1,ssemov,ssemov")
2580 (set_attr "prefix" "vex")
2581 (set_attr "mode" "OI")])
2583 (define_expand "movti"
2584 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2585 (match_operand:TI 1 "nonimmediate_operand" ""))]
2586 "TARGET_SSE || TARGET_64BIT"
2589 ix86_expand_move (TImode, operands);
2590 else if (push_operand (operands[0], TImode))
2591 ix86_expand_push (TImode, operands[1]);
2593 ix86_expand_vector_move (TImode, operands);
2597 (define_insn "*movti_internal"
2598 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2599 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2600 "TARGET_SSE && !TARGET_64BIT
2601 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2603 switch (which_alternative)
2606 if (get_attr_mode (insn) == MODE_V4SF)
2607 return "%vxorps\t%0, %d0";
2609 return "%vpxor\t%0, %d0";
2612 /* TDmode values are passed as TImode on the stack. Moving them
2613 to stack may result in unaligned memory access. */
2614 if (misaligned_operand (operands[0], TImode)
2615 || misaligned_operand (operands[1], TImode))
2617 if (get_attr_mode (insn) == MODE_V4SF)
2618 return "%vmovups\t{%1, %0|%0, %1}";
2620 return "%vmovdqu\t{%1, %0|%0, %1}";
2624 if (get_attr_mode (insn) == MODE_V4SF)
2625 return "%vmovaps\t{%1, %0|%0, %1}";
2627 return "%vmovdqa\t{%1, %0|%0, %1}";
2633 [(set_attr "type" "sselog1,ssemov,ssemov")
2634 (set_attr "prefix" "maybe_vex")
2636 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2638 (const_string "V4SF")
2639 (and (eq_attr "alternative" "2")
2640 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642 (const_string "V4SF")]
2643 (const_string "TI")))])
2645 (define_insn "*movti_rex64"
2646 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2647 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2649 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2651 switch (which_alternative)
2657 if (get_attr_mode (insn) == MODE_V4SF)
2658 return "%vxorps\t%0, %d0";
2660 return "%vpxor\t%0, %d0";
2663 /* TDmode values are passed as TImode on the stack. Moving them
2664 to stack may result in unaligned memory access. */
2665 if (misaligned_operand (operands[0], TImode)
2666 || misaligned_operand (operands[1], TImode))
2668 if (get_attr_mode (insn) == MODE_V4SF)
2669 return "%vmovups\t{%1, %0|%0, %1}";
2671 return "%vmovdqu\t{%1, %0|%0, %1}";
2675 if (get_attr_mode (insn) == MODE_V4SF)
2676 return "%vmovaps\t{%1, %0|%0, %1}";
2678 return "%vmovdqa\t{%1, %0|%0, %1}";
2684 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2685 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2687 (cond [(eq_attr "alternative" "2,3")
2689 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2691 (const_string "V4SF")
2692 (const_string "TI"))
2693 (eq_attr "alternative" "4")
2695 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2697 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2699 (const_string "V4SF")
2700 (const_string "TI"))]
2701 (const_string "DI")))])
2704 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2705 (match_operand:TI 1 "general_operand" ""))]
2706 "reload_completed && !SSE_REG_P (operands[0])
2707 && !SSE_REG_P (operands[1])"
2709 "ix86_split_long_move (operands); DONE;")
2711 ;; This expands to what emit_move_complex would generate if we didn't
2712 ;; have a movti pattern. Having this avoids problems with reload on
2713 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2714 ;; to have around all the time.
2715 (define_expand "movcdi"
2716 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2717 (match_operand:CDI 1 "general_operand" ""))]
2720 if (push_operand (operands[0], CDImode))
2721 emit_move_complex_push (CDImode, operands[0], operands[1]);
2723 emit_move_complex_parts (operands[0], operands[1]);
2727 (define_expand "movsf"
2728 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2729 (match_operand:SF 1 "general_operand" ""))]
2731 "ix86_expand_move (SFmode, operands); DONE;")
2733 (define_insn "*pushsf"
2734 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2735 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2738 /* Anything else should be already split before reg-stack. */
2739 gcc_assert (which_alternative == 1);
2740 return "push{l}\t%1";
2742 [(set_attr "type" "multi,push,multi")
2743 (set_attr "unit" "i387,*,*")
2744 (set_attr "mode" "SF,SI,SF")])
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2760 [(set (match_operand:SF 0 "push_operand" "")
2761 (match_operand:SF 1 "memory_operand" ""))]
2763 && MEM_P (operands[1])
2764 && (operands[2] = find_constant_src (insn))"
2769 ;; %%% Kill this when call knows how to work this out.
2771 [(set (match_operand:SF 0 "push_operand" "")
2772 (match_operand:SF 1 "any_fp_register_operand" ""))]
2774 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2775 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2778 [(set (match_operand:SF 0 "push_operand" "")
2779 (match_operand:SF 1 "any_fp_register_operand" ""))]
2781 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2782 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2784 (define_insn "*movsf_1"
2785 [(set (match_operand:SF 0 "nonimmediate_operand"
2786 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2787 (match_operand:SF 1 "general_operand"
2788 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2789 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2790 && (reload_in_progress || reload_completed
2791 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2792 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2793 && standard_80387_constant_p (operands[1]))
2794 || GET_CODE (operands[1]) != CONST_DOUBLE
2795 || memory_operand (operands[0], SFmode))"
2797 switch (which_alternative)
2801 return output_387_reg_move (insn, operands);
2804 return standard_80387_constant_opcode (operands[1]);
2808 return "mov{l}\t{%1, %0|%0, %1}";
2810 if (get_attr_mode (insn) == MODE_TI)
2811 return "%vpxor\t%0, %d0";
2813 return "%vxorps\t%0, %d0";
2815 if (get_attr_mode (insn) == MODE_V4SF)
2816 return "%vmovaps\t{%1, %0|%0, %1}";
2818 return "%vmovss\t{%1, %d0|%d0, %1}";
2821 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2822 : "vmovss\t{%1, %0|%0, %1}";
2824 return "movss\t{%1, %0|%0, %1}";
2826 return "%vmovss\t{%1, %0|%0, %1}";
2828 case 9: case 10: case 14: case 15:
2829 return "movd\t{%1, %0|%0, %1}";
2831 return "%vmovd\t{%1, %0|%0, %1}";
2834 return "movq\t{%1, %0|%0, %1}";
2840 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2841 (set (attr "prefix")
2842 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2843 (const_string "maybe_vex")
2844 (const_string "orig")))
2846 (cond [(eq_attr "alternative" "3,4,9,10")
2848 (eq_attr "alternative" "5")
2850 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2852 (ne (symbol_ref "TARGET_SSE2")
2854 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2857 (const_string "V4SF"))
2858 /* For architectures resolving dependencies on
2859 whole SSE registers use APS move to break dependency
2860 chains, otherwise use short move to avoid extra work.
2862 Do the same for architectures resolving dependencies on
2863 the parts. While in DF mode it is better to always handle
2864 just register parts, the SF mode is different due to lack
2865 of instructions to load just part of the register. It is
2866 better to maintain the whole registers in single format
2867 to avoid problems on using packed logical operations. */
2868 (eq_attr "alternative" "6")
2870 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2872 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2874 (const_string "V4SF")
2875 (const_string "SF"))
2876 (eq_attr "alternative" "11")
2877 (const_string "DI")]
2878 (const_string "SF")))])
2880 (define_insn "*swapsf"
2881 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2882 (match_operand:SF 1 "fp_register_operand" "+f"))
2885 "reload_completed || TARGET_80387"
2887 if (STACK_TOP_P (operands[0]))
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "SF")])
2895 (define_expand "movdf"
2896 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2897 (match_operand:DF 1 "general_operand" ""))]
2899 "ix86_expand_move (DFmode, operands); DONE;")
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2903 ;; On the average, pushdf using integers can be still shorter. Allow this
2904 ;; pattern for optimize_size too.
2906 (define_insn "*pushdf_nointeger"
2907 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2908 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2909 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2911 /* This insn should be already split before reg-stack. */
2914 [(set_attr "type" "multi")
2915 (set_attr "unit" "i387,*,*,*")
2916 (set_attr "mode" "DF,SI,SI,DF")])
2918 (define_insn "*pushdf_integer"
2919 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2920 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2921 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2923 /* This insn should be already split before reg-stack. */
2926 [(set_attr "type" "multi")
2927 (set_attr "unit" "i387,*,*")
2928 (set_attr "mode" "DF,SI,DF")])
2930 ;; %%% Kill this when call knows how to work this out.
2932 [(set (match_operand:DF 0 "push_operand" "")
2933 (match_operand:DF 1 "any_fp_register_operand" ""))]
2935 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2936 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2940 [(set (match_operand:DF 0 "push_operand" "")
2941 (match_operand:DF 1 "general_operand" ""))]
2944 "ix86_split_long_move (operands); DONE;")
2946 ;; Moving is usually shorter when only FP registers are used. This separate
2947 ;; movdf pattern avoids the use of integer registers for FP operations
2948 ;; when optimizing for size.
2950 (define_insn "*movdf_nointeger"
2951 [(set (match_operand:DF 0 "nonimmediate_operand"
2952 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2953 (match_operand:DF 1 "general_operand"
2954 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2955 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2956 && ((optimize_function_for_size_p (cfun)
2957 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2958 && (reload_in_progress || reload_completed
2959 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2960 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2961 && optimize_function_for_size_p (cfun)
2962 && !memory_operand (operands[0], DFmode)
2963 && standard_80387_constant_p (operands[1]))
2964 || GET_CODE (operands[1]) != CONST_DOUBLE
2965 || ((optimize_function_for_size_p (cfun)
2966 || !TARGET_MEMORY_MISMATCH_STALL
2967 || reload_in_progress || reload_completed)
2968 && memory_operand (operands[0], DFmode)))"
2970 switch (which_alternative)
2974 return output_387_reg_move (insn, operands);
2977 return standard_80387_constant_opcode (operands[1]);
2983 switch (get_attr_mode (insn))
2986 return "%vxorps\t%0, %d0";
2988 return "%vxorpd\t%0, %d0";
2990 return "%vpxor\t%0, %d0";
2997 switch (get_attr_mode (insn))
3000 return "%vmovaps\t{%1, %0|%0, %1}";
3002 return "%vmovapd\t{%1, %0|%0, %1}";
3004 return "%vmovdqa\t{%1, %0|%0, %1}";
3006 return "%vmovq\t{%1, %0|%0, %1}";
3010 if (REG_P (operands[0]) && REG_P (operands[1]))
3011 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3013 return "vmovsd\t{%1, %0|%0, %1}";
3016 return "movsd\t{%1, %0|%0, %1}";
3020 if (REG_P (operands[0]))
3021 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3023 return "vmovlpd\t{%1, %0|%0, %1}";
3026 return "movlpd\t{%1, %0|%0, %1}";
3030 if (REG_P (operands[0]))
3031 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3033 return "vmovlps\t{%1, %0|%0, %1}";
3036 return "movlps\t{%1, %0|%0, %1}";
3045 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3046 (set (attr "prefix")
3047 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3048 (const_string "orig")
3049 (const_string "maybe_vex")))
3051 (cond [(eq_attr "alternative" "0,1,2")
3053 (eq_attr "alternative" "3,4")
3056 /* For SSE1, we have many fewer alternatives. */
3057 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3058 (cond [(eq_attr "alternative" "5,6")
3059 (const_string "V4SF")
3061 (const_string "V2SF"))
3063 /* xorps is one byte shorter. */
3064 (eq_attr "alternative" "5")
3065 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3067 (const_string "V4SF")
3068 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3072 (const_string "V2DF"))
3074 /* For architectures resolving dependencies on
3075 whole SSE registers use APD move to break dependency
3076 chains, otherwise use short move to avoid extra work.
3078 movaps encodes one byte shorter. */
3079 (eq_attr "alternative" "6")
3081 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3083 (const_string "V4SF")
3084 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3086 (const_string "V2DF")
3088 (const_string "DF"))
3089 /* For architectures resolving dependencies on register
3090 parts we may avoid extra work to zero out upper part
3092 (eq_attr "alternative" "7")
3094 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3096 (const_string "V1DF")
3097 (const_string "DF"))
3099 (const_string "DF")))])
3101 (define_insn "*movdf_integer_rex64"
3102 [(set (match_operand:DF 0 "nonimmediate_operand"
3103 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3104 (match_operand:DF 1 "general_operand"
3105 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3106 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3107 && (reload_in_progress || reload_completed
3108 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3109 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3110 && optimize_function_for_size_p (cfun)
3111 && standard_80387_constant_p (operands[1]))
3112 || GET_CODE (operands[1]) != CONST_DOUBLE
3113 || memory_operand (operands[0], DFmode))"
3115 switch (which_alternative)
3119 return output_387_reg_move (insn, operands);
3122 return standard_80387_constant_opcode (operands[1]);
3129 switch (get_attr_mode (insn))
3132 return "%vxorps\t%0, %d0";
3134 return "%vxorpd\t%0, %d0";
3136 return "%vpxor\t%0, %d0";
3143 switch (get_attr_mode (insn))
3146 return "%vmovaps\t{%1, %0|%0, %1}";
3148 return "%vmovapd\t{%1, %0|%0, %1}";
3150 return "%vmovdqa\t{%1, %0|%0, %1}";
3152 return "%vmovq\t{%1, %0|%0, %1}";
3156 if (REG_P (operands[0]) && REG_P (operands[1]))
3157 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3159 return "vmovsd\t{%1, %0|%0, %1}";
3162 return "movsd\t{%1, %0|%0, %1}";
3164 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3166 return "%vmovlps\t{%1, %d0|%d0, %1}";
3173 return "%vmovd\t{%1, %0|%0, %1}";
3179 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3180 (set (attr "prefix")
3181 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3182 (const_string "orig")
3183 (const_string "maybe_vex")))
3185 (cond [(eq_attr "alternative" "0,1,2")
3187 (eq_attr "alternative" "3,4,9,10")
3190 /* For SSE1, we have many fewer alternatives. */
3191 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3192 (cond [(eq_attr "alternative" "5,6")
3193 (const_string "V4SF")
3195 (const_string "V2SF"))
3197 /* xorps is one byte shorter. */
3198 (eq_attr "alternative" "5")
3199 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3201 (const_string "V4SF")
3202 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3206 (const_string "V2DF"))
3208 /* For architectures resolving dependencies on
3209 whole SSE registers use APD move to break dependency
3210 chains, otherwise use short move to avoid extra work.
3212 movaps encodes one byte shorter. */
3213 (eq_attr "alternative" "6")
3215 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3217 (const_string "V4SF")
3218 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3220 (const_string "V2DF")
3222 (const_string "DF"))
3223 /* For architectures resolving dependencies on register
3224 parts we may avoid extra work to zero out upper part
3226 (eq_attr "alternative" "7")
3228 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3230 (const_string "V1DF")
3231 (const_string "DF"))
3233 (const_string "DF")))])
3235 (define_insn "*movdf_integer"
3236 [(set (match_operand:DF 0 "nonimmediate_operand"
3237 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3238 (match_operand:DF 1 "general_operand"
3239 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3240 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3241 && optimize_function_for_speed_p (cfun)
3242 && TARGET_INTEGER_DFMODE_MOVES
3243 && (reload_in_progress || reload_completed
3244 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3245 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3246 && optimize_function_for_size_p (cfun)
3247 && standard_80387_constant_p (operands[1]))
3248 || GET_CODE (operands[1]) != CONST_DOUBLE
3249 || memory_operand (operands[0], DFmode))"
3251 switch (which_alternative)
3255 return output_387_reg_move (insn, operands);
3258 return standard_80387_constant_opcode (operands[1]);
3265 switch (get_attr_mode (insn))
3268 return "xorps\t%0, %0";
3270 return "xorpd\t%0, %0";
3272 return "pxor\t%0, %0";
3279 switch (get_attr_mode (insn))
3282 return "movaps\t{%1, %0|%0, %1}";
3284 return "movapd\t{%1, %0|%0, %1}";
3286 return "movdqa\t{%1, %0|%0, %1}";
3288 return "movq\t{%1, %0|%0, %1}";
3290 return "movsd\t{%1, %0|%0, %1}";
3292 return "movlpd\t{%1, %0|%0, %1}";
3294 return "movlps\t{%1, %0|%0, %1}";
3303 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305 (cond [(eq_attr "alternative" "0,1,2")
3307 (eq_attr "alternative" "3,4")
3310 /* For SSE1, we have many fewer alternatives. */
3311 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3312 (cond [(eq_attr "alternative" "5,6")
3313 (const_string "V4SF")
3315 (const_string "V2SF"))
3317 /* xorps is one byte shorter. */
3318 (eq_attr "alternative" "5")
3319 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3321 (const_string "V4SF")
3322 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3326 (const_string "V2DF"))
3328 /* For architectures resolving dependencies on
3329 whole SSE registers use APD move to break dependency
3330 chains, otherwise use short move to avoid extra work.
3332 movaps encodes one byte shorter. */
3333 (eq_attr "alternative" "6")
3335 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3337 (const_string "V4SF")
3338 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3340 (const_string "V2DF")
3342 (const_string "DF"))
3343 /* For architectures resolving dependencies on register
3344 parts we may avoid extra work to zero out upper part
3346 (eq_attr "alternative" "7")
3348 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3350 (const_string "V1DF")
3351 (const_string "DF"))
3353 (const_string "DF")))])
3356 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3357 (match_operand:DF 1 "general_operand" ""))]
3359 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360 && ! (ANY_FP_REG_P (operands[0]) ||
3361 (GET_CODE (operands[0]) == SUBREG
3362 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3363 && ! (ANY_FP_REG_P (operands[1]) ||
3364 (GET_CODE (operands[1]) == SUBREG
3365 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3367 "ix86_split_long_move (operands); DONE;")
3369 (define_insn "*swapdf"
3370 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3371 (match_operand:DF 1 "fp_register_operand" "+f"))
3374 "reload_completed || TARGET_80387"
3376 if (STACK_TOP_P (operands[0]))
3381 [(set_attr "type" "fxch")
3382 (set_attr "mode" "DF")])
3384 (define_expand "movxf"
3385 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3386 (match_operand:XF 1 "general_operand" ""))]
3388 "ix86_expand_move (XFmode, operands); DONE;")
3390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3391 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3392 ;; Pushing using integer instructions is longer except for constants
3393 ;; and direct memory references.
3394 ;; (assuming that any given constant is pushed only once, but this ought to be
3395 ;; handled elsewhere).
3397 (define_insn "*pushxf_nointeger"
3398 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3399 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3400 "optimize_function_for_size_p (cfun)"
3402 /* This insn should be already split before reg-stack. */
3405 [(set_attr "type" "multi")
3406 (set_attr "unit" "i387,*,*")
3407 (set_attr "mode" "XF,SI,SI")])
3409 (define_insn "*pushxf_integer"
3410 [(set (match_operand:XF 0 "push_operand" "=<,<")
3411 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3412 "optimize_function_for_speed_p (cfun)"
3414 /* This insn should be already split before reg-stack. */
3417 [(set_attr "type" "multi")
3418 (set_attr "unit" "i387,*")
3419 (set_attr "mode" "XF,SI")])
3422 [(set (match_operand 0 "push_operand" "")
3423 (match_operand 1 "general_operand" ""))]
3425 && (GET_MODE (operands[0]) == XFmode
3426 || GET_MODE (operands[0]) == DFmode)
3427 && !ANY_FP_REG_P (operands[1])"
3429 "ix86_split_long_move (operands); DONE;")
3432 [(set (match_operand:XF 0 "push_operand" "")
3433 (match_operand:XF 1 "any_fp_register_operand" ""))]
3435 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3436 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3437 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3439 ;; Do not use integer registers when optimizing for size
3440 (define_insn "*movxf_nointeger"
3441 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3442 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3443 "optimize_function_for_size_p (cfun)
3444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3445 && (reload_in_progress || reload_completed
3446 || standard_80387_constant_p (operands[1])
3447 || GET_CODE (operands[1]) != CONST_DOUBLE
3448 || memory_operand (operands[0], XFmode))"
3450 switch (which_alternative)
3454 return output_387_reg_move (insn, operands);
3457 return standard_80387_constant_opcode (operands[1]);
3465 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3466 (set_attr "mode" "XF,XF,XF,SI,SI")])
3468 (define_insn "*movxf_integer"
3469 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3470 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3471 "optimize_function_for_speed_p (cfun)
3472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3473 && (reload_in_progress || reload_completed
3474 || GET_CODE (operands[1]) != CONST_DOUBLE
3475 || memory_operand (operands[0], XFmode))"
3477 switch (which_alternative)
3481 return output_387_reg_move (insn, operands);
3484 return standard_80387_constant_opcode (operands[1]);
3493 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3494 (set_attr "mode" "XF,XF,XF,SI,SI")])
3496 (define_expand "movtf"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498 (match_operand:TF 1 "nonimmediate_operand" ""))]
3501 ix86_expand_move (TFmode, operands);
3505 (define_insn "*movtf_internal"
3506 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3507 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3509 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3511 switch (which_alternative)
3515 if (get_attr_mode (insn) == MODE_V4SF)
3516 return "%vmovaps\t{%1, %0|%0, %1}";
3518 return "%vmovdqa\t{%1, %0|%0, %1}";
3520 if (get_attr_mode (insn) == MODE_V4SF)
3521 return "%vxorps\t%0, %d0";
3523 return "%vpxor\t%0, %d0";
3531 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3532 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3534 (cond [(eq_attr "alternative" "0,2")
3536 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3538 (const_string "V4SF")
3539 (const_string "TI"))
3540 (eq_attr "alternative" "1")
3542 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3544 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3546 (const_string "V4SF")
3547 (const_string "TI"))]
3548 (const_string "DI")))])
3550 (define_insn "*pushtf_sse"
3551 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3552 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3555 /* This insn should be already split before reg-stack. */
3558 [(set_attr "type" "multi")
3559 (set_attr "unit" "sse,*,*")
3560 (set_attr "mode" "TF,SI,SI")])
3563 [(set (match_operand:TF 0 "push_operand" "")
3564 (match_operand:TF 1 "general_operand" ""))]
3565 "TARGET_SSE2 && reload_completed
3566 && !SSE_REG_P (operands[1])"
3568 "ix86_split_long_move (operands); DONE;")
3571 [(set (match_operand:TF 0 "push_operand" "")
3572 (match_operand:TF 1 "any_fp_register_operand" ""))]
3574 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3575 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3579 [(set (match_operand 0 "nonimmediate_operand" "")
3580 (match_operand 1 "general_operand" ""))]
3582 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3583 && GET_MODE (operands[0]) == XFmode
3584 && ! (ANY_FP_REG_P (operands[0]) ||
3585 (GET_CODE (operands[0]) == SUBREG
3586 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3587 && ! (ANY_FP_REG_P (operands[1]) ||
3588 (GET_CODE (operands[1]) == SUBREG
3589 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3591 "ix86_split_long_move (operands); DONE;")
3594 [(set (match_operand 0 "register_operand" "")
3595 (match_operand 1 "memory_operand" ""))]
3597 && MEM_P (operands[1])
3598 && (GET_MODE (operands[0]) == TFmode
3599 || GET_MODE (operands[0]) == XFmode
3600 || GET_MODE (operands[0]) == SFmode
3601 || GET_MODE (operands[0]) == DFmode)
3602 && (operands[2] = find_constant_src (insn))"
3603 [(set (match_dup 0) (match_dup 2))]
3605 rtx c = operands[2];
3606 rtx r = operands[0];
3608 if (GET_CODE (r) == SUBREG)
3613 if (!standard_sse_constant_p (c))
3616 else if (FP_REG_P (r))
3618 if (!standard_80387_constant_p (c))
3621 else if (MMX_REG_P (r))
3626 [(set (match_operand 0 "register_operand" "")
3627 (float_extend (match_operand 1 "memory_operand" "")))]
3629 && MEM_P (operands[1])
3630 && (GET_MODE (operands[0]) == TFmode
3631 || GET_MODE (operands[0]) == XFmode
3632 || GET_MODE (operands[0]) == SFmode
3633 || GET_MODE (operands[0]) == DFmode)
3634 && (operands[2] = find_constant_src (insn))"
3635 [(set (match_dup 0) (match_dup 2))]
3637 rtx c = operands[2];
3638 rtx r = operands[0];
3640 if (GET_CODE (r) == SUBREG)
3645 if (!standard_sse_constant_p (c))
3648 else if (FP_REG_P (r))
3650 if (!standard_80387_constant_p (c))
3653 else if (MMX_REG_P (r))
3657 (define_insn "swapxf"
3658 [(set (match_operand:XF 0 "register_operand" "+f")
3659 (match_operand:XF 1 "register_operand" "+f"))
3664 if (STACK_TOP_P (operands[0]))
3669 [(set_attr "type" "fxch")
3670 (set_attr "mode" "XF")])
3672 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3674 [(set (match_operand:X87MODEF 0 "register_operand" "")
3675 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3676 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3677 && (standard_80387_constant_p (operands[1]) == 8
3678 || standard_80387_constant_p (operands[1]) == 9)"
3679 [(set (match_dup 0)(match_dup 1))
3681 (neg:X87MODEF (match_dup 0)))]
3685 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3686 if (real_isnegzero (&r))
3687 operands[1] = CONST0_RTX (<MODE>mode);
3689 operands[1] = CONST1_RTX (<MODE>mode);
3693 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3694 (match_operand:TF 1 "general_operand" ""))]
3696 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3698 "ix86_split_long_move (operands); DONE;")
3700 ;; Zero extension instructions
3702 (define_expand "zero_extendhisi2"
3703 [(set (match_operand:SI 0 "register_operand" "")
3704 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3707 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3709 operands[1] = force_reg (HImode, operands[1]);
3710 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3715 (define_insn "zero_extendhisi2_and"
3716 [(set (match_operand:SI 0 "register_operand" "=r")
3717 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3718 (clobber (reg:CC FLAGS_REG))]
3719 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721 [(set_attr "type" "alu1")
3722 (set_attr "mode" "SI")])
3725 [(set (match_operand:SI 0 "register_operand" "")
3726 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3727 (clobber (reg:CC FLAGS_REG))]
3728 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3729 && optimize_function_for_speed_p (cfun)"
3730 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3731 (clobber (reg:CC FLAGS_REG))])]
3734 (define_insn "*zero_extendhisi2_movzwl"
3735 [(set (match_operand:SI 0 "register_operand" "=r")
3736 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3737 "!TARGET_ZERO_EXTEND_WITH_AND
3738 || optimize_function_for_size_p (cfun)"
3739 "movz{wl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3743 (define_expand "zero_extendqihi2"
3745 [(set (match_operand:HI 0 "register_operand" "")
3746 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3747 (clobber (reg:CC FLAGS_REG))])]
3751 (define_insn "*zero_extendqihi2_and"
3752 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3753 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3754 (clobber (reg:CC FLAGS_REG))]
3755 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3757 [(set_attr "type" "alu1")
3758 (set_attr "mode" "HI")])
3760 (define_insn "*zero_extendqihi2_movzbw_and"
3761 [(set (match_operand:HI 0 "register_operand" "=r,r")
3762 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3763 (clobber (reg:CC FLAGS_REG))]
3764 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3766 [(set_attr "type" "imovx,alu1")
3767 (set_attr "mode" "HI")])
3769 ; zero extend to SImode here to avoid partial register stalls
3770 (define_insn "*zero_extendqihi2_movzbl"
3771 [(set (match_operand:HI 0 "register_operand" "=r")
3772 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3773 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3774 && reload_completed"
3775 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "SI")])
3779 ;; For the movzbw case strip only the clobber
3781 [(set (match_operand:HI 0 "register_operand" "")
3782 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3783 (clobber (reg:CC FLAGS_REG))]
3785 && (!TARGET_ZERO_EXTEND_WITH_AND
3786 || optimize_function_for_size_p (cfun))
3787 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3788 [(set (match_operand:HI 0 "register_operand" "")
3789 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3791 ;; When source and destination does not overlap, clear destination
3792 ;; first and then do the movb
3794 [(set (match_operand:HI 0 "register_operand" "")
3795 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3796 (clobber (reg:CC FLAGS_REG))]
3798 && ANY_QI_REG_P (operands[0])
3799 && (TARGET_ZERO_EXTEND_WITH_AND
3800 && optimize_function_for_speed_p (cfun))
3801 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3802 [(set (match_dup 0) (const_int 0))
3803 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3804 "operands[2] = gen_lowpart (QImode, operands[0]);")
3806 ;; Rest is handled by single and.
3808 [(set (match_operand:HI 0 "register_operand" "")
3809 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3810 (clobber (reg:CC FLAGS_REG))]
3812 && true_regnum (operands[0]) == true_regnum (operands[1])"
3813 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3814 (clobber (reg:CC FLAGS_REG))])]
3817 (define_expand "zero_extendqisi2"
3819 [(set (match_operand:SI 0 "register_operand" "")
3820 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821 (clobber (reg:CC FLAGS_REG))])]
3825 (define_insn "*zero_extendqisi2_and"
3826 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3827 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3828 (clobber (reg:CC FLAGS_REG))]
3829 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3831 [(set_attr "type" "alu1")
3832 (set_attr "mode" "SI")])
3834 (define_insn "*zero_extendqisi2_movzbw_and"
3835 [(set (match_operand:SI 0 "register_operand" "=r,r")
3836 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3837 (clobber (reg:CC FLAGS_REG))]
3838 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3840 [(set_attr "type" "imovx,alu1")
3841 (set_attr "mode" "SI")])
3843 (define_insn "*zero_extendqisi2_movzbw"
3844 [(set (match_operand:SI 0 "register_operand" "=r")
3845 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3846 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3847 && reload_completed"
3848 "movz{bl|x}\t{%1, %0|%0, %1}"
3849 [(set_attr "type" "imovx")
3850 (set_attr "mode" "SI")])
3852 ;; For the movzbl case strip only the clobber
3854 [(set (match_operand:SI 0 "register_operand" "")
3855 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3856 (clobber (reg:CC FLAGS_REG))]
3858 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3859 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3861 (zero_extend:SI (match_dup 1)))])
3863 ;; When source and destination does not overlap, clear destination
3864 ;; first and then do the movb
3866 [(set (match_operand:SI 0 "register_operand" "")
3867 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3868 (clobber (reg:CC FLAGS_REG))]
3870 && ANY_QI_REG_P (operands[0])
3871 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3872 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3873 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3874 [(set (match_dup 0) (const_int 0))
3875 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3876 "operands[2] = gen_lowpart (QImode, operands[0]);")
3878 ;; Rest is handled by single and.
3880 [(set (match_operand:SI 0 "register_operand" "")
3881 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3882 (clobber (reg:CC FLAGS_REG))]
3884 && true_regnum (operands[0]) == true_regnum (operands[1])"
3885 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3886 (clobber (reg:CC FLAGS_REG))])]
3889 ;; %%% Kill me once multi-word ops are sane.
3890 (define_expand "zero_extendsidi2"
3891 [(set (match_operand:DI 0 "register_operand" "")
3892 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3897 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3902 (define_insn "zero_extendsidi2_32"
3903 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3905 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3906 (clobber (reg:CC FLAGS_REG))]
3912 movd\t{%1, %0|%0, %1}
3913 movd\t{%1, %0|%0, %1}
3914 %vmovd\t{%1, %0|%0, %1}
3915 %vmovd\t{%1, %0|%0, %1}"
3916 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3917 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3918 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3920 (define_insn "zero_extendsidi2_rex64"
3921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3923 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3926 mov\t{%k1, %k0|%k0, %k1}
3928 movd\t{%1, %0|%0, %1}
3929 movd\t{%1, %0|%0, %1}
3930 %vmovd\t{%1, %0|%0, %1}
3931 %vmovd\t{%1, %0|%0, %1}"
3932 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3933 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3934 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3937 [(set (match_operand:DI 0 "memory_operand" "")
3938 (zero_extend:DI (match_dup 0)))]
3940 [(set (match_dup 4) (const_int 0))]
3941 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3944 [(set (match_operand:DI 0 "register_operand" "")
3945 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3946 (clobber (reg:CC FLAGS_REG))]
3947 "!TARGET_64BIT && reload_completed
3948 && true_regnum (operands[0]) == true_regnum (operands[1])"
3949 [(set (match_dup 4) (const_int 0))]
3950 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3953 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3954 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3955 (clobber (reg:CC FLAGS_REG))]
3956 "!TARGET_64BIT && reload_completed
3957 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3958 [(set (match_dup 3) (match_dup 1))
3959 (set (match_dup 4) (const_int 0))]
3960 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3962 (define_insn "zero_extendhidi2"
3963 [(set (match_operand:DI 0 "register_operand" "=r")
3964 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3966 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3967 [(set_attr "type" "imovx")
3968 (set_attr "mode" "DI")])
3970 (define_insn "zero_extendqidi2"
3971 [(set (match_operand:DI 0 "register_operand" "=r")
3972 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3974 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3975 [(set_attr "type" "imovx")
3976 (set_attr "mode" "DI")])
3978 ;; Sign extension instructions
3980 (define_expand "extendsidi2"
3981 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3982 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3983 (clobber (reg:CC FLAGS_REG))
3984 (clobber (match_scratch:SI 2 ""))])]
3989 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3994 (define_insn "*extendsidi2_1"
3995 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3996 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3997 (clobber (reg:CC FLAGS_REG))
3998 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4002 (define_insn "extendsidi2_rex64"
4003 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4004 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4008 movs{lq|x}\t{%1,%0|%0, %1}"
4009 [(set_attr "type" "imovx")
4010 (set_attr "mode" "DI")
4011 (set_attr "prefix_0f" "0")
4012 (set_attr "modrm" "0,1")])
4014 (define_insn "extendhidi2"
4015 [(set (match_operand:DI 0 "register_operand" "=r")
4016 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4018 "movs{wq|x}\t{%1,%0|%0, %1}"
4019 [(set_attr "type" "imovx")
4020 (set_attr "mode" "DI")])
4022 (define_insn "extendqidi2"
4023 [(set (match_operand:DI 0 "register_operand" "=r")
4024 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4026 "movs{bq|x}\t{%1,%0|%0, %1}"
4027 [(set_attr "type" "imovx")
4028 (set_attr "mode" "DI")])
4030 ;; Extend to memory case when source register does die.
4032 [(set (match_operand:DI 0 "memory_operand" "")
4033 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4034 (clobber (reg:CC FLAGS_REG))
4035 (clobber (match_operand:SI 2 "register_operand" ""))]
4037 && dead_or_set_p (insn, operands[1])
4038 && !reg_mentioned_p (operands[1], operands[0]))"
4039 [(set (match_dup 3) (match_dup 1))
4040 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4041 (clobber (reg:CC FLAGS_REG))])
4042 (set (match_dup 4) (match_dup 1))]
4043 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4045 ;; Extend to memory case when source register does not die.
4047 [(set (match_operand:DI 0 "memory_operand" "")
4048 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4049 (clobber (reg:CC FLAGS_REG))
4050 (clobber (match_operand:SI 2 "register_operand" ""))]
4054 split_di (&operands[0], 1, &operands[3], &operands[4]);
4056 emit_move_insn (operands[3], operands[1]);
4058 /* Generate a cltd if possible and doing so it profitable. */
4059 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4060 && true_regnum (operands[1]) == AX_REG
4061 && true_regnum (operands[2]) == DX_REG)
4063 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4067 emit_move_insn (operands[2], operands[1]);
4068 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4070 emit_move_insn (operands[4], operands[2]);
4074 ;; Extend to register case. Optimize case where source and destination
4075 ;; registers match and cases where we can use cltd.
4077 [(set (match_operand:DI 0 "register_operand" "")
4078 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4079 (clobber (reg:CC FLAGS_REG))
4080 (clobber (match_scratch:SI 2 ""))]
4084 split_di (&operands[0], 1, &operands[3], &operands[4]);
4086 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4087 emit_move_insn (operands[3], operands[1]);
4089 /* Generate a cltd if possible and doing so it profitable. */
4090 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4091 && true_regnum (operands[3]) == AX_REG)
4093 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4097 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4098 emit_move_insn (operands[4], operands[1]);
4100 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4104 (define_insn "extendhisi2"
4105 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4106 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4109 switch (get_attr_prefix_0f (insn))
4112 return "{cwtl|cwde}";
4114 return "movs{wl|x}\t{%1,%0|%0, %1}";
4117 [(set_attr "type" "imovx")
4118 (set_attr "mode" "SI")
4119 (set (attr "prefix_0f")
4120 ;; movsx is short decodable while cwtl is vector decoded.
4121 (if_then_else (and (eq_attr "cpu" "!k6")
4122 (eq_attr "alternative" "0"))
4124 (const_string "1")))
4126 (if_then_else (eq_attr "prefix_0f" "0")
4128 (const_string "1")))])
4130 (define_insn "*extendhisi2_zext"
4131 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4133 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4136 switch (get_attr_prefix_0f (insn))
4139 return "{cwtl|cwde}";
4141 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4144 [(set_attr "type" "imovx")
4145 (set_attr "mode" "SI")
4146 (set (attr "prefix_0f")
4147 ;; movsx is short decodable while cwtl is vector decoded.
4148 (if_then_else (and (eq_attr "cpu" "!k6")
4149 (eq_attr "alternative" "0"))
4151 (const_string "1")))
4153 (if_then_else (eq_attr "prefix_0f" "0")
4155 (const_string "1")))])
4157 (define_insn "extendqihi2"
4158 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4159 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4162 switch (get_attr_prefix_0f (insn))
4165 return "{cbtw|cbw}";
4167 return "movs{bw|x}\t{%1,%0|%0, %1}";
4170 [(set_attr "type" "imovx")
4171 (set_attr "mode" "HI")
4172 (set (attr "prefix_0f")
4173 ;; movsx is short decodable while cwtl is vector decoded.
4174 (if_then_else (and (eq_attr "cpu" "!k6")
4175 (eq_attr "alternative" "0"))
4177 (const_string "1")))
4179 (if_then_else (eq_attr "prefix_0f" "0")
4181 (const_string "1")))])
4183 (define_insn "extendqisi2"
4184 [(set (match_operand:SI 0 "register_operand" "=r")
4185 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4187 "movs{bl|x}\t{%1,%0|%0, %1}"
4188 [(set_attr "type" "imovx")
4189 (set_attr "mode" "SI")])
4191 (define_insn "*extendqisi2_zext"
4192 [(set (match_operand:DI 0 "register_operand" "=r")
4194 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4196 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4197 [(set_attr "type" "imovx")
4198 (set_attr "mode" "SI")])
4200 ;; Conversions between float and double.
4202 ;; These are all no-ops in the model used for the 80387. So just
4205 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4206 (define_insn "*dummy_extendsfdf2"
4207 [(set (match_operand:DF 0 "push_operand" "=<")
4208 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4213 [(set (match_operand:DF 0 "push_operand" "")
4214 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4216 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4217 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4219 (define_insn "*dummy_extendsfxf2"
4220 [(set (match_operand:XF 0 "push_operand" "=<")
4221 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4226 [(set (match_operand:XF 0 "push_operand" "")
4227 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4229 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4230 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4231 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4234 [(set (match_operand:XF 0 "push_operand" "")
4235 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4237 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4238 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4239 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4241 (define_expand "extendsfdf2"
4242 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4243 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4244 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4246 /* ??? Needed for compress_float_constant since all fp constants
4247 are LEGITIMATE_CONSTANT_P. */
4248 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4250 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4251 && standard_80387_constant_p (operands[1]) > 0)
4253 operands[1] = simplify_const_unary_operation
4254 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4255 emit_move_insn_1 (operands[0], operands[1]);
4258 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4262 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4264 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4266 We do the conversion post reload to avoid producing of 128bit spills
4267 that might lead to ICE on 32bit target. The sequence unlikely combine
4270 [(set (match_operand:DF 0 "register_operand" "")
4272 (match_operand:SF 1 "nonimmediate_operand" "")))]
4273 "TARGET_USE_VECTOR_FP_CONVERTS
4274 && optimize_insn_for_speed_p ()
4275 && reload_completed && SSE_REG_P (operands[0])"
4280 (parallel [(const_int 0) (const_int 1)]))))]
4282 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4283 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4284 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4285 Try to avoid move when unpacking can be done in source. */
4286 if (REG_P (operands[1]))
4288 /* If it is unsafe to overwrite upper half of source, we need
4289 to move to destination and unpack there. */
4290 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4291 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4292 && true_regnum (operands[0]) != true_regnum (operands[1]))
4294 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4295 emit_move_insn (tmp, operands[1]);
4298 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4299 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4302 emit_insn (gen_vec_setv4sf_0 (operands[3],
4303 CONST0_RTX (V4SFmode), operands[1]));
4306 (define_insn "*extendsfdf2_mixed"
4307 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4309 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4310 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4312 switch (which_alternative)
4316 return output_387_reg_move (insn, operands);
4319 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4325 [(set_attr "type" "fmov,fmov,ssecvt")
4326 (set_attr "prefix" "orig,orig,maybe_vex")
4327 (set_attr "mode" "SF,XF,DF")])
4329 (define_insn "*extendsfdf2_sse"
4330 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4331 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4332 "TARGET_SSE2 && TARGET_SSE_MATH"
4333 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4334 [(set_attr "type" "ssecvt")
4335 (set_attr "prefix" "maybe_vex")
4336 (set_attr "mode" "DF")])
4338 (define_insn "*extendsfdf2_i387"
4339 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4340 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4342 "* return output_387_reg_move (insn, operands);"
4343 [(set_attr "type" "fmov")
4344 (set_attr "mode" "SF,XF")])
4346 (define_expand "extend<mode>xf2"
4347 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4348 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4351 /* ??? Needed for compress_float_constant since all fp constants
4352 are LEGITIMATE_CONSTANT_P. */
4353 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4355 if (standard_80387_constant_p (operands[1]) > 0)
4357 operands[1] = simplify_const_unary_operation
4358 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4359 emit_move_insn_1 (operands[0], operands[1]);
4362 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4366 (define_insn "*extend<mode>xf2_i387"
4367 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4369 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4371 "* return output_387_reg_move (insn, operands);"
4372 [(set_attr "type" "fmov")
4373 (set_attr "mode" "<MODE>,XF")])
4375 ;; %%% This seems bad bad news.
4376 ;; This cannot output into an f-reg because there is no way to be sure
4377 ;; of truncating in that case. Otherwise this is just like a simple move
4378 ;; insn. So we pretend we can output to a reg in order to get better
4379 ;; register preferencing, but we really use a stack slot.
4381 ;; Conversion from DFmode to SFmode.
4383 (define_expand "truncdfsf2"
4384 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4386 (match_operand:DF 1 "nonimmediate_operand" "")))]
4387 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4389 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4391 else if (flag_unsafe_math_optimizations)
4395 enum ix86_stack_slot slot = (virtuals_instantiated
4398 rtx temp = assign_386_stack_local (SFmode, slot);
4399 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4404 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4406 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4408 We do the conversion post reload to avoid producing of 128bit spills
4409 that might lead to ICE on 32bit target. The sequence unlikely combine
4412 [(set (match_operand:SF 0 "register_operand" "")
4414 (match_operand:DF 1 "nonimmediate_operand" "")))]
4415 "TARGET_USE_VECTOR_FP_CONVERTS
4416 && optimize_insn_for_speed_p ()
4417 && reload_completed && SSE_REG_P (operands[0])"
4420 (float_truncate:V2SF
4424 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4425 operands[3] = CONST0_RTX (V2SFmode);
4426 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4427 /* Use movsd for loading from memory, unpcklpd for registers.
4428 Try to avoid move when unpacking can be done in source, or SSE3
4429 movddup is available. */
4430 if (REG_P (operands[1]))
4433 && true_regnum (operands[0]) != true_regnum (operands[1])
4434 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4435 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4437 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4438 emit_move_insn (tmp, operands[1]);
4441 else if (!TARGET_SSE3)
4442 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4443 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4446 emit_insn (gen_sse2_loadlpd (operands[4],
4447 CONST0_RTX (V2DFmode), operands[1]));
4450 (define_expand "truncdfsf2_with_temp"
4451 [(parallel [(set (match_operand:SF 0 "" "")
4452 (float_truncate:SF (match_operand:DF 1 "" "")))
4453 (clobber (match_operand:SF 2 "" ""))])]
4456 (define_insn "*truncdfsf_fast_mixed"
4457 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4459 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4460 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4462 switch (which_alternative)
4465 return output_387_reg_move (insn, operands);
4467 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4472 [(set_attr "type" "fmov,ssecvt")
4473 (set_attr "prefix" "orig,maybe_vex")
4474 (set_attr "mode" "SF")])
4476 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4477 ;; because nothing we do here is unsafe.
4478 (define_insn "*truncdfsf_fast_sse"
4479 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4481 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4482 "TARGET_SSE2 && TARGET_SSE_MATH"
4483 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4484 [(set_attr "type" "ssecvt")
4485 (set_attr "prefix" "maybe_vex")
4486 (set_attr "mode" "SF")])
4488 (define_insn "*truncdfsf_fast_i387"
4489 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4491 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4492 "TARGET_80387 && flag_unsafe_math_optimizations"
4493 "* return output_387_reg_move (insn, operands);"
4494 [(set_attr "type" "fmov")
4495 (set_attr "mode" "SF")])
4497 (define_insn "*truncdfsf_mixed"
4498 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4500 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4501 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4502 "TARGET_MIX_SSE_I387"
4504 switch (which_alternative)
4507 return output_387_reg_move (insn, operands);
4509 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4515 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4516 (set_attr "unit" "*,*,i387,i387,i387")
4517 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4518 (set_attr "mode" "SF")])
4520 (define_insn "*truncdfsf_i387"
4521 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4523 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4524 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4527 switch (which_alternative)
4530 return output_387_reg_move (insn, operands);
4536 [(set_attr "type" "fmov,multi,multi,multi")
4537 (set_attr "unit" "*,i387,i387,i387")
4538 (set_attr "mode" "SF")])
4540 (define_insn "*truncdfsf2_i387_1"
4541 [(set (match_operand:SF 0 "memory_operand" "=m")
4543 (match_operand:DF 1 "register_operand" "f")))]
4545 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4546 && !TARGET_MIX_SSE_I387"
4547 "* return output_387_reg_move (insn, operands);"
4548 [(set_attr "type" "fmov")
4549 (set_attr "mode" "SF")])
4552 [(set (match_operand:SF 0 "register_operand" "")
4554 (match_operand:DF 1 "fp_register_operand" "")))
4555 (clobber (match_operand 2 "" ""))]
4557 [(set (match_dup 2) (match_dup 1))
4558 (set (match_dup 0) (match_dup 2))]
4560 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4563 ;; Conversion from XFmode to {SF,DF}mode
4565 (define_expand "truncxf<mode>2"
4566 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4567 (float_truncate:MODEF
4568 (match_operand:XF 1 "register_operand" "")))
4569 (clobber (match_dup 2))])]
4572 if (flag_unsafe_math_optimizations)
4574 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4575 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4576 if (reg != operands[0])
4577 emit_move_insn (operands[0], reg);
4582 enum ix86_stack_slot slot = (virtuals_instantiated
4585 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4589 (define_insn "*truncxfsf2_mixed"
4590 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4592 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4593 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4596 gcc_assert (!which_alternative);
4597 return output_387_reg_move (insn, operands);
4599 [(set_attr "type" "fmov,multi,multi,multi")
4600 (set_attr "unit" "*,i387,i387,i387")
4601 (set_attr "mode" "SF")])
4603 (define_insn "*truncxfdf2_mixed"
4604 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4606 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4607 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4610 gcc_assert (!which_alternative);
4611 return output_387_reg_move (insn, operands);
4613 [(set_attr "type" "fmov,multi,multi,multi")
4614 (set_attr "unit" "*,i387,i387,i387")
4615 (set_attr "mode" "DF")])
4617 (define_insn "truncxf<mode>2_i387_noop"
4618 [(set (match_operand:MODEF 0 "register_operand" "=f")
4619 (float_truncate:MODEF
4620 (match_operand:XF 1 "register_operand" "f")))]
4621 "TARGET_80387 && flag_unsafe_math_optimizations"
4622 "* return output_387_reg_move (insn, operands);"
4623 [(set_attr "type" "fmov")
4624 (set_attr "mode" "<MODE>")])
4626 (define_insn "*truncxf<mode>2_i387"
4627 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4628 (float_truncate:MODEF
4629 (match_operand:XF 1 "register_operand" "f")))]
4631 "* return output_387_reg_move (insn, operands);"
4632 [(set_attr "type" "fmov")
4633 (set_attr "mode" "<MODE>")])
4636 [(set (match_operand:MODEF 0 "register_operand" "")
4637 (float_truncate:MODEF
4638 (match_operand:XF 1 "register_operand" "")))
4639 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4640 "TARGET_80387 && reload_completed"
4641 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4642 (set (match_dup 0) (match_dup 2))]
4646 [(set (match_operand:MODEF 0 "memory_operand" "")
4647 (float_truncate:MODEF
4648 (match_operand:XF 1 "register_operand" "")))
4649 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4651 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4654 ;; Signed conversion to DImode.
4656 (define_expand "fix_truncxfdi2"
4657 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4658 (fix:DI (match_operand:XF 1 "register_operand" "")))
4659 (clobber (reg:CC FLAGS_REG))])]
4664 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4669 (define_expand "fix_trunc<mode>di2"
4670 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4671 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4672 (clobber (reg:CC FLAGS_REG))])]
4673 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4676 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4678 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4681 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4683 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4684 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4685 if (out != operands[0])
4686 emit_move_insn (operands[0], out);
4691 ;; Signed conversion to SImode.
4693 (define_expand "fix_truncxfsi2"
4694 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4695 (fix:SI (match_operand:XF 1 "register_operand" "")))
4696 (clobber (reg:CC FLAGS_REG))])]
4701 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4706 (define_expand "fix_trunc<mode>si2"
4707 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4708 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4709 (clobber (reg:CC FLAGS_REG))])]
4710 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4713 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4715 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4718 if (SSE_FLOAT_MODE_P (<MODE>mode))
4720 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4721 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4722 if (out != operands[0])
4723 emit_move_insn (operands[0], out);
4728 ;; Signed conversion to HImode.
4730 (define_expand "fix_trunc<mode>hi2"
4731 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4733 (clobber (reg:CC FLAGS_REG))])]
4735 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4739 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4744 ;; Unsigned conversion to SImode.
4746 (define_expand "fixuns_trunc<mode>si2"
4748 [(set (match_operand:SI 0 "register_operand" "")
4750 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4752 (clobber (match_scratch:<ssevecmode> 3 ""))
4753 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4754 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4756 enum machine_mode mode = <MODE>mode;
4757 enum machine_mode vecmode = <ssevecmode>mode;
4758 REAL_VALUE_TYPE TWO31r;
4761 if (optimize_insn_for_size_p ())
4764 real_ldexp (&TWO31r, &dconst1, 31);
4765 two31 = const_double_from_real_value (TWO31r, mode);
4766 two31 = ix86_build_const_vector (mode, true, two31);
4767 operands[2] = force_reg (vecmode, two31);
4770 (define_insn_and_split "*fixuns_trunc<mode>_1"
4771 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4773 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4774 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4775 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4776 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4777 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4778 && optimize_function_for_speed_p (cfun)"
4780 "&& reload_completed"
4783 ix86_split_convert_uns_si_sse (operands);
4787 ;; Unsigned conversion to HImode.
4788 ;; Without these patterns, we'll try the unsigned SI conversion which
4789 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4791 (define_expand "fixuns_trunc<mode>hi2"
4793 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4794 (set (match_operand:HI 0 "nonimmediate_operand" "")
4795 (subreg:HI (match_dup 2) 0))]
4796 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4797 "operands[2] = gen_reg_rtx (SImode);")
4799 ;; When SSE is available, it is always faster to use it!
4800 (define_insn "fix_trunc<mode>di_sse"
4801 [(set (match_operand:DI 0 "register_operand" "=r,r")
4802 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4803 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4804 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4805 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4806 [(set_attr "type" "sseicvt")
4807 (set_attr "prefix" "maybe_vex")
4808 (set_attr "mode" "<MODE>")
4809 (set_attr "athlon_decode" "double,vector")
4810 (set_attr "amdfam10_decode" "double,double")])
4812 (define_insn "fix_trunc<mode>si_sse"
4813 [(set (match_operand:SI 0 "register_operand" "=r,r")
4814 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4815 "SSE_FLOAT_MODE_P (<MODE>mode)
4816 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4817 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4818 [(set_attr "type" "sseicvt")
4819 (set_attr "prefix" "maybe_vex")
4820 (set_attr "mode" "<MODE>")
4821 (set_attr "athlon_decode" "double,vector")
4822 (set_attr "amdfam10_decode" "double,double")])
4824 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4826 [(set (match_operand:MODEF 0 "register_operand" "")
4827 (match_operand:MODEF 1 "memory_operand" ""))
4828 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4829 (fix:SSEMODEI24 (match_dup 0)))]
4830 "TARGET_SHORTEN_X87_SSE
4831 && peep2_reg_dead_p (2, operands[0])"
4832 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4835 ;; Avoid vector decoded forms of the instruction.
4837 [(match_scratch:DF 2 "Y2")
4838 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4839 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4840 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4841 [(set (match_dup 2) (match_dup 1))
4842 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4846 [(match_scratch:SF 2 "x")
4847 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4848 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4849 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4850 [(set (match_dup 2) (match_dup 1))
4851 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4854 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4855 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4856 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4857 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4859 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4860 && (TARGET_64BIT || <MODE>mode != DImode))
4862 && !(reload_completed || reload_in_progress)"
4867 if (memory_operand (operands[0], VOIDmode))
4868 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4871 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4872 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4878 [(set_attr "type" "fisttp")
4879 (set_attr "mode" "<MODE>")])
4881 (define_insn "fix_trunc<mode>_i387_fisttp"
4882 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4883 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4884 (clobber (match_scratch:XF 2 "=&1f"))]
4885 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4888 && (TARGET_64BIT || <MODE>mode != DImode))
4889 && TARGET_SSE_MATH)"
4890 "* return output_fix_trunc (insn, operands, 1);"
4891 [(set_attr "type" "fisttp")
4892 (set_attr "mode" "<MODE>")])
4894 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4895 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4896 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4897 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4898 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4899 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4901 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902 && (TARGET_64BIT || <MODE>mode != DImode))
4903 && TARGET_SSE_MATH)"
4905 [(set_attr "type" "fisttp")
4906 (set_attr "mode" "<MODE>")])
4909 [(set (match_operand:X87MODEI 0 "register_operand" "")
4910 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4911 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4912 (clobber (match_scratch 3 ""))]
4914 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4915 (clobber (match_dup 3))])
4916 (set (match_dup 0) (match_dup 2))]
4920 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4921 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4922 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4923 (clobber (match_scratch 3 ""))]
4925 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4926 (clobber (match_dup 3))])]
4929 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4930 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4931 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4932 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4933 ;; function in i386.c.
4934 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4935 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4936 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4937 (clobber (reg:CC FLAGS_REG))]
4938 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4940 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4941 && (TARGET_64BIT || <MODE>mode != DImode))
4942 && !(reload_completed || reload_in_progress)"
4947 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4949 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4950 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4951 if (memory_operand (operands[0], VOIDmode))
4952 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4953 operands[2], operands[3]));
4956 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4957 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4958 operands[2], operands[3],
4963 [(set_attr "type" "fistp")
4964 (set_attr "i387_cw" "trunc")
4965 (set_attr "mode" "<MODE>")])
4967 (define_insn "fix_truncdi_i387"
4968 [(set (match_operand:DI 0 "memory_operand" "=m")
4969 (fix:DI (match_operand 1 "register_operand" "f")))
4970 (use (match_operand:HI 2 "memory_operand" "m"))
4971 (use (match_operand:HI 3 "memory_operand" "m"))
4972 (clobber (match_scratch:XF 4 "=&1f"))]
4973 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4975 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4976 "* return output_fix_trunc (insn, operands, 0);"
4977 [(set_attr "type" "fistp")
4978 (set_attr "i387_cw" "trunc")
4979 (set_attr "mode" "DI")])
4981 (define_insn "fix_truncdi_i387_with_temp"
4982 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4983 (fix:DI (match_operand 1 "register_operand" "f,f")))
4984 (use (match_operand:HI 2 "memory_operand" "m,m"))
4985 (use (match_operand:HI 3 "memory_operand" "m,m"))
4986 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4987 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4988 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4992 [(set_attr "type" "fistp")
4993 (set_attr "i387_cw" "trunc")
4994 (set_attr "mode" "DI")])
4997 [(set (match_operand:DI 0 "register_operand" "")
4998 (fix:DI (match_operand 1 "register_operand" "")))
4999 (use (match_operand:HI 2 "memory_operand" ""))
5000 (use (match_operand:HI 3 "memory_operand" ""))
5001 (clobber (match_operand:DI 4 "memory_operand" ""))
5002 (clobber (match_scratch 5 ""))]
5004 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5007 (clobber (match_dup 5))])
5008 (set (match_dup 0) (match_dup 4))]
5012 [(set (match_operand:DI 0 "memory_operand" "")
5013 (fix:DI (match_operand 1 "register_operand" "")))
5014 (use (match_operand:HI 2 "memory_operand" ""))
5015 (use (match_operand:HI 3 "memory_operand" ""))
5016 (clobber (match_operand:DI 4 "memory_operand" ""))
5017 (clobber (match_scratch 5 ""))]
5019 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5022 (clobber (match_dup 5))])]
5025 (define_insn "fix_trunc<mode>_i387"
5026 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5027 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5028 (use (match_operand:HI 2 "memory_operand" "m"))
5029 (use (match_operand:HI 3 "memory_operand" "m"))]
5030 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5032 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5033 "* return output_fix_trunc (insn, operands, 0);"
5034 [(set_attr "type" "fistp")
5035 (set_attr "i387_cw" "trunc")
5036 (set_attr "mode" "<MODE>")])
5038 (define_insn "fix_trunc<mode>_i387_with_temp"
5039 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5040 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5041 (use (match_operand:HI 2 "memory_operand" "m,m"))
5042 (use (match_operand:HI 3 "memory_operand" "m,m"))
5043 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5044 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5046 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5048 [(set_attr "type" "fistp")
5049 (set_attr "i387_cw" "trunc")
5050 (set_attr "mode" "<MODE>")])
5053 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5054 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5055 (use (match_operand:HI 2 "memory_operand" ""))
5056 (use (match_operand:HI 3 "memory_operand" ""))
5057 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5059 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5061 (use (match_dup 3))])
5062 (set (match_dup 0) (match_dup 4))]
5066 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5067 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5068 (use (match_operand:HI 2 "memory_operand" ""))
5069 (use (match_operand:HI 3 "memory_operand" ""))
5070 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5072 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5074 (use (match_dup 3))])]
5077 (define_insn "x86_fnstcw_1"
5078 [(set (match_operand:HI 0 "memory_operand" "=m")
5079 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5082 [(set_attr "length" "2")
5083 (set_attr "mode" "HI")
5084 (set_attr "unit" "i387")])
5086 (define_insn "x86_fldcw_1"
5087 [(set (reg:HI FPCR_REG)
5088 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5091 [(set_attr "length" "2")
5092 (set_attr "mode" "HI")
5093 (set_attr "unit" "i387")
5094 (set_attr "athlon_decode" "vector")
5095 (set_attr "amdfam10_decode" "vector")])
5097 ;; Conversion between fixed point and floating point.
5099 ;; Even though we only accept memory inputs, the backend _really_
5100 ;; wants to be able to do this between registers.
5102 (define_expand "floathi<mode>2"
5103 [(set (match_operand:X87MODEF 0 "register_operand" "")
5104 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5107 || TARGET_MIX_SSE_I387)"
5110 ;; Pre-reload splitter to add memory clobber to the pattern.
5111 (define_insn_and_split "*floathi<mode>2_1"
5112 [(set (match_operand:X87MODEF 0 "register_operand" "")
5113 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116 || TARGET_MIX_SSE_I387)
5117 && !(reload_completed || reload_in_progress)"
5120 [(parallel [(set (match_dup 0)
5121 (float:X87MODEF (match_dup 1)))
5122 (clobber (match_dup 2))])]
5123 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5125 (define_insn "*floathi<mode>2_i387_with_temp"
5126 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5127 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5128 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5131 || TARGET_MIX_SSE_I387)"
5133 [(set_attr "type" "fmov,multi")
5134 (set_attr "mode" "<MODE>")
5135 (set_attr "unit" "*,i387")
5136 (set_attr "fp_int_src" "true")])
5138 (define_insn "*floathi<mode>2_i387"
5139 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5140 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5143 || TARGET_MIX_SSE_I387)"
5145 [(set_attr "type" "fmov")
5146 (set_attr "mode" "<MODE>")
5147 (set_attr "fp_int_src" "true")])
5150 [(set (match_operand:X87MODEF 0 "register_operand" "")
5151 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5152 (clobber (match_operand:HI 2 "memory_operand" ""))]
5154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5155 || TARGET_MIX_SSE_I387)
5156 && reload_completed"
5157 [(set (match_dup 2) (match_dup 1))
5158 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5162 [(set (match_operand:X87MODEF 0 "register_operand" "")
5163 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5164 (clobber (match_operand:HI 2 "memory_operand" ""))]
5166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5167 || TARGET_MIX_SSE_I387)
5168 && reload_completed"
5169 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5172 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5173 [(set (match_operand:X87MODEF 0 "register_operand" "")
5175 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5177 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5181 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5182 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5183 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5185 rtx reg = gen_reg_rtx (XFmode);
5186 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5187 /* Avoid references to nonexistent function in dead code in XFmode case. */
5188 #define gen_truncxfxf2 gen_truncxfdf2
5189 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5190 #undef gen_truncxfxf2
5195 ;; Pre-reload splitter to add memory clobber to the pattern.
5196 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5197 [(set (match_operand:X87MODEF 0 "register_operand" "")
5198 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5201 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5203 || TARGET_MIX_SSE_I387))
5204 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5205 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5206 && ((<SSEMODEI24:MODE>mode == SImode
5207 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5208 && optimize_function_for_speed_p (cfun)
5209 && flag_trapping_math)
5210 || !(TARGET_INTER_UNIT_CONVERSIONS
5211 || optimize_function_for_size_p (cfun)))))
5212 && !(reload_completed || reload_in_progress)"
5215 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5216 (clobber (match_dup 2))])]
5218 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5220 /* Avoid store forwarding (partial memory) stall penalty
5221 by passing DImode value through XMM registers. */
5222 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5223 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5224 && optimize_function_for_speed_p (cfun))
5226 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5233 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5234 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5236 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5237 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5238 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5239 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5241 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5242 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5243 (set_attr "unit" "*,i387,*,*,*")
5244 (set_attr "athlon_decode" "*,*,double,direct,double")
5245 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5246 (set_attr "fp_int_src" "true")])
5248 (define_insn "*floatsi<mode>2_vector_mixed"
5249 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5250 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5251 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5252 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5256 [(set_attr "type" "fmov,sseicvt")
5257 (set_attr "mode" "<MODE>,<ssevecmode>")
5258 (set_attr "unit" "i387,*")
5259 (set_attr "athlon_decode" "*,direct")
5260 (set_attr "amdfam10_decode" "*,double")
5261 (set_attr "fp_int_src" "true")])
5263 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5264 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5266 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5267 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5268 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5269 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5271 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5272 (set_attr "mode" "<MODEF:MODE>")
5273 (set_attr "unit" "*,i387,*,*")
5274 (set_attr "athlon_decode" "*,*,double,direct")
5275 (set_attr "amdfam10_decode" "*,*,vector,double")
5276 (set_attr "fp_int_src" "true")])
5279 [(set (match_operand:MODEF 0 "register_operand" "")
5280 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5281 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5282 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5283 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5284 && TARGET_INTER_UNIT_CONVERSIONS
5286 && (SSE_REG_P (operands[0])
5287 || (GET_CODE (operands[0]) == SUBREG
5288 && SSE_REG_P (operands[0])))"
5289 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5293 [(set (match_operand:MODEF 0 "register_operand" "")
5294 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5295 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5296 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5298 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5300 && (SSE_REG_P (operands[0])
5301 || (GET_CODE (operands[0]) == SUBREG
5302 && SSE_REG_P (operands[0])))"
5303 [(set (match_dup 2) (match_dup 1))
5304 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5307 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5308 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5310 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5311 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5312 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5313 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5316 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5317 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5318 [(set_attr "type" "fmov,sseicvt,sseicvt")
5319 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5320 (set_attr "mode" "<MODEF:MODE>")
5321 (set_attr "unit" "i387,*,*")
5322 (set_attr "athlon_decode" "*,double,direct")
5323 (set_attr "amdfam10_decode" "*,vector,double")
5324 (set_attr "fp_int_src" "true")])
5326 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5327 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5329 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5330 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5331 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5332 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5335 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5336 [(set_attr "type" "fmov,sseicvt")
5337 (set_attr "prefix" "orig,maybe_vex")
5338 (set_attr "mode" "<MODEF:MODE>")
5339 (set_attr "athlon_decode" "*,direct")
5340 (set_attr "amdfam10_decode" "*,double")
5341 (set_attr "fp_int_src" "true")])
5343 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5344 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5346 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5347 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5348 "TARGET_SSE2 && TARGET_SSE_MATH
5349 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5351 [(set_attr "type" "sseicvt")
5352 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5353 (set_attr "athlon_decode" "double,direct,double")
5354 (set_attr "amdfam10_decode" "vector,double,double")
5355 (set_attr "fp_int_src" "true")])
5357 (define_insn "*floatsi<mode>2_vector_sse"
5358 [(set (match_operand:MODEF 0 "register_operand" "=x")
5359 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5360 "TARGET_SSE2 && TARGET_SSE_MATH
5361 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5363 [(set_attr "type" "sseicvt")
5364 (set_attr "mode" "<MODE>")
5365 (set_attr "athlon_decode" "direct")
5366 (set_attr "amdfam10_decode" "double")
5367 (set_attr "fp_int_src" "true")])
5370 [(set (match_operand:MODEF 0 "register_operand" "")
5371 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5372 (clobber (match_operand:SI 2 "memory_operand" ""))]
5373 "TARGET_SSE2 && TARGET_SSE_MATH
5374 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5376 && (SSE_REG_P (operands[0])
5377 || (GET_CODE (operands[0]) == SUBREG
5378 && SSE_REG_P (operands[0])))"
5381 rtx op1 = operands[1];
5383 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5385 if (GET_CODE (op1) == SUBREG)
5386 op1 = SUBREG_REG (op1);
5388 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5390 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5391 emit_insn (gen_sse2_loadld (operands[4],
5392 CONST0_RTX (V4SImode), operands[1]));
5394 /* We can ignore possible trapping value in the
5395 high part of SSE register for non-trapping math. */
5396 else if (SSE_REG_P (op1) && !flag_trapping_math)
5397 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5400 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5401 emit_move_insn (operands[2], operands[1]);
5402 emit_insn (gen_sse2_loadld (operands[4],
5403 CONST0_RTX (V4SImode), operands[2]));
5406 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5411 [(set (match_operand:MODEF 0 "register_operand" "")
5412 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5413 (clobber (match_operand:SI 2 "memory_operand" ""))]
5414 "TARGET_SSE2 && TARGET_SSE_MATH
5415 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5417 && (SSE_REG_P (operands[0])
5418 || (GET_CODE (operands[0]) == SUBREG
5419 && SSE_REG_P (operands[0])))"
5422 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5424 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5426 emit_insn (gen_sse2_loadld (operands[4],
5427 CONST0_RTX (V4SImode), operands[1]));
5429 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5434 [(set (match_operand:MODEF 0 "register_operand" "")
5435 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5436 "TARGET_SSE2 && TARGET_SSE_MATH
5437 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5439 && (SSE_REG_P (operands[0])
5440 || (GET_CODE (operands[0]) == SUBREG
5441 && SSE_REG_P (operands[0])))"
5444 rtx op1 = operands[1];
5446 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5448 if (GET_CODE (op1) == SUBREG)
5449 op1 = SUBREG_REG (op1);
5451 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5453 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5454 emit_insn (gen_sse2_loadld (operands[4],
5455 CONST0_RTX (V4SImode), operands[1]));
5457 /* We can ignore possible trapping value in the
5458 high part of SSE register for non-trapping math. */
5459 else if (SSE_REG_P (op1) && !flag_trapping_math)
5460 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5464 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5469 [(set (match_operand:MODEF 0 "register_operand" "")
5470 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5471 "TARGET_SSE2 && TARGET_SSE_MATH
5472 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5474 && (SSE_REG_P (operands[0])
5475 || (GET_CODE (operands[0]) == SUBREG
5476 && SSE_REG_P (operands[0])))"
5479 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5481 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5483 emit_insn (gen_sse2_loadld (operands[4],
5484 CONST0_RTX (V4SImode), operands[1]));
5486 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5490 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5491 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5493 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5494 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5495 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5496 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5498 [(set_attr "type" "sseicvt")
5499 (set_attr "mode" "<MODEF:MODE>")
5500 (set_attr "athlon_decode" "double,direct")
5501 (set_attr "amdfam10_decode" "vector,double")
5502 (set_attr "fp_int_src" "true")])
5504 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5505 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5507 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5508 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5509 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5510 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5511 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5512 [(set_attr "type" "sseicvt")
5513 (set_attr "prefix" "maybe_vex")
5514 (set_attr "mode" "<MODEF:MODE>")
5515 (set_attr "athlon_decode" "double,direct")
5516 (set_attr "amdfam10_decode" "vector,double")
5517 (set_attr "fp_int_src" "true")])
5520 [(set (match_operand:MODEF 0 "register_operand" "")
5521 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5522 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5523 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5524 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5525 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5527 && (SSE_REG_P (operands[0])
5528 || (GET_CODE (operands[0]) == SUBREG
5529 && SSE_REG_P (operands[0])))"
5530 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5533 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5534 [(set (match_operand:MODEF 0 "register_operand" "=x")
5536 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5537 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5538 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5539 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5540 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5541 [(set_attr "type" "sseicvt")
5542 (set_attr "prefix" "maybe_vex")
5543 (set_attr "mode" "<MODEF:MODE>")
5544 (set_attr "athlon_decode" "direct")
5545 (set_attr "amdfam10_decode" "double")
5546 (set_attr "fp_int_src" "true")])
5549 [(set (match_operand:MODEF 0 "register_operand" "")
5550 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5551 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5552 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5553 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5554 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5556 && (SSE_REG_P (operands[0])
5557 || (GET_CODE (operands[0]) == SUBREG
5558 && SSE_REG_P (operands[0])))"
5559 [(set (match_dup 2) (match_dup 1))
5560 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5564 [(set (match_operand:MODEF 0 "register_operand" "")
5565 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5566 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5567 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5568 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5570 && (SSE_REG_P (operands[0])
5571 || (GET_CODE (operands[0]) == SUBREG
5572 && SSE_REG_P (operands[0])))"
5573 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5576 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5577 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5579 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5580 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5582 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5586 [(set_attr "type" "fmov,multi")
5587 (set_attr "mode" "<X87MODEF:MODE>")
5588 (set_attr "unit" "*,i387")
5589 (set_attr "fp_int_src" "true")])
5591 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5592 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5594 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5596 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5598 [(set_attr "type" "fmov")
5599 (set_attr "mode" "<X87MODEF:MODE>")
5600 (set_attr "fp_int_src" "true")])
5603 [(set (match_operand:X87MODEF 0 "register_operand" "")
5604 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5605 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5607 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5609 && FP_REG_P (operands[0])"
5610 [(set (match_dup 2) (match_dup 1))
5611 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5615 [(set (match_operand:X87MODEF 0 "register_operand" "")
5616 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5617 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5619 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5621 && FP_REG_P (operands[0])"
5622 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5625 ;; Avoid store forwarding (partial memory) stall penalty
5626 ;; by passing DImode value through XMM registers. */
5628 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5629 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5631 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5632 (clobber (match_scratch:V4SI 3 "=X,x"))
5633 (clobber (match_scratch:V4SI 4 "=X,x"))
5634 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5635 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5636 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5637 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5639 [(set_attr "type" "multi")
5640 (set_attr "mode" "<X87MODEF:MODE>")
5641 (set_attr "unit" "i387")
5642 (set_attr "fp_int_src" "true")])
5645 [(set (match_operand:X87MODEF 0 "register_operand" "")
5646 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5647 (clobber (match_scratch:V4SI 3 ""))
5648 (clobber (match_scratch:V4SI 4 ""))
5649 (clobber (match_operand:DI 2 "memory_operand" ""))]
5650 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5651 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5652 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5654 && FP_REG_P (operands[0])"
5655 [(set (match_dup 2) (match_dup 3))
5656 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5658 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5659 Assemble the 64-bit DImode value in an xmm register. */
5660 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5661 gen_rtx_SUBREG (SImode, operands[1], 0)));
5662 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5663 gen_rtx_SUBREG (SImode, operands[1], 4)));
5664 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5666 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5670 [(set (match_operand:X87MODEF 0 "register_operand" "")
5671 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5672 (clobber (match_scratch:V4SI 3 ""))
5673 (clobber (match_scratch:V4SI 4 ""))
5674 (clobber (match_operand:DI 2 "memory_operand" ""))]
5675 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5676 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5677 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5679 && FP_REG_P (operands[0])"
5680 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5683 ;; Avoid store forwarding (partial memory) stall penalty by extending
5684 ;; SImode value to DImode through XMM register instead of pushing two
5685 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5686 ;; targets benefit from this optimization. Also note that fild
5687 ;; loads from memory only.
5689 (define_insn "*floatunssi<mode>2_1"
5690 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5691 (unsigned_float:X87MODEF
5692 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5693 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5694 (clobber (match_scratch:SI 3 "=X,x"))]
5696 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5699 [(set_attr "type" "multi")
5700 (set_attr "mode" "<MODE>")])
5703 [(set (match_operand:X87MODEF 0 "register_operand" "")
5704 (unsigned_float:X87MODEF
5705 (match_operand:SI 1 "register_operand" "")))
5706 (clobber (match_operand:DI 2 "memory_operand" ""))
5707 (clobber (match_scratch:SI 3 ""))]
5709 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5711 && reload_completed"
5712 [(set (match_dup 2) (match_dup 1))
5714 (float:X87MODEF (match_dup 2)))]
5715 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5718 [(set (match_operand:X87MODEF 0 "register_operand" "")
5719 (unsigned_float:X87MODEF
5720 (match_operand:SI 1 "memory_operand" "")))
5721 (clobber (match_operand:DI 2 "memory_operand" ""))
5722 (clobber (match_scratch:SI 3 ""))]
5724 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5726 && reload_completed"
5727 [(set (match_dup 2) (match_dup 3))
5729 (float:X87MODEF (match_dup 2)))]
5731 emit_move_insn (operands[3], operands[1]);
5732 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5735 (define_expand "floatunssi<mode>2"
5737 [(set (match_operand:X87MODEF 0 "register_operand" "")
5738 (unsigned_float:X87MODEF
5739 (match_operand:SI 1 "nonimmediate_operand" "")))
5740 (clobber (match_dup 2))
5741 (clobber (match_scratch:SI 3 ""))])]
5743 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5745 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5747 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5749 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5754 enum ix86_stack_slot slot = (virtuals_instantiated
5757 operands[2] = assign_386_stack_local (DImode, slot);
5761 (define_expand "floatunsdisf2"
5762 [(use (match_operand:SF 0 "register_operand" ""))
5763 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5764 "TARGET_64BIT && TARGET_SSE_MATH"
5765 "x86_emit_floatuns (operands); DONE;")
5767 (define_expand "floatunsdidf2"
5768 [(use (match_operand:DF 0 "register_operand" ""))
5769 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5770 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5771 && TARGET_SSE2 && TARGET_SSE_MATH"
5774 x86_emit_floatuns (operands);
5776 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5782 ;; %%% splits for addditi3
5784 (define_expand "addti3"
5785 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5786 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5787 (match_operand:TI 2 "x86_64_general_operand" "")))]
5789 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5791 (define_insn "*addti3_1"
5792 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5793 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5794 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5795 (clobber (reg:CC FLAGS_REG))]
5796 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5800 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5801 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5802 (match_operand:TI 2 "x86_64_general_operand" "")))
5803 (clobber (reg:CC FLAGS_REG))]
5804 "TARGET_64BIT && reload_completed"
5805 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5807 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5808 (parallel [(set (match_dup 3)
5809 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5812 (clobber (reg:CC FLAGS_REG))])]
5813 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5815 ;; %%% splits for addsidi3
5816 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5817 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5818 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5820 (define_expand "adddi3"
5821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5822 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5823 (match_operand:DI 2 "x86_64_general_operand" "")))]
5825 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5827 (define_insn "*adddi3_1"
5828 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5829 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5830 (match_operand:DI 2 "general_operand" "roiF,riF")))
5831 (clobber (reg:CC FLAGS_REG))]
5832 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5837 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5838 (match_operand:DI 2 "general_operand" "")))
5839 (clobber (reg:CC FLAGS_REG))]
5840 "!TARGET_64BIT && reload_completed"
5841 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5843 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5844 (parallel [(set (match_dup 3)
5845 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5848 (clobber (reg:CC FLAGS_REG))])]
5849 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5851 (define_insn "adddi3_carry_rex64"
5852 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5853 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5854 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5855 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5856 (clobber (reg:CC FLAGS_REG))]
5857 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5858 "adc{q}\t{%2, %0|%0, %2}"
5859 [(set_attr "type" "alu")
5860 (set_attr "use_carry" "1")
5861 (set_attr "pent_pair" "pu")
5862 (set_attr "mode" "DI")])
5864 (define_insn "*adddi3_cc_rex64"
5865 [(set (reg:CC FLAGS_REG)
5866 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5869 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5870 (plus:DI (match_dup 1) (match_dup 2)))]
5871 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5872 "add{q}\t{%2, %0|%0, %2}"
5873 [(set_attr "type" "alu")
5874 (set_attr "mode" "DI")])
5876 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5877 [(set (reg:CCC FLAGS_REG)
5880 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5881 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5883 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5884 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5885 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5886 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5887 [(set_attr "type" "alu")
5888 (set_attr "mode" "<MODE>")])
5890 (define_insn "*add<mode>3_cconly_overflow"
5891 [(set (reg:CCC FLAGS_REG)
5893 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5894 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5896 (clobber (match_scratch:SWI 0 "=<r>"))]
5897 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5898 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5899 [(set_attr "type" "alu")
5900 (set_attr "mode" "<MODE>")])
5902 (define_insn "*sub<mode>3_cconly_overflow"
5903 [(set (reg:CCC FLAGS_REG)
5905 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5906 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5909 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5910 [(set_attr "type" "icmp")
5911 (set_attr "mode" "<MODE>")])
5913 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5914 [(set (reg:CCC FLAGS_REG)
5916 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5917 (match_operand:SI 2 "general_operand" "g"))
5919 (set (match_operand:DI 0 "register_operand" "=r")
5920 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5921 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5922 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5923 [(set_attr "type" "alu")
5924 (set_attr "mode" "SI")])
5926 (define_insn "addqi3_carry"
5927 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5928 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5929 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5930 (match_operand:QI 2 "general_operand" "qn,qm")))
5931 (clobber (reg:CC FLAGS_REG))]
5932 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5933 "adc{b}\t{%2, %0|%0, %2}"
5934 [(set_attr "type" "alu")
5935 (set_attr "use_carry" "1")
5936 (set_attr "pent_pair" "pu")
5937 (set_attr "mode" "QI")])
5939 (define_insn "addhi3_carry"
5940 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5941 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5942 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5943 (match_operand:HI 2 "general_operand" "rn,rm")))
5944 (clobber (reg:CC FLAGS_REG))]
5945 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5946 "adc{w}\t{%2, %0|%0, %2}"
5947 [(set_attr "type" "alu")
5948 (set_attr "use_carry" "1")
5949 (set_attr "pent_pair" "pu")
5950 (set_attr "mode" "HI")])
5952 (define_insn "addsi3_carry"
5953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5954 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5955 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5956 (match_operand:SI 2 "general_operand" "ri,rm")))
5957 (clobber (reg:CC FLAGS_REG))]
5958 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5959 "adc{l}\t{%2, %0|%0, %2}"
5960 [(set_attr "type" "alu")
5961 (set_attr "use_carry" "1")
5962 (set_attr "pent_pair" "pu")
5963 (set_attr "mode" "SI")])
5965 (define_insn "*addsi3_carry_zext"
5966 [(set (match_operand:DI 0 "register_operand" "=r")
5968 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5969 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5970 (match_operand:SI 2 "general_operand" "g"))))
5971 (clobber (reg:CC FLAGS_REG))]
5972 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 "adc{l}\t{%2, %k0|%k0, %2}"
5974 [(set_attr "type" "alu")
5975 (set_attr "use_carry" "1")
5976 (set_attr "pent_pair" "pu")
5977 (set_attr "mode" "SI")])
5979 (define_insn "*addsi3_cc"
5980 [(set (reg:CC FLAGS_REG)
5981 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5982 (match_operand:SI 2 "general_operand" "ri,rm")]
5984 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5985 (plus:SI (match_dup 1) (match_dup 2)))]
5986 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5987 "add{l}\t{%2, %0|%0, %2}"
5988 [(set_attr "type" "alu")
5989 (set_attr "mode" "SI")])
5991 (define_insn "addqi3_cc"
5992 [(set (reg:CC FLAGS_REG)
5993 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5994 (match_operand:QI 2 "general_operand" "qn,qm")]
5996 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5997 (plus:QI (match_dup 1) (match_dup 2)))]
5998 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5999 "add{b}\t{%2, %0|%0, %2}"
6000 [(set_attr "type" "alu")
6001 (set_attr "mode" "QI")])
6003 (define_expand "addsi3"
6004 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6005 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6006 (match_operand:SI 2 "general_operand" "")))]
6008 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6010 (define_insn "*lea_1"
6011 [(set (match_operand:SI 0 "register_operand" "=r")
6012 (match_operand:SI 1 "no_seg_address_operand" "p"))]
6014 "lea{l}\t{%a1, %0|%0, %a1}"
6015 [(set_attr "type" "lea")
6016 (set_attr "mode" "SI")])
6018 (define_insn "*lea_1_rex64"
6019 [(set (match_operand:SI 0 "register_operand" "=r")
6020 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6022 "lea{l}\t{%a1, %0|%0, %a1}"
6023 [(set_attr "type" "lea")
6024 (set_attr "mode" "SI")])
6026 (define_insn "*lea_1_zext"
6027 [(set (match_operand:DI 0 "register_operand" "=r")
6029 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6031 "lea{l}\t{%a1, %k0|%k0, %a1}"
6032 [(set_attr "type" "lea")
6033 (set_attr "mode" "SI")])
6035 (define_insn "*lea_2_rex64"
6036 [(set (match_operand:DI 0 "register_operand" "=r")
6037 (match_operand:DI 1 "no_seg_address_operand" "p"))]
6039 "lea{q}\t{%a1, %0|%0, %a1}"
6040 [(set_attr "type" "lea")
6041 (set_attr "mode" "DI")])
6043 ;; The lea patterns for non-Pmodes needs to be matched by several
6044 ;; insns converted to real lea by splitters.
6046 (define_insn_and_split "*lea_general_1"
6047 [(set (match_operand 0 "register_operand" "=r")
6048 (plus (plus (match_operand 1 "index_register_operand" "l")
6049 (match_operand 2 "register_operand" "r"))
6050 (match_operand 3 "immediate_operand" "i")))]
6051 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6052 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6053 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6055 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6056 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6057 || GET_MODE (operands[3]) == VOIDmode)"
6059 "&& reload_completed"
6063 operands[0] = gen_lowpart (SImode, operands[0]);
6064 operands[1] = gen_lowpart (Pmode, operands[1]);
6065 operands[2] = gen_lowpart (Pmode, operands[2]);
6066 operands[3] = gen_lowpart (Pmode, operands[3]);
6067 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6069 if (Pmode != SImode)
6070 pat = gen_rtx_SUBREG (SImode, pat, 0);
6071 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6074 [(set_attr "type" "lea")
6075 (set_attr "mode" "SI")])
6077 (define_insn_and_split "*lea_general_1_zext"
6078 [(set (match_operand:DI 0 "register_operand" "=r")
6080 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6081 (match_operand:SI 2 "register_operand" "r"))
6082 (match_operand:SI 3 "immediate_operand" "i"))))]
6085 "&& reload_completed"
6087 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6089 (match_dup 3)) 0)))]
6091 operands[1] = gen_lowpart (Pmode, operands[1]);
6092 operands[2] = gen_lowpart (Pmode, operands[2]);
6093 operands[3] = gen_lowpart (Pmode, operands[3]);
6095 [(set_attr "type" "lea")
6096 (set_attr "mode" "SI")])
6098 (define_insn_and_split "*lea_general_2"
6099 [(set (match_operand 0 "register_operand" "=r")
6100 (plus (mult (match_operand 1 "index_register_operand" "l")
6101 (match_operand 2 "const248_operand" "i"))
6102 (match_operand 3 "nonmemory_operand" "ri")))]
6103 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6104 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6105 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6106 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6107 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6108 || GET_MODE (operands[3]) == VOIDmode)"
6110 "&& reload_completed"
6114 operands[0] = gen_lowpart (SImode, operands[0]);
6115 operands[1] = gen_lowpart (Pmode, operands[1]);
6116 operands[3] = gen_lowpart (Pmode, operands[3]);
6117 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6119 if (Pmode != SImode)
6120 pat = gen_rtx_SUBREG (SImode, pat, 0);
6121 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6124 [(set_attr "type" "lea")
6125 (set_attr "mode" "SI")])
6127 (define_insn_and_split "*lea_general_2_zext"
6128 [(set (match_operand:DI 0 "register_operand" "=r")
6130 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6131 (match_operand:SI 2 "const248_operand" "n"))
6132 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6135 "&& reload_completed"
6137 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6139 (match_dup 3)) 0)))]
6141 operands[1] = gen_lowpart (Pmode, operands[1]);
6142 operands[3] = gen_lowpart (Pmode, operands[3]);
6144 [(set_attr "type" "lea")
6145 (set_attr "mode" "SI")])
6147 (define_insn_and_split "*lea_general_3"
6148 [(set (match_operand 0 "register_operand" "=r")
6149 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6150 (match_operand 2 "const248_operand" "i"))
6151 (match_operand 3 "register_operand" "r"))
6152 (match_operand 4 "immediate_operand" "i")))]
6153 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6154 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6155 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6156 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6157 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6159 "&& reload_completed"
6163 operands[0] = gen_lowpart (SImode, operands[0]);
6164 operands[1] = gen_lowpart (Pmode, operands[1]);
6165 operands[3] = gen_lowpart (Pmode, operands[3]);
6166 operands[4] = gen_lowpart (Pmode, operands[4]);
6167 pat = gen_rtx_PLUS (Pmode,
6168 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6172 if (Pmode != SImode)
6173 pat = gen_rtx_SUBREG (SImode, pat, 0);
6174 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6177 [(set_attr "type" "lea")
6178 (set_attr "mode" "SI")])
6180 (define_insn_and_split "*lea_general_3_zext"
6181 [(set (match_operand:DI 0 "register_operand" "=r")
6183 (plus:SI (plus:SI (mult:SI
6184 (match_operand:SI 1 "index_register_operand" "l")
6185 (match_operand:SI 2 "const248_operand" "n"))
6186 (match_operand:SI 3 "register_operand" "r"))
6187 (match_operand:SI 4 "immediate_operand" "i"))))]
6190 "&& reload_completed"
6192 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6195 (match_dup 4)) 0)))]
6197 operands[1] = gen_lowpart (Pmode, operands[1]);
6198 operands[3] = gen_lowpart (Pmode, operands[3]);
6199 operands[4] = gen_lowpart (Pmode, operands[4]);
6201 [(set_attr "type" "lea")
6202 (set_attr "mode" "SI")])
6204 (define_insn "*adddi_1_rex64"
6205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6206 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6207 (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6208 (clobber (reg:CC FLAGS_REG))]
6209 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6211 switch (get_attr_type (insn))
6214 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6215 return "lea{q}\t{%a2, %0|%0, %a2}";
6218 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6219 if (operands[2] == const1_rtx)
6220 return "inc{q}\t%0";
6223 gcc_assert (operands[2] == constm1_rtx);
6224 return "dec{q}\t%0";
6228 /* Use add as much as possible to replace lea for AGU optimization. */
6229 if (which_alternative == 2 && TARGET_OPT_AGU)
6230 return "add{q}\t{%1, %0|%0, %1}";
6232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6235 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6236 if (CONST_INT_P (operands[2])
6237 /* Avoid overflows. */
6238 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6239 && (INTVAL (operands[2]) == 128
6240 || (INTVAL (operands[2]) < 0
6241 && INTVAL (operands[2]) != -128)))
6243 operands[2] = GEN_INT (-INTVAL (operands[2]));
6244 return "sub{q}\t{%2, %0|%0, %2}";
6246 return "add{q}\t{%2, %0|%0, %2}";
6250 (cond [(and (eq_attr "alternative" "2")
6251 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6252 (const_string "lea")
6253 (eq_attr "alternative" "3")
6254 (const_string "lea")
6255 ; Current assemblers are broken and do not allow @GOTOFF in
6256 ; ought but a memory context.
6257 (match_operand:DI 2 "pic_symbolic_operand" "")
6258 (const_string "lea")
6259 (match_operand:DI 2 "incdec_operand" "")
6260 (const_string "incdec")
6262 (const_string "alu")))
6263 (set_attr "mode" "DI")])
6265 ;; Convert lea to the lea pattern to avoid flags dependency.
6267 [(set (match_operand:DI 0 "register_operand" "")
6268 (plus:DI (match_operand:DI 1 "register_operand" "")
6269 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6270 (clobber (reg:CC FLAGS_REG))]
6271 "TARGET_64BIT && reload_completed
6272 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6274 (plus:DI (match_dup 1)
6278 (define_insn "*adddi_2_rex64"
6279 [(set (reg FLAGS_REG)
6281 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6282 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6284 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6285 (plus:DI (match_dup 1) (match_dup 2)))]
6286 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6287 && ix86_binary_operator_ok (PLUS, DImode, operands)
6288 /* Current assemblers are broken and do not allow @GOTOFF in
6289 ought but a memory context. */
6290 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6292 switch (get_attr_type (insn))
6295 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6296 if (operands[2] == const1_rtx)
6297 return "inc{q}\t%0";
6300 gcc_assert (operands[2] == constm1_rtx);
6301 return "dec{q}\t%0";
6305 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6306 /* ???? We ought to handle there the 32bit case too
6307 - do we need new constraint? */
6308 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6310 if (CONST_INT_P (operands[2])
6311 /* Avoid overflows. */
6312 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6313 && (INTVAL (operands[2]) == 128
6314 || (INTVAL (operands[2]) < 0
6315 && INTVAL (operands[2]) != -128)))
6317 operands[2] = GEN_INT (-INTVAL (operands[2]));
6318 return "sub{q}\t{%2, %0|%0, %2}";
6320 return "add{q}\t{%2, %0|%0, %2}";
6324 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6325 (const_string "incdec")
6326 (const_string "alu")))
6327 (set_attr "mode" "DI")])
6329 (define_insn "*adddi_3_rex64"
6330 [(set (reg FLAGS_REG)
6331 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6332 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6333 (clobber (match_scratch:DI 0 "=r"))]
6335 && ix86_match_ccmode (insn, CCZmode)
6336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6337 /* Current assemblers are broken and do not allow @GOTOFF in
6338 ought but a memory context. */
6339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6341 switch (get_attr_type (insn))
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 if (operands[2] == const1_rtx)
6346 return "inc{q}\t%0";
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{q}\t%0";
6354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355 /* ???? We ought to handle there the 32bit case too
6356 - do we need new constraint? */
6357 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6358 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6359 if (CONST_INT_P (operands[2])
6360 /* Avoid overflows. */
6361 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6362 && (INTVAL (operands[2]) == 128
6363 || (INTVAL (operands[2]) < 0
6364 && INTVAL (operands[2]) != -128)))
6366 operands[2] = GEN_INT (-INTVAL (operands[2]));
6367 return "sub{q}\t{%2, %0|%0, %2}";
6369 return "add{q}\t{%2, %0|%0, %2}";
6373 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6374 (const_string "incdec")
6375 (const_string "alu")))
6376 (set_attr "mode" "DI")])
6378 ; For comparisons against 1, -1 and 128, we may generate better code
6379 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6380 ; is matched then. We can't accept general immediate, because for
6381 ; case of overflows, the result is messed up.
6382 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6384 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6385 ; only for comparisons not depending on it.
6386 (define_insn "*adddi_4_rex64"
6387 [(set (reg FLAGS_REG)
6388 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6389 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6390 (clobber (match_scratch:DI 0 "=rm"))]
6392 && ix86_match_ccmode (insn, CCGCmode)"
6394 switch (get_attr_type (insn))
6397 if (operands[2] == constm1_rtx)
6398 return "inc{q}\t%0";
6401 gcc_assert (operands[2] == const1_rtx);
6402 return "dec{q}\t%0";
6406 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6407 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6409 if ((INTVAL (operands[2]) == -128
6410 || (INTVAL (operands[2]) > 0
6411 && INTVAL (operands[2]) != 128))
6412 /* Avoid overflows. */
6413 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6414 return "sub{q}\t{%2, %0|%0, %2}";
6415 operands[2] = GEN_INT (-INTVAL (operands[2]));
6416 return "add{q}\t{%2, %0|%0, %2}";
6420 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6421 (const_string "incdec")
6422 (const_string "alu")))
6423 (set_attr "mode" "DI")])
6425 (define_insn "*adddi_5_rex64"
6426 [(set (reg FLAGS_REG)
6428 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6429 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6431 (clobber (match_scratch:DI 0 "=r"))]
6433 && ix86_match_ccmode (insn, CCGOCmode)
6434 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6435 /* Current assemblers are broken and do not allow @GOTOFF in
6436 ought but a memory context. */
6437 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6439 switch (get_attr_type (insn))
6442 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6443 if (operands[2] == const1_rtx)
6444 return "inc{q}\t%0";
6447 gcc_assert (operands[2] == constm1_rtx);
6448 return "dec{q}\t%0";
6452 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6453 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6454 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6455 if (CONST_INT_P (operands[2])
6456 /* Avoid overflows. */
6457 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6458 && (INTVAL (operands[2]) == 128
6459 || (INTVAL (operands[2]) < 0
6460 && INTVAL (operands[2]) != -128)))
6462 operands[2] = GEN_INT (-INTVAL (operands[2]));
6463 return "sub{q}\t{%2, %0|%0, %2}";
6465 return "add{q}\t{%2, %0|%0, %2}";
6469 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6470 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "DI")])
6475 (define_insn "*addsi_1"
6476 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6477 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6478 (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6479 (clobber (reg:CC FLAGS_REG))]
6480 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6482 switch (get_attr_type (insn))
6485 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6486 return "lea{l}\t{%a2, %0|%0, %a2}";
6489 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6490 if (operands[2] == const1_rtx)
6491 return "inc{l}\t%0";
6494 gcc_assert (operands[2] == constm1_rtx);
6495 return "dec{l}\t%0";
6499 /* Use add as much as possible to replace lea for AGU optimization. */
6500 if (which_alternative == 2 && TARGET_OPT_AGU)
6501 return "add{l}\t{%1, %0|%0, %1}";
6503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6505 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6506 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6507 if (CONST_INT_P (operands[2])
6508 && (INTVAL (operands[2]) == 128
6509 || (INTVAL (operands[2]) < 0
6510 && INTVAL (operands[2]) != -128)))
6512 operands[2] = GEN_INT (-INTVAL (operands[2]));
6513 return "sub{l}\t{%2, %0|%0, %2}";
6515 return "add{l}\t{%2, %0|%0, %2}";
6519 (cond [(and (eq_attr "alternative" "2")
6520 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6521 (const_string "lea")
6522 (eq_attr "alternative" "3")
6523 (const_string "lea")
6524 ; Current assemblers are broken and do not allow @GOTOFF in
6525 ; ought but a memory context.
6526 (match_operand:SI 2 "pic_symbolic_operand" "")
6527 (const_string "lea")
6528 (match_operand:SI 2 "incdec_operand" "")
6529 (const_string "incdec")
6531 (const_string "alu")))
6532 (set_attr "mode" "SI")])
6534 ;; Convert lea to the lea pattern to avoid flags dependency.
6536 [(set (match_operand 0 "register_operand" "")
6537 (plus (match_operand 1 "register_operand" "")
6538 (match_operand 2 "nonmemory_operand" "")))
6539 (clobber (reg:CC FLAGS_REG))]
6540 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6544 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6545 may confuse gen_lowpart. */
6546 if (GET_MODE (operands[0]) != Pmode)
6548 operands[1] = gen_lowpart (Pmode, operands[1]);
6549 operands[2] = gen_lowpart (Pmode, operands[2]);
6551 operands[0] = gen_lowpart (SImode, operands[0]);
6552 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6553 if (Pmode != SImode)
6554 pat = gen_rtx_SUBREG (SImode, pat, 0);
6555 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6559 ;; It may seem that nonimmediate operand is proper one for operand 1.
6560 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6561 ;; we take care in ix86_binary_operator_ok to not allow two memory
6562 ;; operands so proper swapping will be done in reload. This allow
6563 ;; patterns constructed from addsi_1 to match.
6564 (define_insn "addsi_1_zext"
6565 [(set (match_operand:DI 0 "register_operand" "=r,r")
6567 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6568 (match_operand:SI 2 "general_operand" "g,li"))))
6569 (clobber (reg:CC FLAGS_REG))]
6570 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6572 switch (get_attr_type (insn))
6575 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6576 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6579 if (operands[2] == const1_rtx)
6580 return "inc{l}\t%k0";
6583 gcc_assert (operands[2] == constm1_rtx);
6584 return "dec{l}\t%k0";
6588 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6589 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6590 if (CONST_INT_P (operands[2])
6591 && (INTVAL (operands[2]) == 128
6592 || (INTVAL (operands[2]) < 0
6593 && INTVAL (operands[2]) != -128)))
6595 operands[2] = GEN_INT (-INTVAL (operands[2]));
6596 return "sub{l}\t{%2, %k0|%k0, %2}";
6598 return "add{l}\t{%2, %k0|%k0, %2}";
6602 (cond [(eq_attr "alternative" "1")
6603 (const_string "lea")
6604 ; Current assemblers are broken and do not allow @GOTOFF in
6605 ; ought but a memory context.
6606 (match_operand:SI 2 "pic_symbolic_operand" "")
6607 (const_string "lea")
6608 (match_operand:SI 2 "incdec_operand" "")
6609 (const_string "incdec")
6611 (const_string "alu")))
6612 (set_attr "mode" "SI")])
6614 ;; Convert lea to the lea pattern to avoid flags dependency.
6616 [(set (match_operand:DI 0 "register_operand" "")
6618 (plus:SI (match_operand:SI 1 "register_operand" "")
6619 (match_operand:SI 2 "nonmemory_operand" ""))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "TARGET_64BIT && reload_completed
6622 && true_regnum (operands[0]) != true_regnum (operands[1])"
6624 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6626 operands[1] = gen_lowpart (Pmode, operands[1]);
6627 operands[2] = gen_lowpart (Pmode, operands[2]);
6630 (define_insn "*addsi_2"
6631 [(set (reg FLAGS_REG)
6633 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6634 (match_operand:SI 2 "general_operand" "g,ri"))
6636 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6637 (plus:SI (match_dup 1) (match_dup 2)))]
6638 "ix86_match_ccmode (insn, CCGOCmode)
6639 && ix86_binary_operator_ok (PLUS, SImode, operands)
6640 /* Current assemblers are broken and do not allow @GOTOFF in
6641 ought but a memory context. */
6642 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6644 switch (get_attr_type (insn))
6647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648 if (operands[2] == const1_rtx)
6649 return "inc{l}\t%0";
6652 gcc_assert (operands[2] == constm1_rtx);
6653 return "dec{l}\t%0";
6657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6658 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6659 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6660 if (CONST_INT_P (operands[2])
6661 && (INTVAL (operands[2]) == 128
6662 || (INTVAL (operands[2]) < 0
6663 && INTVAL (operands[2]) != -128)))
6665 operands[2] = GEN_INT (-INTVAL (operands[2]));
6666 return "sub{l}\t{%2, %0|%0, %2}";
6668 return "add{l}\t{%2, %0|%0, %2}";
6672 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6673 (const_string "incdec")
6674 (const_string "alu")))
6675 (set_attr "mode" "SI")])
6677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6678 (define_insn "*addsi_2_zext"
6679 [(set (reg FLAGS_REG)
6681 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6682 (match_operand:SI 2 "general_operand" "g"))
6684 (set (match_operand:DI 0 "register_operand" "=r")
6685 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6686 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6687 && ix86_binary_operator_ok (PLUS, SImode, operands)
6688 /* Current assemblers are broken and do not allow @GOTOFF in
6689 ought but a memory context. */
6690 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6692 switch (get_attr_type (insn))
6695 if (operands[2] == const1_rtx)
6696 return "inc{l}\t%k0";
6699 gcc_assert (operands[2] == constm1_rtx);
6700 return "dec{l}\t%k0";
6704 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6705 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6706 if (CONST_INT_P (operands[2])
6707 && (INTVAL (operands[2]) == 128
6708 || (INTVAL (operands[2]) < 0
6709 && INTVAL (operands[2]) != -128)))
6711 operands[2] = GEN_INT (-INTVAL (operands[2]));
6712 return "sub{l}\t{%2, %k0|%k0, %2}";
6714 return "add{l}\t{%2, %k0|%k0, %2}";
6718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6719 (const_string "incdec")
6720 (const_string "alu")))
6721 (set_attr "mode" "SI")])
6723 (define_insn "*addsi_3"
6724 [(set (reg FLAGS_REG)
6725 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6726 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6727 (clobber (match_scratch:SI 0 "=r"))]
6728 "ix86_match_ccmode (insn, CCZmode)
6729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6730 /* Current assemblers are broken and do not allow @GOTOFF in
6731 ought but a memory context. */
6732 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6734 switch (get_attr_type (insn))
6737 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6738 if (operands[2] == const1_rtx)
6739 return "inc{l}\t%0";
6742 gcc_assert (operands[2] == constm1_rtx);
6743 return "dec{l}\t%0";
6747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6748 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6749 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6750 if (CONST_INT_P (operands[2])
6751 && (INTVAL (operands[2]) == 128
6752 || (INTVAL (operands[2]) < 0
6753 && INTVAL (operands[2]) != -128)))
6755 operands[2] = GEN_INT (-INTVAL (operands[2]));
6756 return "sub{l}\t{%2, %0|%0, %2}";
6758 return "add{l}\t{%2, %0|%0, %2}";
6762 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6763 (const_string "incdec")
6764 (const_string "alu")))
6765 (set_attr "mode" "SI")])
6767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6768 (define_insn "*addsi_3_zext"
6769 [(set (reg FLAGS_REG)
6770 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6771 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6772 (set (match_operand:DI 0 "register_operand" "=r")
6773 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6774 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6775 && ix86_binary_operator_ok (PLUS, SImode, operands)
6776 /* Current assemblers are broken and do not allow @GOTOFF in
6777 ought but a memory context. */
6778 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6780 switch (get_attr_type (insn))
6783 if (operands[2] == const1_rtx)
6784 return "inc{l}\t%k0";
6787 gcc_assert (operands[2] == constm1_rtx);
6788 return "dec{l}\t%k0";
6792 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6793 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6794 if (CONST_INT_P (operands[2])
6795 && (INTVAL (operands[2]) == 128
6796 || (INTVAL (operands[2]) < 0
6797 && INTVAL (operands[2]) != -128)))
6799 operands[2] = GEN_INT (-INTVAL (operands[2]));
6800 return "sub{l}\t{%2, %k0|%k0, %2}";
6802 return "add{l}\t{%2, %k0|%k0, %2}";
6806 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6807 (const_string "incdec")
6808 (const_string "alu")))
6809 (set_attr "mode" "SI")])
6811 ; For comparisons against 1, -1 and 128, we may generate better code
6812 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6813 ; is matched then. We can't accept general immediate, because for
6814 ; case of overflows, the result is messed up.
6815 ; This pattern also don't hold of 0x80000000, since the value overflows
6817 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6818 ; only for comparisons not depending on it.
6819 (define_insn "*addsi_4"
6820 [(set (reg FLAGS_REG)
6821 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6822 (match_operand:SI 2 "const_int_operand" "n")))
6823 (clobber (match_scratch:SI 0 "=rm"))]
6824 "ix86_match_ccmode (insn, CCGCmode)
6825 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6827 switch (get_attr_type (insn))
6830 if (operands[2] == constm1_rtx)
6831 return "inc{l}\t%0";
6834 gcc_assert (operands[2] == const1_rtx);
6835 return "dec{l}\t%0";
6839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6842 if ((INTVAL (operands[2]) == -128
6843 || (INTVAL (operands[2]) > 0
6844 && INTVAL (operands[2]) != 128)))
6845 return "sub{l}\t{%2, %0|%0, %2}";
6846 operands[2] = GEN_INT (-INTVAL (operands[2]));
6847 return "add{l}\t{%2, %0|%0, %2}";
6851 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6852 (const_string "incdec")
6853 (const_string "alu")))
6854 (set_attr "mode" "SI")])
6856 (define_insn "*addsi_5"
6857 [(set (reg FLAGS_REG)
6859 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6860 (match_operand:SI 2 "general_operand" "g"))
6862 (clobber (match_scratch:SI 0 "=r"))]
6863 "ix86_match_ccmode (insn, CCGOCmode)
6864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6865 /* Current assemblers are broken and do not allow @GOTOFF in
6866 ought but a memory context. */
6867 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6869 switch (get_attr_type (insn))
6872 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6873 if (operands[2] == const1_rtx)
6874 return "inc{l}\t%0";
6877 gcc_assert (operands[2] == constm1_rtx);
6878 return "dec{l}\t%0";
6882 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6883 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6884 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6885 if (CONST_INT_P (operands[2])
6886 && (INTVAL (operands[2]) == 128
6887 || (INTVAL (operands[2]) < 0
6888 && INTVAL (operands[2]) != -128)))
6890 operands[2] = GEN_INT (-INTVAL (operands[2]));
6891 return "sub{l}\t{%2, %0|%0, %2}";
6893 return "add{l}\t{%2, %0|%0, %2}";
6897 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6898 (const_string "incdec")
6899 (const_string "alu")))
6900 (set_attr "mode" "SI")])
6902 (define_expand "addhi3"
6903 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6904 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6905 (match_operand:HI 2 "general_operand" "")))]
6906 "TARGET_HIMODE_MATH"
6907 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6909 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6910 ;; type optimizations enabled by define-splits. This is not important
6911 ;; for PII, and in fact harmful because of partial register stalls.
6913 (define_insn "*addhi_1_lea"
6914 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6915 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6916 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6917 (clobber (reg:CC FLAGS_REG))]
6918 "!TARGET_PARTIAL_REG_STALL
6919 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6921 switch (get_attr_type (insn))
6926 if (operands[2] == const1_rtx)
6927 return "inc{w}\t%0";
6930 gcc_assert (operands[2] == constm1_rtx);
6931 return "dec{w}\t%0";
6935 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6936 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6937 if (CONST_INT_P (operands[2])
6938 && (INTVAL (operands[2]) == 128
6939 || (INTVAL (operands[2]) < 0
6940 && INTVAL (operands[2]) != -128)))
6942 operands[2] = GEN_INT (-INTVAL (operands[2]));
6943 return "sub{w}\t{%2, %0|%0, %2}";
6945 return "add{w}\t{%2, %0|%0, %2}";
6949 (if_then_else (eq_attr "alternative" "2")
6950 (const_string "lea")
6951 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6952 (const_string "incdec")
6953 (const_string "alu"))))
6954 (set_attr "mode" "HI,HI,SI")])
6956 (define_insn "*addhi_1"
6957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6958 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6959 (match_operand:HI 2 "general_operand" "rn,rm")))
6960 (clobber (reg:CC FLAGS_REG))]
6961 "TARGET_PARTIAL_REG_STALL
6962 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6964 switch (get_attr_type (insn))
6967 if (operands[2] == const1_rtx)
6968 return "inc{w}\t%0";
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{w}\t%0";
6976 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6977 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6978 if (CONST_INT_P (operands[2])
6979 && (INTVAL (operands[2]) == 128
6980 || (INTVAL (operands[2]) < 0
6981 && INTVAL (operands[2]) != -128)))
6983 operands[2] = GEN_INT (-INTVAL (operands[2]));
6984 return "sub{w}\t{%2, %0|%0, %2}";
6986 return "add{w}\t{%2, %0|%0, %2}";
6990 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6991 (const_string "incdec")
6992 (const_string "alu")))
6993 (set_attr "mode" "HI")])
6995 (define_insn "*addhi_2"
6996 [(set (reg FLAGS_REG)
6998 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6999 (match_operand:HI 2 "general_operand" "rmn,rn"))
7001 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7002 (plus:HI (match_dup 1) (match_dup 2)))]
7003 "ix86_match_ccmode (insn, CCGOCmode)
7004 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7006 switch (get_attr_type (insn))
7009 if (operands[2] == const1_rtx)
7010 return "inc{w}\t%0";
7013 gcc_assert (operands[2] == constm1_rtx);
7014 return "dec{w}\t%0";
7018 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7019 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7020 if (CONST_INT_P (operands[2])
7021 && (INTVAL (operands[2]) == 128
7022 || (INTVAL (operands[2]) < 0
7023 && INTVAL (operands[2]) != -128)))
7025 operands[2] = GEN_INT (-INTVAL (operands[2]));
7026 return "sub{w}\t{%2, %0|%0, %2}";
7028 return "add{w}\t{%2, %0|%0, %2}";
7032 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7033 (const_string "incdec")
7034 (const_string "alu")))
7035 (set_attr "mode" "HI")])
7037 (define_insn "*addhi_3"
7038 [(set (reg FLAGS_REG)
7039 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7040 (match_operand:HI 1 "nonimmediate_operand" "%0")))
7041 (clobber (match_scratch:HI 0 "=r"))]
7042 "ix86_match_ccmode (insn, CCZmode)
7043 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7045 switch (get_attr_type (insn))
7048 if (operands[2] == const1_rtx)
7049 return "inc{w}\t%0";
7052 gcc_assert (operands[2] == constm1_rtx);
7053 return "dec{w}\t%0";
7057 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7058 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7059 if (CONST_INT_P (operands[2])
7060 && (INTVAL (operands[2]) == 128
7061 || (INTVAL (operands[2]) < 0
7062 && INTVAL (operands[2]) != -128)))
7064 operands[2] = GEN_INT (-INTVAL (operands[2]));
7065 return "sub{w}\t{%2, %0|%0, %2}";
7067 return "add{w}\t{%2, %0|%0, %2}";
7071 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7072 (const_string "incdec")
7073 (const_string "alu")))
7074 (set_attr "mode" "HI")])
7076 ; See comments above addsi_4 for details.
7077 (define_insn "*addhi_4"
7078 [(set (reg FLAGS_REG)
7079 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7080 (match_operand:HI 2 "const_int_operand" "n")))
7081 (clobber (match_scratch:HI 0 "=rm"))]
7082 "ix86_match_ccmode (insn, CCGCmode)
7083 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7085 switch (get_attr_type (insn))
7088 if (operands[2] == constm1_rtx)
7089 return "inc{w}\t%0";
7092 gcc_assert (operands[2] == const1_rtx);
7093 return "dec{w}\t%0";
7097 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7098 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7099 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7100 if ((INTVAL (operands[2]) == -128
7101 || (INTVAL (operands[2]) > 0
7102 && INTVAL (operands[2]) != 128)))
7103 return "sub{w}\t{%2, %0|%0, %2}";
7104 operands[2] = GEN_INT (-INTVAL (operands[2]));
7105 return "add{w}\t{%2, %0|%0, %2}";
7109 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7110 (const_string "incdec")
7111 (const_string "alu")))
7112 (set_attr "mode" "SI")])
7115 (define_insn "*addhi_5"
7116 [(set (reg FLAGS_REG)
7118 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7119 (match_operand:HI 2 "general_operand" "rmn"))
7121 (clobber (match_scratch:HI 0 "=r"))]
7122 "ix86_match_ccmode (insn, CCGOCmode)
7123 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125 switch (get_attr_type (insn))
7128 if (operands[2] == const1_rtx)
7129 return "inc{w}\t%0";
7132 gcc_assert (operands[2] == constm1_rtx);
7133 return "dec{w}\t%0";
7137 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7138 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7139 if (CONST_INT_P (operands[2])
7140 && (INTVAL (operands[2]) == 128
7141 || (INTVAL (operands[2]) < 0
7142 && INTVAL (operands[2]) != -128)))
7144 operands[2] = GEN_INT (-INTVAL (operands[2]));
7145 return "sub{w}\t{%2, %0|%0, %2}";
7147 return "add{w}\t{%2, %0|%0, %2}";
7151 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7152 (const_string "incdec")
7153 (const_string "alu")))
7154 (set_attr "mode" "HI")])
7156 (define_expand "addqi3"
7157 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7158 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7159 (match_operand:QI 2 "general_operand" "")))]
7160 "TARGET_QIMODE_MATH"
7161 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7163 ;; %%% Potential partial reg stall on alternative 2. What to do?
7164 (define_insn "*addqi_1_lea"
7165 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7166 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7167 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7168 (clobber (reg:CC FLAGS_REG))]
7169 "!TARGET_PARTIAL_REG_STALL
7170 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7172 int widen = (which_alternative == 2);
7173 switch (get_attr_type (insn))
7178 if (operands[2] == const1_rtx)
7179 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7182 gcc_assert (operands[2] == constm1_rtx);
7183 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7187 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7188 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7189 if (CONST_INT_P (operands[2])
7190 && (INTVAL (operands[2]) == 128
7191 || (INTVAL (operands[2]) < 0
7192 && INTVAL (operands[2]) != -128)))
7194 operands[2] = GEN_INT (-INTVAL (operands[2]));
7196 return "sub{l}\t{%2, %k0|%k0, %2}";
7198 return "sub{b}\t{%2, %0|%0, %2}";
7201 return "add{l}\t{%k2, %k0|%k0, %k2}";
7203 return "add{b}\t{%2, %0|%0, %2}";
7207 (if_then_else (eq_attr "alternative" "3")
7208 (const_string "lea")
7209 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7210 (const_string "incdec")
7211 (const_string "alu"))))
7212 (set_attr "mode" "QI,QI,SI,SI")])
7214 (define_insn "*addqi_1"
7215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7216 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7217 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7218 (clobber (reg:CC FLAGS_REG))]
7219 "TARGET_PARTIAL_REG_STALL
7220 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7222 int widen = (which_alternative == 2);
7223 switch (get_attr_type (insn))
7226 if (operands[2] == const1_rtx)
7227 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7230 gcc_assert (operands[2] == constm1_rtx);
7231 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7235 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7236 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7237 if (CONST_INT_P (operands[2])
7238 && (INTVAL (operands[2]) == 128
7239 || (INTVAL (operands[2]) < 0
7240 && INTVAL (operands[2]) != -128)))
7242 operands[2] = GEN_INT (-INTVAL (operands[2]));
7244 return "sub{l}\t{%2, %k0|%k0, %2}";
7246 return "sub{b}\t{%2, %0|%0, %2}";
7249 return "add{l}\t{%k2, %k0|%k0, %k2}";
7251 return "add{b}\t{%2, %0|%0, %2}";
7255 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7256 (const_string "incdec")
7257 (const_string "alu")))
7258 (set_attr "mode" "QI,QI,SI")])
7260 (define_insn "*addqi_1_slp"
7261 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7262 (plus:QI (match_dup 0)
7263 (match_operand:QI 1 "general_operand" "qn,qnm")))
7264 (clobber (reg:CC FLAGS_REG))]
7265 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7268 switch (get_attr_type (insn))
7271 if (operands[1] == const1_rtx)
7272 return "inc{b}\t%0";
7275 gcc_assert (operands[1] == constm1_rtx);
7276 return "dec{b}\t%0";
7280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7281 if (CONST_INT_P (operands[1])
7282 && INTVAL (operands[1]) < 0)
7284 operands[1] = GEN_INT (-INTVAL (operands[1]));
7285 return "sub{b}\t{%1, %0|%0, %1}";
7287 return "add{b}\t{%1, %0|%0, %1}";
7291 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7292 (const_string "incdec")
7293 (const_string "alu1")))
7294 (set (attr "memory")
7295 (if_then_else (match_operand 1 "memory_operand" "")
7296 (const_string "load")
7297 (const_string "none")))
7298 (set_attr "mode" "QI")])
7300 (define_insn "*addqi_2"
7301 [(set (reg FLAGS_REG)
7303 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7304 (match_operand:QI 2 "general_operand" "qmn,qn"))
7306 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7307 (plus:QI (match_dup 1) (match_dup 2)))]
7308 "ix86_match_ccmode (insn, CCGOCmode)
7309 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7311 switch (get_attr_type (insn))
7314 if (operands[2] == const1_rtx)
7315 return "inc{b}\t%0";
7318 gcc_assert (operands[2] == constm1_rtx
7319 || (CONST_INT_P (operands[2])
7320 && INTVAL (operands[2]) == 255));
7321 return "dec{b}\t%0";
7325 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7326 if (CONST_INT_P (operands[2])
7327 && INTVAL (operands[2]) < 0)
7329 operands[2] = GEN_INT (-INTVAL (operands[2]));
7330 return "sub{b}\t{%2, %0|%0, %2}";
7332 return "add{b}\t{%2, %0|%0, %2}";
7336 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7337 (const_string "incdec")
7338 (const_string "alu")))
7339 (set_attr "mode" "QI")])
7341 (define_insn "*addqi_3"
7342 [(set (reg FLAGS_REG)
7343 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7344 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7345 (clobber (match_scratch:QI 0 "=q"))]
7346 "ix86_match_ccmode (insn, CCZmode)
7347 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7349 switch (get_attr_type (insn))
7352 if (operands[2] == const1_rtx)
7353 return "inc{b}\t%0";
7356 gcc_assert (operands[2] == constm1_rtx
7357 || (CONST_INT_P (operands[2])
7358 && INTVAL (operands[2]) == 255));
7359 return "dec{b}\t%0";
7363 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7364 if (CONST_INT_P (operands[2])
7365 && INTVAL (operands[2]) < 0)
7367 operands[2] = GEN_INT (-INTVAL (operands[2]));
7368 return "sub{b}\t{%2, %0|%0, %2}";
7370 return "add{b}\t{%2, %0|%0, %2}";
7374 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7375 (const_string "incdec")
7376 (const_string "alu")))
7377 (set_attr "mode" "QI")])
7379 ; See comments above addsi_4 for details.
7380 (define_insn "*addqi_4"
7381 [(set (reg FLAGS_REG)
7382 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7383 (match_operand:QI 2 "const_int_operand" "n")))
7384 (clobber (match_scratch:QI 0 "=qm"))]
7385 "ix86_match_ccmode (insn, CCGCmode)
7386 && (INTVAL (operands[2]) & 0xff) != 0x80"
7388 switch (get_attr_type (insn))
7391 if (operands[2] == constm1_rtx
7392 || (CONST_INT_P (operands[2])
7393 && INTVAL (operands[2]) == 255))
7394 return "inc{b}\t%0";
7397 gcc_assert (operands[2] == const1_rtx);
7398 return "dec{b}\t%0";
7402 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7403 if (INTVAL (operands[2]) < 0)
7405 operands[2] = GEN_INT (-INTVAL (operands[2]));
7406 return "add{b}\t{%2, %0|%0, %2}";
7408 return "sub{b}\t{%2, %0|%0, %2}";
7412 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7413 (const_string "incdec")
7414 (const_string "alu")))
7415 (set_attr "mode" "QI")])
7418 (define_insn "*addqi_5"
7419 [(set (reg FLAGS_REG)
7421 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7422 (match_operand:QI 2 "general_operand" "qmn"))
7424 (clobber (match_scratch:QI 0 "=q"))]
7425 "ix86_match_ccmode (insn, CCGOCmode)
7426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7428 switch (get_attr_type (insn))
7431 if (operands[2] == const1_rtx)
7432 return "inc{b}\t%0";
7435 gcc_assert (operands[2] == constm1_rtx
7436 || (CONST_INT_P (operands[2])
7437 && INTVAL (operands[2]) == 255));
7438 return "dec{b}\t%0";
7442 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7443 if (CONST_INT_P (operands[2])
7444 && INTVAL (operands[2]) < 0)
7446 operands[2] = GEN_INT (-INTVAL (operands[2]));
7447 return "sub{b}\t{%2, %0|%0, %2}";
7449 return "add{b}\t{%2, %0|%0, %2}";
7453 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7454 (const_string "incdec")
7455 (const_string "alu")))
7456 (set_attr "mode" "QI")])
7459 (define_insn "addqi_ext_1"
7460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7465 (match_operand 1 "ext_register_operand" "0")
7468 (match_operand:QI 2 "general_operand" "Qmn")))
7469 (clobber (reg:CC FLAGS_REG))]
7472 switch (get_attr_type (insn))
7475 if (operands[2] == const1_rtx)
7476 return "inc{b}\t%h0";
7479 gcc_assert (operands[2] == constm1_rtx
7480 || (CONST_INT_P (operands[2])
7481 && INTVAL (operands[2]) == 255));
7482 return "dec{b}\t%h0";
7486 return "add{b}\t{%2, %h0|%h0, %2}";
7490 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7491 (const_string "incdec")
7492 (const_string "alu")))
7493 (set_attr "mode" "QI")])
7495 (define_insn "*addqi_ext_1_rex64"
7496 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7501 (match_operand 1 "ext_register_operand" "0")
7504 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7505 (clobber (reg:CC FLAGS_REG))]
7508 switch (get_attr_type (insn))
7511 if (operands[2] == const1_rtx)
7512 return "inc{b}\t%h0";
7515 gcc_assert (operands[2] == constm1_rtx
7516 || (CONST_INT_P (operands[2])
7517 && INTVAL (operands[2]) == 255));
7518 return "dec{b}\t%h0";
7522 return "add{b}\t{%2, %h0|%h0, %2}";
7526 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7527 (const_string "incdec")
7528 (const_string "alu")))
7529 (set_attr "mode" "QI")])
7531 (define_insn "*addqi_ext_2"
7532 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7537 (match_operand 1 "ext_register_operand" "%0")
7541 (match_operand 2 "ext_register_operand" "Q")
7544 (clobber (reg:CC FLAGS_REG))]
7546 "add{b}\t{%h2, %h0|%h0, %h2}"
7547 [(set_attr "type" "alu")
7548 (set_attr "mode" "QI")])
7550 ;; The patterns that match these are at the end of this file.
7552 (define_expand "addxf3"
7553 [(set (match_operand:XF 0 "register_operand" "")
7554 (plus:XF (match_operand:XF 1 "register_operand" "")
7555 (match_operand:XF 2 "register_operand" "")))]
7559 (define_expand "add<mode>3"
7560 [(set (match_operand:MODEF 0 "register_operand" "")
7561 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7562 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7563 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7567 ;; Subtract instructions
7569 ;; %%% splits for subditi3
7571 (define_expand "subti3"
7572 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7573 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7574 (match_operand:TI 2 "x86_64_general_operand" "")))]
7576 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7578 (define_insn "*subti3_1"
7579 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7580 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7581 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7587 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7588 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7589 (match_operand:TI 2 "x86_64_general_operand" "")))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "TARGET_64BIT && reload_completed"
7592 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7593 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7594 (parallel [(set (match_dup 3)
7595 (minus:DI (match_dup 4)
7596 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7598 (clobber (reg:CC FLAGS_REG))])]
7599 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7601 ;; %%% splits for subsidi3
7603 (define_expand "subdi3"
7604 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7606 (match_operand:DI 2 "x86_64_general_operand" "")))]
7608 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7610 (define_insn "*subdi3_1"
7611 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7612 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7613 (match_operand:DI 2 "general_operand" "roiF,riF")))
7614 (clobber (reg:CC FLAGS_REG))]
7615 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7619 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7620 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7621 (match_operand:DI 2 "general_operand" "")))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "!TARGET_64BIT && reload_completed"
7624 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7625 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7626 (parallel [(set (match_dup 3)
7627 (minus:SI (match_dup 4)
7628 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7630 (clobber (reg:CC FLAGS_REG))])]
7631 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7633 (define_insn "subdi3_carry_rex64"
7634 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7635 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7636 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7637 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7638 (clobber (reg:CC FLAGS_REG))]
7639 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7640 "sbb{q}\t{%2, %0|%0, %2}"
7641 [(set_attr "type" "alu")
7642 (set_attr "use_carry" "1")
7643 (set_attr "pent_pair" "pu")
7644 (set_attr "mode" "DI")])
7646 (define_insn "*subdi_1_rex64"
7647 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7648 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7649 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7652 "sub{q}\t{%2, %0|%0, %2}"
7653 [(set_attr "type" "alu")
7654 (set_attr "mode" "DI")])
7656 (define_insn "*subdi_2_rex64"
7657 [(set (reg FLAGS_REG)
7659 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7660 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7662 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7663 (minus:DI (match_dup 1) (match_dup 2)))]
7664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7665 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7666 "sub{q}\t{%2, %0|%0, %2}"
7667 [(set_attr "type" "alu")
7668 (set_attr "mode" "DI")])
7670 (define_insn "*subdi_3_rex63"
7671 [(set (reg FLAGS_REG)
7672 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7673 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7674 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7675 (minus:DI (match_dup 1) (match_dup 2)))]
7676 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7677 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7678 "sub{q}\t{%2, %0|%0, %2}"
7679 [(set_attr "type" "alu")
7680 (set_attr "mode" "DI")])
7682 (define_insn "subqi3_carry"
7683 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7684 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7685 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7686 (match_operand:QI 2 "general_operand" "qn,qm"))))
7687 (clobber (reg:CC FLAGS_REG))]
7688 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7689 "sbb{b}\t{%2, %0|%0, %2}"
7690 [(set_attr "type" "alu")
7691 (set_attr "use_carry" "1")
7692 (set_attr "pent_pair" "pu")
7693 (set_attr "mode" "QI")])
7695 (define_insn "subhi3_carry"
7696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7697 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7698 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7699 (match_operand:HI 2 "general_operand" "rn,rm"))))
7700 (clobber (reg:CC FLAGS_REG))]
7701 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7702 "sbb{w}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "alu")
7704 (set_attr "use_carry" "1")
7705 (set_attr "pent_pair" "pu")
7706 (set_attr "mode" "HI")])
7708 (define_insn "subsi3_carry"
7709 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7710 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7711 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7712 (match_operand:SI 2 "general_operand" "ri,rm"))))
7713 (clobber (reg:CC FLAGS_REG))]
7714 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7715 "sbb{l}\t{%2, %0|%0, %2}"
7716 [(set_attr "type" "alu")
7717 (set_attr "use_carry" "1")
7718 (set_attr "pent_pair" "pu")
7719 (set_attr "mode" "SI")])
7721 (define_insn "subsi3_carry_zext"
7722 [(set (match_operand:DI 0 "register_operand" "=r")
7724 (minus:SI (match_operand:SI 1 "register_operand" "0")
7725 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7726 (match_operand:SI 2 "general_operand" "g")))))
7727 (clobber (reg:CC FLAGS_REG))]
7728 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7729 "sbb{l}\t{%2, %k0|%k0, %2}"
7730 [(set_attr "type" "alu")
7731 (set_attr "pent_pair" "pu")
7732 (set_attr "mode" "SI")])
7734 (define_expand "subsi3"
7735 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7736 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7737 (match_operand:SI 2 "general_operand" "")))]
7739 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7741 (define_insn "*subsi_1"
7742 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7743 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7744 (match_operand:SI 2 "general_operand" "ri,rm")))
7745 (clobber (reg:CC FLAGS_REG))]
7746 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7747 "sub{l}\t{%2, %0|%0, %2}"
7748 [(set_attr "type" "alu")
7749 (set_attr "mode" "SI")])
7751 (define_insn "*subsi_1_zext"
7752 [(set (match_operand:DI 0 "register_operand" "=r")
7754 (minus:SI (match_operand:SI 1 "register_operand" "0")
7755 (match_operand:SI 2 "general_operand" "g"))))
7756 (clobber (reg:CC FLAGS_REG))]
7757 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7758 "sub{l}\t{%2, %k0|%k0, %2}"
7759 [(set_attr "type" "alu")
7760 (set_attr "mode" "SI")])
7762 (define_insn "*subsi_2"
7763 [(set (reg FLAGS_REG)
7765 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:SI 2 "general_operand" "ri,rm"))
7768 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7769 (minus:SI (match_dup 1) (match_dup 2)))]
7770 "ix86_match_ccmode (insn, CCGOCmode)
7771 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7772 "sub{l}\t{%2, %0|%0, %2}"
7773 [(set_attr "type" "alu")
7774 (set_attr "mode" "SI")])
7776 (define_insn "*subsi_2_zext"
7777 [(set (reg FLAGS_REG)
7779 (minus:SI (match_operand:SI 1 "register_operand" "0")
7780 (match_operand:SI 2 "general_operand" "g"))
7782 (set (match_operand:DI 0 "register_operand" "=r")
7784 (minus:SI (match_dup 1)
7786 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7787 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7788 "sub{l}\t{%2, %k0|%k0, %2}"
7789 [(set_attr "type" "alu")
7790 (set_attr "mode" "SI")])
7792 (define_insn "*subsi_3"
7793 [(set (reg FLAGS_REG)
7794 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7795 (match_operand:SI 2 "general_operand" "ri,rm")))
7796 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7797 (minus:SI (match_dup 1) (match_dup 2)))]
7798 "ix86_match_ccmode (insn, CCmode)
7799 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7800 "sub{l}\t{%2, %0|%0, %2}"
7801 [(set_attr "type" "alu")
7802 (set_attr "mode" "SI")])
7804 (define_insn "*subsi_3_zext"
7805 [(set (reg FLAGS_REG)
7806 (compare (match_operand:SI 1 "register_operand" "0")
7807 (match_operand:SI 2 "general_operand" "g")))
7808 (set (match_operand:DI 0 "register_operand" "=r")
7810 (minus:SI (match_dup 1)
7812 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7813 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7814 "sub{l}\t{%2, %1|%1, %2}"
7815 [(set_attr "type" "alu")
7816 (set_attr "mode" "DI")])
7818 (define_expand "subhi3"
7819 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7820 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7821 (match_operand:HI 2 "general_operand" "")))]
7822 "TARGET_HIMODE_MATH"
7823 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7825 (define_insn "*subhi_1"
7826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7827 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7828 (match_operand:HI 2 "general_operand" "rn,rm")))
7829 (clobber (reg:CC FLAGS_REG))]
7830 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7831 "sub{w}\t{%2, %0|%0, %2}"
7832 [(set_attr "type" "alu")
7833 (set_attr "mode" "HI")])
7835 (define_insn "*subhi_2"
7836 [(set (reg FLAGS_REG)
7838 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7839 (match_operand:HI 2 "general_operand" "rn,rm"))
7841 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7842 (minus:HI (match_dup 1) (match_dup 2)))]
7843 "ix86_match_ccmode (insn, CCGOCmode)
7844 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7845 "sub{w}\t{%2, %0|%0, %2}"
7846 [(set_attr "type" "alu")
7847 (set_attr "mode" "HI")])
7849 (define_insn "*subhi_3"
7850 [(set (reg FLAGS_REG)
7851 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7852 (match_operand:HI 2 "general_operand" "rn,rm")))
7853 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7854 (minus:HI (match_dup 1) (match_dup 2)))]
7855 "ix86_match_ccmode (insn, CCmode)
7856 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7857 "sub{w}\t{%2, %0|%0, %2}"
7858 [(set_attr "type" "alu")
7859 (set_attr "mode" "HI")])
7861 (define_expand "subqi3"
7862 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7863 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7864 (match_operand:QI 2 "general_operand" "")))]
7865 "TARGET_QIMODE_MATH"
7866 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7868 (define_insn "*subqi_1"
7869 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7870 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7871 (match_operand:QI 2 "general_operand" "qn,qm")))
7872 (clobber (reg:CC FLAGS_REG))]
7873 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7874 "sub{b}\t{%2, %0|%0, %2}"
7875 [(set_attr "type" "alu")
7876 (set_attr "mode" "QI")])
7878 (define_insn "*subqi_1_slp"
7879 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7880 (minus:QI (match_dup 0)
7881 (match_operand:QI 1 "general_operand" "qn,qm")))
7882 (clobber (reg:CC FLAGS_REG))]
7883 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7885 "sub{b}\t{%1, %0|%0, %1}"
7886 [(set_attr "type" "alu1")
7887 (set_attr "mode" "QI")])
7889 (define_insn "*subqi_2"
7890 [(set (reg FLAGS_REG)
7892 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7893 (match_operand:QI 2 "general_operand" "qn,qm"))
7895 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7896 (minus:QI (match_dup 1) (match_dup 2)))]
7897 "ix86_match_ccmode (insn, CCGOCmode)
7898 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7899 "sub{b}\t{%2, %0|%0, %2}"
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "QI")])
7903 (define_insn "*subqi_3"
7904 [(set (reg FLAGS_REG)
7905 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7906 (match_operand:QI 2 "general_operand" "qn,qm")))
7907 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7908 (minus:QI (match_dup 1) (match_dup 2)))]
7909 "ix86_match_ccmode (insn, CCmode)
7910 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7911 "sub{b}\t{%2, %0|%0, %2}"
7912 [(set_attr "type" "alu")
7913 (set_attr "mode" "QI")])
7915 ;; The patterns that match these are at the end of this file.
7917 (define_expand "subxf3"
7918 [(set (match_operand:XF 0 "register_operand" "")
7919 (minus:XF (match_operand:XF 1 "register_operand" "")
7920 (match_operand:XF 2 "register_operand" "")))]
7924 (define_expand "sub<mode>3"
7925 [(set (match_operand:MODEF 0 "register_operand" "")
7926 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7927 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7928 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7929 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7932 ;; Multiply instructions
7934 (define_expand "muldi3"
7935 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7936 (mult:DI (match_operand:DI 1 "register_operand" "")
7937 (match_operand:DI 2 "x86_64_general_operand" "")))
7938 (clobber (reg:CC FLAGS_REG))])]
7943 ;; IMUL reg64, reg64, imm8 Direct
7944 ;; IMUL reg64, mem64, imm8 VectorPath
7945 ;; IMUL reg64, reg64, imm32 Direct
7946 ;; IMUL reg64, mem64, imm32 VectorPath
7947 ;; IMUL reg64, reg64 Direct
7948 ;; IMUL reg64, mem64 Direct
7950 (define_insn "*muldi3_1_rex64"
7951 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7952 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7953 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7954 (clobber (reg:CC FLAGS_REG))]
7956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7958 imul{q}\t{%2, %1, %0|%0, %1, %2}
7959 imul{q}\t{%2, %1, %0|%0, %1, %2}
7960 imul{q}\t{%2, %0|%0, %2}"
7961 [(set_attr "type" "imul")
7962 (set_attr "prefix_0f" "0,0,1")
7963 (set (attr "athlon_decode")
7964 (cond [(eq_attr "cpu" "athlon")
7965 (const_string "vector")
7966 (eq_attr "alternative" "1")
7967 (const_string "vector")
7968 (and (eq_attr "alternative" "2")
7969 (match_operand 1 "memory_operand" ""))
7970 (const_string "vector")]
7971 (const_string "direct")))
7972 (set (attr "amdfam10_decode")
7973 (cond [(and (eq_attr "alternative" "0,1")
7974 (match_operand 1 "memory_operand" ""))
7975 (const_string "vector")]
7976 (const_string "direct")))
7977 (set_attr "mode" "DI")])
7979 (define_expand "mulsi3"
7980 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7981 (mult:SI (match_operand:SI 1 "register_operand" "")
7982 (match_operand:SI 2 "general_operand" "")))
7983 (clobber (reg:CC FLAGS_REG))])]
7988 ;; IMUL reg32, reg32, imm8 Direct
7989 ;; IMUL reg32, mem32, imm8 VectorPath
7990 ;; IMUL reg32, reg32, imm32 Direct
7991 ;; IMUL reg32, mem32, imm32 VectorPath
7992 ;; IMUL reg32, reg32 Direct
7993 ;; IMUL reg32, mem32 Direct
7995 (define_insn "*mulsi3_1"
7996 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7997 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7998 (match_operand:SI 2 "general_operand" "K,i,mr")))
7999 (clobber (reg:CC FLAGS_REG))]
8000 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8002 imul{l}\t{%2, %1, %0|%0, %1, %2}
8003 imul{l}\t{%2, %1, %0|%0, %1, %2}
8004 imul{l}\t{%2, %0|%0, %2}"
8005 [(set_attr "type" "imul")
8006 (set_attr "prefix_0f" "0,0,1")
8007 (set (attr "athlon_decode")
8008 (cond [(eq_attr "cpu" "athlon")
8009 (const_string "vector")
8010 (eq_attr "alternative" "1")
8011 (const_string "vector")
8012 (and (eq_attr "alternative" "2")
8013 (match_operand 1 "memory_operand" ""))
8014 (const_string "vector")]
8015 (const_string "direct")))
8016 (set (attr "amdfam10_decode")
8017 (cond [(and (eq_attr "alternative" "0,1")
8018 (match_operand 1 "memory_operand" ""))
8019 (const_string "vector")]
8020 (const_string "direct")))
8021 (set_attr "mode" "SI")])
8023 (define_insn "*mulsi3_1_zext"
8024 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8026 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8027 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8028 (clobber (reg:CC FLAGS_REG))]
8030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8033 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8034 imul{l}\t{%2, %k0|%k0, %2}"
8035 [(set_attr "type" "imul")
8036 (set_attr "prefix_0f" "0,0,1")
8037 (set (attr "athlon_decode")
8038 (cond [(eq_attr "cpu" "athlon")
8039 (const_string "vector")
8040 (eq_attr "alternative" "1")
8041 (const_string "vector")
8042 (and (eq_attr "alternative" "2")
8043 (match_operand 1 "memory_operand" ""))
8044 (const_string "vector")]
8045 (const_string "direct")))
8046 (set (attr "amdfam10_decode")
8047 (cond [(and (eq_attr "alternative" "0,1")
8048 (match_operand 1 "memory_operand" ""))
8049 (const_string "vector")]
8050 (const_string "direct")))
8051 (set_attr "mode" "SI")])
8053 (define_expand "mulhi3"
8054 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8055 (mult:HI (match_operand:HI 1 "register_operand" "")
8056 (match_operand:HI 2 "general_operand" "")))
8057 (clobber (reg:CC FLAGS_REG))])]
8058 "TARGET_HIMODE_MATH"
8062 ;; IMUL reg16, reg16, imm8 VectorPath
8063 ;; IMUL reg16, mem16, imm8 VectorPath
8064 ;; IMUL reg16, reg16, imm16 VectorPath
8065 ;; IMUL reg16, mem16, imm16 VectorPath
8066 ;; IMUL reg16, reg16 Direct
8067 ;; IMUL reg16, mem16 Direct
8068 (define_insn "*mulhi3_1"
8069 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8070 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8071 (match_operand:HI 2 "general_operand" "K,n,mr")))
8072 (clobber (reg:CC FLAGS_REG))]
8073 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8075 imul{w}\t{%2, %1, %0|%0, %1, %2}
8076 imul{w}\t{%2, %1, %0|%0, %1, %2}
8077 imul{w}\t{%2, %0|%0, %2}"
8078 [(set_attr "type" "imul")
8079 (set_attr "prefix_0f" "0,0,1")
8080 (set (attr "athlon_decode")
8081 (cond [(eq_attr "cpu" "athlon")
8082 (const_string "vector")
8083 (eq_attr "alternative" "1,2")
8084 (const_string "vector")]
8085 (const_string "direct")))
8086 (set (attr "amdfam10_decode")
8087 (cond [(eq_attr "alternative" "0,1")
8088 (const_string "vector")]
8089 (const_string "direct")))
8090 (set_attr "mode" "HI")])
8092 (define_expand "mulqi3"
8093 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8094 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8095 (match_operand:QI 2 "register_operand" "")))
8096 (clobber (reg:CC FLAGS_REG))])]
8097 "TARGET_QIMODE_MATH"
8104 (define_insn "*mulqi3_1"
8105 [(set (match_operand:QI 0 "register_operand" "=a")
8106 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8107 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8108 (clobber (reg:CC FLAGS_REG))]
8110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112 [(set_attr "type" "imul")
8113 (set_attr "length_immediate" "0")
8114 (set (attr "athlon_decode")
8115 (if_then_else (eq_attr "cpu" "athlon")
8116 (const_string "vector")
8117 (const_string "direct")))
8118 (set_attr "amdfam10_decode" "direct")
8119 (set_attr "mode" "QI")])
8121 (define_expand "umulqihi3"
8122 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8123 (mult:HI (zero_extend:HI
8124 (match_operand:QI 1 "nonimmediate_operand" ""))
8126 (match_operand:QI 2 "register_operand" ""))))
8127 (clobber (reg:CC FLAGS_REG))])]
8128 "TARGET_QIMODE_MATH"
8131 (define_insn "*umulqihi3_1"
8132 [(set (match_operand:HI 0 "register_operand" "=a")
8133 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8134 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8135 (clobber (reg:CC FLAGS_REG))]
8137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 [(set_attr "type" "imul")
8140 (set_attr "length_immediate" "0")
8141 (set (attr "athlon_decode")
8142 (if_then_else (eq_attr "cpu" "athlon")
8143 (const_string "vector")
8144 (const_string "direct")))
8145 (set_attr "amdfam10_decode" "direct")
8146 (set_attr "mode" "QI")])
8148 (define_expand "mulqihi3"
8149 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8150 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8151 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8152 (clobber (reg:CC FLAGS_REG))])]
8153 "TARGET_QIMODE_MATH"
8156 (define_insn "*mulqihi3_insn"
8157 [(set (match_operand:HI 0 "register_operand" "=a")
8158 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8159 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8160 (clobber (reg:CC FLAGS_REG))]
8162 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8164 [(set_attr "type" "imul")
8165 (set_attr "length_immediate" "0")
8166 (set (attr "athlon_decode")
8167 (if_then_else (eq_attr "cpu" "athlon")
8168 (const_string "vector")
8169 (const_string "direct")))
8170 (set_attr "amdfam10_decode" "direct")
8171 (set_attr "mode" "QI")])
8173 (define_expand "umulditi3"
8174 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8175 (mult:TI (zero_extend:TI
8176 (match_operand:DI 1 "nonimmediate_operand" ""))
8178 (match_operand:DI 2 "register_operand" ""))))
8179 (clobber (reg:CC FLAGS_REG))])]
8183 (define_insn "*umulditi3_insn"
8184 [(set (match_operand:TI 0 "register_operand" "=A")
8185 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8186 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8187 (clobber (reg:CC FLAGS_REG))]
8189 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8191 [(set_attr "type" "imul")
8192 (set_attr "length_immediate" "0")
8193 (set (attr "athlon_decode")
8194 (if_then_else (eq_attr "cpu" "athlon")
8195 (const_string "vector")
8196 (const_string "double")))
8197 (set_attr "amdfam10_decode" "double")
8198 (set_attr "mode" "DI")])
8200 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8201 (define_expand "umulsidi3"
8202 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8203 (mult:DI (zero_extend:DI
8204 (match_operand:SI 1 "nonimmediate_operand" ""))
8206 (match_operand:SI 2 "register_operand" ""))))
8207 (clobber (reg:CC FLAGS_REG))])]
8211 (define_insn "*umulsidi3_insn"
8212 [(set (match_operand:DI 0 "register_operand" "=A")
8213 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8214 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8215 (clobber (reg:CC FLAGS_REG))]
8217 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8219 [(set_attr "type" "imul")
8220 (set_attr "length_immediate" "0")
8221 (set (attr "athlon_decode")
8222 (if_then_else (eq_attr "cpu" "athlon")
8223 (const_string "vector")
8224 (const_string "double")))
8225 (set_attr "amdfam10_decode" "double")
8226 (set_attr "mode" "SI")])
8228 (define_expand "mulditi3"
8229 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8230 (mult:TI (sign_extend:TI
8231 (match_operand:DI 1 "nonimmediate_operand" ""))
8233 (match_operand:DI 2 "register_operand" ""))))
8234 (clobber (reg:CC FLAGS_REG))])]
8238 (define_insn "*mulditi3_insn"
8239 [(set (match_operand:TI 0 "register_operand" "=A")
8240 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8241 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8242 (clobber (reg:CC FLAGS_REG))]
8244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8246 [(set_attr "type" "imul")
8247 (set_attr "length_immediate" "0")
8248 (set (attr "athlon_decode")
8249 (if_then_else (eq_attr "cpu" "athlon")
8250 (const_string "vector")
8251 (const_string "double")))
8252 (set_attr "amdfam10_decode" "double")
8253 (set_attr "mode" "DI")])
8255 (define_expand "mulsidi3"
8256 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8257 (mult:DI (sign_extend:DI
8258 (match_operand:SI 1 "nonimmediate_operand" ""))
8260 (match_operand:SI 2 "register_operand" ""))))
8261 (clobber (reg:CC FLAGS_REG))])]
8265 (define_insn "*mulsidi3_insn"
8266 [(set (match_operand:DI 0 "register_operand" "=A")
8267 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8268 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8269 (clobber (reg:CC FLAGS_REG))]
8271 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8273 [(set_attr "type" "imul")
8274 (set_attr "length_immediate" "0")
8275 (set (attr "athlon_decode")
8276 (if_then_else (eq_attr "cpu" "athlon")
8277 (const_string "vector")
8278 (const_string "double")))
8279 (set_attr "amdfam10_decode" "double")
8280 (set_attr "mode" "SI")])
8282 (define_expand "umuldi3_highpart"
8283 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8286 (mult:TI (zero_extend:TI
8287 (match_operand:DI 1 "nonimmediate_operand" ""))
8289 (match_operand:DI 2 "register_operand" "")))
8291 (clobber (match_scratch:DI 3 ""))
8292 (clobber (reg:CC FLAGS_REG))])]
8296 (define_insn "*umuldi3_highpart_rex64"
8297 [(set (match_operand:DI 0 "register_operand" "=d")
8300 (mult:TI (zero_extend:TI
8301 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8303 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8305 (clobber (match_scratch:DI 3 "=1"))
8306 (clobber (reg:CC FLAGS_REG))]
8308 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8310 [(set_attr "type" "imul")
8311 (set_attr "length_immediate" "0")
8312 (set (attr "athlon_decode")
8313 (if_then_else (eq_attr "cpu" "athlon")
8314 (const_string "vector")
8315 (const_string "double")))
8316 (set_attr "amdfam10_decode" "double")
8317 (set_attr "mode" "DI")])
8319 (define_expand "umulsi3_highpart"
8320 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8323 (mult:DI (zero_extend:DI
8324 (match_operand:SI 1 "nonimmediate_operand" ""))
8326 (match_operand:SI 2 "register_operand" "")))
8328 (clobber (match_scratch:SI 3 ""))
8329 (clobber (reg:CC FLAGS_REG))])]
8333 (define_insn "*umulsi3_highpart_insn"
8334 [(set (match_operand:SI 0 "register_operand" "=d")
8337 (mult:DI (zero_extend:DI
8338 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8340 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8342 (clobber (match_scratch:SI 3 "=1"))
8343 (clobber (reg:CC FLAGS_REG))]
8344 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8346 [(set_attr "type" "imul")
8347 (set_attr "length_immediate" "0")
8348 (set (attr "athlon_decode")
8349 (if_then_else (eq_attr "cpu" "athlon")
8350 (const_string "vector")
8351 (const_string "double")))
8352 (set_attr "amdfam10_decode" "double")
8353 (set_attr "mode" "SI")])
8355 (define_insn "*umulsi3_highpart_zext"
8356 [(set (match_operand:DI 0 "register_operand" "=d")
8357 (zero_extend:DI (truncate:SI
8359 (mult:DI (zero_extend:DI
8360 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8362 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8364 (clobber (match_scratch:SI 3 "=1"))
8365 (clobber (reg:CC FLAGS_REG))]
8367 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8369 [(set_attr "type" "imul")
8370 (set_attr "length_immediate" "0")
8371 (set (attr "athlon_decode")
8372 (if_then_else (eq_attr "cpu" "athlon")
8373 (const_string "vector")
8374 (const_string "double")))
8375 (set_attr "amdfam10_decode" "double")
8376 (set_attr "mode" "SI")])
8378 (define_expand "smuldi3_highpart"
8379 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8382 (mult:TI (sign_extend:TI
8383 (match_operand:DI 1 "nonimmediate_operand" ""))
8385 (match_operand:DI 2 "register_operand" "")))
8387 (clobber (match_scratch:DI 3 ""))
8388 (clobber (reg:CC FLAGS_REG))])]
8392 (define_insn "*smuldi3_highpart_rex64"
8393 [(set (match_operand:DI 0 "register_operand" "=d")
8396 (mult:TI (sign_extend:TI
8397 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8399 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8401 (clobber (match_scratch:DI 3 "=1"))
8402 (clobber (reg:CC FLAGS_REG))]
8404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8406 [(set_attr "type" "imul")
8407 (set (attr "athlon_decode")
8408 (if_then_else (eq_attr "cpu" "athlon")
8409 (const_string "vector")
8410 (const_string "double")))
8411 (set_attr "amdfam10_decode" "double")
8412 (set_attr "mode" "DI")])
8414 (define_expand "smulsi3_highpart"
8415 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8418 (mult:DI (sign_extend:DI
8419 (match_operand:SI 1 "nonimmediate_operand" ""))
8421 (match_operand:SI 2 "register_operand" "")))
8423 (clobber (match_scratch:SI 3 ""))
8424 (clobber (reg:CC FLAGS_REG))])]
8428 (define_insn "*smulsi3_highpart_insn"
8429 [(set (match_operand:SI 0 "register_operand" "=d")
8432 (mult:DI (sign_extend:DI
8433 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8435 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8437 (clobber (match_scratch:SI 3 "=1"))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8441 [(set_attr "type" "imul")
8442 (set (attr "athlon_decode")
8443 (if_then_else (eq_attr "cpu" "athlon")
8444 (const_string "vector")
8445 (const_string "double")))
8446 (set_attr "amdfam10_decode" "double")
8447 (set_attr "mode" "SI")])
8449 (define_insn "*smulsi3_highpart_zext"
8450 [(set (match_operand:DI 0 "register_operand" "=d")
8451 (zero_extend:DI (truncate:SI
8453 (mult:DI (sign_extend:DI
8454 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8456 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8458 (clobber (match_scratch:SI 3 "=1"))
8459 (clobber (reg:CC FLAGS_REG))]
8461 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8463 [(set_attr "type" "imul")
8464 (set (attr "athlon_decode")
8465 (if_then_else (eq_attr "cpu" "athlon")
8466 (const_string "vector")
8467 (const_string "double")))
8468 (set_attr "amdfam10_decode" "double")
8469 (set_attr "mode" "SI")])
8471 ;; The patterns that match these are at the end of this file.
8473 (define_expand "mulxf3"
8474 [(set (match_operand:XF 0 "register_operand" "")
8475 (mult:XF (match_operand:XF 1 "register_operand" "")
8476 (match_operand:XF 2 "register_operand" "")))]
8480 (define_expand "mul<mode>3"
8481 [(set (match_operand:MODEF 0 "register_operand" "")
8482 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8483 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8484 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8485 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8488 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8491 ;; Divide instructions
8493 (define_insn "divqi3"
8494 [(set (match_operand:QI 0 "register_operand" "=a")
8495 (div:QI (match_operand:HI 1 "register_operand" "0")
8496 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8497 (clobber (reg:CC FLAGS_REG))]
8498 "TARGET_QIMODE_MATH"
8500 [(set_attr "type" "idiv")
8501 (set_attr "mode" "QI")])
8503 (define_insn "udivqi3"
8504 [(set (match_operand:QI 0 "register_operand" "=a")
8505 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8506 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8507 (clobber (reg:CC FLAGS_REG))]
8508 "TARGET_QIMODE_MATH"
8510 [(set_attr "type" "idiv")
8511 (set_attr "mode" "QI")])
8513 ;; The patterns that match these are at the end of this file.
8515 (define_expand "divxf3"
8516 [(set (match_operand:XF 0 "register_operand" "")
8517 (div:XF (match_operand:XF 1 "register_operand" "")
8518 (match_operand:XF 2 "register_operand" "")))]
8522 (define_expand "divdf3"
8523 [(set (match_operand:DF 0 "register_operand" "")
8524 (div:DF (match_operand:DF 1 "register_operand" "")
8525 (match_operand:DF 2 "nonimmediate_operand" "")))]
8526 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8527 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8530 (define_expand "divsf3"
8531 [(set (match_operand:SF 0 "register_operand" "")
8532 (div:SF (match_operand:SF 1 "register_operand" "")
8533 (match_operand:SF 2 "nonimmediate_operand" "")))]
8534 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8537 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8538 && flag_finite_math_only && !flag_trapping_math
8539 && flag_unsafe_math_optimizations)
8541 ix86_emit_swdivsf (operands[0], operands[1],
8542 operands[2], SFmode);
8547 ;; Remainder instructions.
8549 (define_expand "divmoddi4"
8550 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8551 (div:DI (match_operand:DI 1 "register_operand" "")
8552 (match_operand:DI 2 "nonimmediate_operand" "")))
8553 (set (match_operand:DI 3 "register_operand" "")
8554 (mod:DI (match_dup 1) (match_dup 2)))
8555 (clobber (reg:CC FLAGS_REG))])]
8559 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8560 ;; Penalize eax case slightly because it results in worse scheduling
8562 (define_insn "*divmoddi4_nocltd_rex64"
8563 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8564 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8565 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8566 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8567 (mod:DI (match_dup 2) (match_dup 3)))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8571 [(set_attr "type" "multi")])
8573 (define_insn "*divmoddi4_cltd_rex64"
8574 [(set (match_operand:DI 0 "register_operand" "=a")
8575 (div:DI (match_operand:DI 2 "register_operand" "a")
8576 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8577 (set (match_operand:DI 1 "register_operand" "=&d")
8578 (mod:DI (match_dup 2) (match_dup 3)))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8582 [(set_attr "type" "multi")])
8584 (define_insn "*divmoddi_noext_rex64"
8585 [(set (match_operand:DI 0 "register_operand" "=a")
8586 (div:DI (match_operand:DI 1 "register_operand" "0")
8587 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8588 (set (match_operand:DI 3 "register_operand" "=d")
8589 (mod:DI (match_dup 1) (match_dup 2)))
8590 (use (match_operand:DI 4 "register_operand" "3"))
8591 (clobber (reg:CC FLAGS_REG))]
8594 [(set_attr "type" "idiv")
8595 (set_attr "mode" "DI")])
8598 [(set (match_operand:DI 0 "register_operand" "")
8599 (div:DI (match_operand:DI 1 "register_operand" "")
8600 (match_operand:DI 2 "nonimmediate_operand" "")))
8601 (set (match_operand:DI 3 "register_operand" "")
8602 (mod:DI (match_dup 1) (match_dup 2)))
8603 (clobber (reg:CC FLAGS_REG))]
8604 "TARGET_64BIT && reload_completed"
8605 [(parallel [(set (match_dup 3)
8606 (ashiftrt:DI (match_dup 4) (const_int 63)))
8607 (clobber (reg:CC FLAGS_REG))])
8608 (parallel [(set (match_dup 0)
8609 (div:DI (reg:DI 0) (match_dup 2)))
8611 (mod:DI (reg:DI 0) (match_dup 2)))
8613 (clobber (reg:CC FLAGS_REG))])]
8615 /* Avoid use of cltd in favor of a mov+shift. */
8616 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8618 if (true_regnum (operands[1]))
8619 emit_move_insn (operands[0], operands[1]);
8621 emit_move_insn (operands[3], operands[1]);
8622 operands[4] = operands[3];
8626 gcc_assert (!true_regnum (operands[1]));
8627 operands[4] = operands[1];
8632 (define_expand "divmodsi4"
8633 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8634 (div:SI (match_operand:SI 1 "register_operand" "")
8635 (match_operand:SI 2 "nonimmediate_operand" "")))
8636 (set (match_operand:SI 3 "register_operand" "")
8637 (mod:SI (match_dup 1) (match_dup 2)))
8638 (clobber (reg:CC FLAGS_REG))])]
8642 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8643 ;; Penalize eax case slightly because it results in worse scheduling
8645 (define_insn "*divmodsi4_nocltd"
8646 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8647 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8648 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8649 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8650 (mod:SI (match_dup 2) (match_dup 3)))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8654 [(set_attr "type" "multi")])
8656 (define_insn "*divmodsi4_cltd"
8657 [(set (match_operand:SI 0 "register_operand" "=a")
8658 (div:SI (match_operand:SI 2 "register_operand" "a")
8659 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8660 (set (match_operand:SI 1 "register_operand" "=&d")
8661 (mod:SI (match_dup 2) (match_dup 3)))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8665 [(set_attr "type" "multi")])
8667 (define_insn "*divmodsi_noext"
8668 [(set (match_operand:SI 0 "register_operand" "=a")
8669 (div:SI (match_operand:SI 1 "register_operand" "0")
8670 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8671 (set (match_operand:SI 3 "register_operand" "=d")
8672 (mod:SI (match_dup 1) (match_dup 2)))
8673 (use (match_operand:SI 4 "register_operand" "3"))
8674 (clobber (reg:CC FLAGS_REG))]
8677 [(set_attr "type" "idiv")
8678 (set_attr "mode" "SI")])
8681 [(set (match_operand:SI 0 "register_operand" "")
8682 (div:SI (match_operand:SI 1 "register_operand" "")
8683 (match_operand:SI 2 "nonimmediate_operand" "")))
8684 (set (match_operand:SI 3 "register_operand" "")
8685 (mod:SI (match_dup 1) (match_dup 2)))
8686 (clobber (reg:CC FLAGS_REG))]
8688 [(parallel [(set (match_dup 3)
8689 (ashiftrt:SI (match_dup 4) (const_int 31)))
8690 (clobber (reg:CC FLAGS_REG))])
8691 (parallel [(set (match_dup 0)
8692 (div:SI (reg:SI 0) (match_dup 2)))
8694 (mod:SI (reg:SI 0) (match_dup 2)))
8696 (clobber (reg:CC FLAGS_REG))])]
8698 /* Avoid use of cltd in favor of a mov+shift. */
8699 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8701 if (true_regnum (operands[1]))
8702 emit_move_insn (operands[0], operands[1]);
8704 emit_move_insn (operands[3], operands[1]);
8705 operands[4] = operands[3];
8709 gcc_assert (!true_regnum (operands[1]));
8710 operands[4] = operands[1];
8714 (define_insn "divmodhi4"
8715 [(set (match_operand:HI 0 "register_operand" "=a")
8716 (div:HI (match_operand:HI 1 "register_operand" "0")
8717 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8718 (set (match_operand:HI 3 "register_operand" "=&d")
8719 (mod:HI (match_dup 1) (match_dup 2)))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "TARGET_HIMODE_MATH"
8723 [(set_attr "type" "multi")
8724 (set_attr "length_immediate" "0")
8725 (set_attr "mode" "SI")])
8727 (define_insn "udivmoddi4"
8728 [(set (match_operand:DI 0 "register_operand" "=a")
8729 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8730 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8731 (set (match_operand:DI 3 "register_operand" "=&d")
8732 (umod:DI (match_dup 1) (match_dup 2)))
8733 (clobber (reg:CC FLAGS_REG))]
8735 "xor{q}\t%3, %3\;div{q}\t%2"
8736 [(set_attr "type" "multi")
8737 (set_attr "length_immediate" "0")
8738 (set_attr "mode" "DI")])
8740 (define_insn "*udivmoddi4_noext"
8741 [(set (match_operand:DI 0 "register_operand" "=a")
8742 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8743 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8744 (set (match_operand:DI 3 "register_operand" "=d")
8745 (umod:DI (match_dup 1) (match_dup 2)))
8747 (clobber (reg:CC FLAGS_REG))]
8750 [(set_attr "type" "idiv")
8751 (set_attr "mode" "DI")])
8754 [(set (match_operand:DI 0 "register_operand" "")
8755 (udiv:DI (match_operand:DI 1 "register_operand" "")
8756 (match_operand:DI 2 "nonimmediate_operand" "")))
8757 (set (match_operand:DI 3 "register_operand" "")
8758 (umod:DI (match_dup 1) (match_dup 2)))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "TARGET_64BIT && reload_completed"
8761 [(set (match_dup 3) (const_int 0))
8762 (parallel [(set (match_dup 0)
8763 (udiv:DI (match_dup 1) (match_dup 2)))
8765 (umod:DI (match_dup 1) (match_dup 2)))
8767 (clobber (reg:CC FLAGS_REG))])]
8770 (define_insn "udivmodsi4"
8771 [(set (match_operand:SI 0 "register_operand" "=a")
8772 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8773 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8774 (set (match_operand:SI 3 "register_operand" "=&d")
8775 (umod:SI (match_dup 1) (match_dup 2)))
8776 (clobber (reg:CC FLAGS_REG))]
8778 "xor{l}\t%3, %3\;div{l}\t%2"
8779 [(set_attr "type" "multi")
8780 (set_attr "length_immediate" "0")
8781 (set_attr "mode" "SI")])
8783 (define_insn "*udivmodsi4_noext"
8784 [(set (match_operand:SI 0 "register_operand" "=a")
8785 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8786 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8787 (set (match_operand:SI 3 "register_operand" "=d")
8788 (umod:SI (match_dup 1) (match_dup 2)))
8790 (clobber (reg:CC FLAGS_REG))]
8793 [(set_attr "type" "idiv")
8794 (set_attr "mode" "SI")])
8797 [(set (match_operand:SI 0 "register_operand" "")
8798 (udiv:SI (match_operand:SI 1 "register_operand" "")
8799 (match_operand:SI 2 "nonimmediate_operand" "")))
8800 (set (match_operand:SI 3 "register_operand" "")
8801 (umod:SI (match_dup 1) (match_dup 2)))
8802 (clobber (reg:CC FLAGS_REG))]
8804 [(set (match_dup 3) (const_int 0))
8805 (parallel [(set (match_dup 0)
8806 (udiv:SI (match_dup 1) (match_dup 2)))
8808 (umod:SI (match_dup 1) (match_dup 2)))
8810 (clobber (reg:CC FLAGS_REG))])]
8813 (define_expand "udivmodhi4"
8814 [(set (match_dup 4) (const_int 0))
8815 (parallel [(set (match_operand:HI 0 "register_operand" "")
8816 (udiv:HI (match_operand:HI 1 "register_operand" "")
8817 (match_operand:HI 2 "nonimmediate_operand" "")))
8818 (set (match_operand:HI 3 "register_operand" "")
8819 (umod:HI (match_dup 1) (match_dup 2)))
8821 (clobber (reg:CC FLAGS_REG))])]
8822 "TARGET_HIMODE_MATH"
8823 "operands[4] = gen_reg_rtx (HImode);")
8825 (define_insn "*udivmodhi_noext"
8826 [(set (match_operand:HI 0 "register_operand" "=a")
8827 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8828 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8829 (set (match_operand:HI 3 "register_operand" "=d")
8830 (umod:HI (match_dup 1) (match_dup 2)))
8831 (use (match_operand:HI 4 "register_operand" "3"))
8832 (clobber (reg:CC FLAGS_REG))]
8835 [(set_attr "type" "idiv")
8836 (set_attr "mode" "HI")])
8838 ;; We cannot use div/idiv for double division, because it causes
8839 ;; "division by zero" on the overflow and that's not what we expect
8840 ;; from truncate. Because true (non truncating) double division is
8841 ;; never generated, we can't create this insn anyway.
8844 ; [(set (match_operand:SI 0 "register_operand" "=a")
8846 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8848 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8849 ; (set (match_operand:SI 3 "register_operand" "=d")
8851 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8852 ; (clobber (reg:CC FLAGS_REG))]
8854 ; "div{l}\t{%2, %0|%0, %2}"
8855 ; [(set_attr "type" "idiv")])
8857 ;;- Logical AND instructions
8859 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8860 ;; Note that this excludes ah.
8862 (define_insn "*testdi_1_rex64"
8863 [(set (reg FLAGS_REG)
8865 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8866 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8871 test{l}\t{%k1, %k0|%k0, %k1}
8872 test{l}\t{%k1, %k0|%k0, %k1}
8873 test{q}\t{%1, %0|%0, %1}
8874 test{q}\t{%1, %0|%0, %1}
8875 test{q}\t{%1, %0|%0, %1}"
8876 [(set_attr "type" "test")
8877 (set_attr "modrm" "0,1,0,1,1")
8878 (set_attr "mode" "SI,SI,DI,DI,DI")
8879 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8881 (define_insn "testsi_1"
8882 [(set (reg FLAGS_REG)
8884 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8885 (match_operand:SI 1 "general_operand" "i,i,ri"))
8887 "ix86_match_ccmode (insn, CCNOmode)
8888 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8889 "test{l}\t{%1, %0|%0, %1}"
8890 [(set_attr "type" "test")
8891 (set_attr "modrm" "0,1,1")
8892 (set_attr "mode" "SI")
8893 (set_attr "pent_pair" "uv,np,uv")])
8895 (define_expand "testsi_ccno_1"
8896 [(set (reg:CCNO FLAGS_REG)
8898 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8899 (match_operand:SI 1 "nonmemory_operand" ""))
8904 (define_insn "*testhi_1"
8905 [(set (reg FLAGS_REG)
8906 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8907 (match_operand:HI 1 "general_operand" "n,n,rn"))
8909 "ix86_match_ccmode (insn, CCNOmode)
8910 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8911 "test{w}\t{%1, %0|%0, %1}"
8912 [(set_attr "type" "test")
8913 (set_attr "modrm" "0,1,1")
8914 (set_attr "mode" "HI")
8915 (set_attr "pent_pair" "uv,np,uv")])
8917 (define_expand "testqi_ccz_1"
8918 [(set (reg:CCZ FLAGS_REG)
8919 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8920 (match_operand:QI 1 "nonmemory_operand" ""))
8925 (define_insn "*testqi_1_maybe_si"
8926 [(set (reg FLAGS_REG)
8929 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8930 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8932 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8933 && ix86_match_ccmode (insn,
8934 CONST_INT_P (operands[1])
8935 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8937 if (which_alternative == 3)
8939 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8940 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8941 return "test{l}\t{%1, %k0|%k0, %1}";
8943 return "test{b}\t{%1, %0|%0, %1}";
8945 [(set_attr "type" "test")
8946 (set_attr "modrm" "0,1,1,1")
8947 (set_attr "mode" "QI,QI,QI,SI")
8948 (set_attr "pent_pair" "uv,np,uv,np")])
8950 (define_insn "*testqi_1"
8951 [(set (reg FLAGS_REG)
8954 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8955 (match_operand:QI 1 "general_operand" "n,n,qn"))
8957 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8958 && ix86_match_ccmode (insn, CCNOmode)"
8959 "test{b}\t{%1, %0|%0, %1}"
8960 [(set_attr "type" "test")
8961 (set_attr "modrm" "0,1,1")
8962 (set_attr "mode" "QI")
8963 (set_attr "pent_pair" "uv,np,uv")])
8965 (define_expand "testqi_ext_ccno_0"
8966 [(set (reg:CCNO FLAGS_REG)
8970 (match_operand 0 "ext_register_operand" "")
8973 (match_operand 1 "const_int_operand" ""))
8978 (define_insn "*testqi_ext_0"
8979 [(set (reg FLAGS_REG)
8983 (match_operand 0 "ext_register_operand" "Q")
8986 (match_operand 1 "const_int_operand" "n"))
8988 "ix86_match_ccmode (insn, CCNOmode)"
8989 "test{b}\t{%1, %h0|%h0, %1}"
8990 [(set_attr "type" "test")
8991 (set_attr "mode" "QI")
8992 (set_attr "length_immediate" "1")
8993 (set_attr "pent_pair" "np")])
8995 (define_insn "*testqi_ext_1"
8996 [(set (reg FLAGS_REG)
9000 (match_operand 0 "ext_register_operand" "Q")
9004 (match_operand:QI 1 "general_operand" "Qm")))
9006 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9008 "test{b}\t{%1, %h0|%h0, %1}"
9009 [(set_attr "type" "test")
9010 (set_attr "mode" "QI")])
9012 (define_insn "*testqi_ext_1_rex64"
9013 [(set (reg FLAGS_REG)
9017 (match_operand 0 "ext_register_operand" "Q")
9021 (match_operand:QI 1 "register_operand" "Q")))
9023 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9024 "test{b}\t{%1, %h0|%h0, %1}"
9025 [(set_attr "type" "test")
9026 (set_attr "mode" "QI")])
9028 (define_insn "*testqi_ext_2"
9029 [(set (reg FLAGS_REG)
9033 (match_operand 0 "ext_register_operand" "Q")
9037 (match_operand 1 "ext_register_operand" "Q")
9041 "ix86_match_ccmode (insn, CCNOmode)"
9042 "test{b}\t{%h1, %h0|%h0, %h1}"
9043 [(set_attr "type" "test")
9044 (set_attr "mode" "QI")])
9046 ;; Combine likes to form bit extractions for some tests. Humor it.
9047 (define_insn "*testqi_ext_3"
9048 [(set (reg FLAGS_REG)
9049 (compare (zero_extract:SI
9050 (match_operand 0 "nonimmediate_operand" "rm")
9051 (match_operand:SI 1 "const_int_operand" "")
9052 (match_operand:SI 2 "const_int_operand" ""))
9054 "ix86_match_ccmode (insn, CCNOmode)
9055 && INTVAL (operands[1]) > 0
9056 && INTVAL (operands[2]) >= 0
9057 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9058 && (GET_MODE (operands[0]) == SImode
9059 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9060 || GET_MODE (operands[0]) == HImode
9061 || GET_MODE (operands[0]) == QImode)"
9064 (define_insn "*testqi_ext_3_rex64"
9065 [(set (reg FLAGS_REG)
9066 (compare (zero_extract:DI
9067 (match_operand 0 "nonimmediate_operand" "rm")
9068 (match_operand:DI 1 "const_int_operand" "")
9069 (match_operand:DI 2 "const_int_operand" ""))
9072 && ix86_match_ccmode (insn, CCNOmode)
9073 && INTVAL (operands[1]) > 0
9074 && INTVAL (operands[2]) >= 0
9075 /* Ensure that resulting mask is zero or sign extended operand. */
9076 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9077 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9078 && INTVAL (operands[1]) > 32))
9079 && (GET_MODE (operands[0]) == SImode
9080 || GET_MODE (operands[0]) == DImode
9081 || GET_MODE (operands[0]) == HImode
9082 || GET_MODE (operands[0]) == QImode)"
9086 [(set (match_operand 0 "flags_reg_operand" "")
9087 (match_operator 1 "compare_operator"
9089 (match_operand 2 "nonimmediate_operand" "")
9090 (match_operand 3 "const_int_operand" "")
9091 (match_operand 4 "const_int_operand" ""))
9093 "ix86_match_ccmode (insn, CCNOmode)"
9094 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9096 rtx val = operands[2];
9097 HOST_WIDE_INT len = INTVAL (operands[3]);
9098 HOST_WIDE_INT pos = INTVAL (operands[4]);
9100 enum machine_mode mode, submode;
9102 mode = GET_MODE (val);
9105 /* ??? Combine likes to put non-volatile mem extractions in QImode
9106 no matter the size of the test. So find a mode that works. */
9107 if (! MEM_VOLATILE_P (val))
9109 mode = smallest_mode_for_size (pos + len, MODE_INT);
9110 val = adjust_address (val, mode, 0);
9113 else if (GET_CODE (val) == SUBREG
9114 && (submode = GET_MODE (SUBREG_REG (val)),
9115 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9116 && pos + len <= GET_MODE_BITSIZE (submode))
9118 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9120 val = SUBREG_REG (val);
9122 else if (mode == HImode && pos + len <= 8)
9124 /* Small HImode tests can be converted to QImode. */
9126 val = gen_lowpart (QImode, val);
9129 if (len == HOST_BITS_PER_WIDE_INT)
9132 mask = ((HOST_WIDE_INT)1 << len) - 1;
9135 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9138 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9139 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9140 ;; this is relatively important trick.
9141 ;; Do the conversion only post-reload to avoid limiting of the register class
9144 [(set (match_operand 0 "flags_reg_operand" "")
9145 (match_operator 1 "compare_operator"
9146 [(and (match_operand 2 "register_operand" "")
9147 (match_operand 3 "const_int_operand" ""))
9150 && QI_REG_P (operands[2])
9151 && GET_MODE (operands[2]) != QImode
9152 && ((ix86_match_ccmode (insn, CCZmode)
9153 && !(INTVAL (operands[3]) & ~(255 << 8)))
9154 || (ix86_match_ccmode (insn, CCNOmode)
9155 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9158 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9161 "operands[2] = gen_lowpart (SImode, operands[2]);
9162 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9165 [(set (match_operand 0 "flags_reg_operand" "")
9166 (match_operator 1 "compare_operator"
9167 [(and (match_operand 2 "nonimmediate_operand" "")
9168 (match_operand 3 "const_int_operand" ""))
9171 && GET_MODE (operands[2]) != QImode
9172 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9173 && ((ix86_match_ccmode (insn, CCZmode)
9174 && !(INTVAL (operands[3]) & ~255))
9175 || (ix86_match_ccmode (insn, CCNOmode)
9176 && !(INTVAL (operands[3]) & ~127)))"
9178 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9180 "operands[2] = gen_lowpart (QImode, operands[2]);
9181 operands[3] = gen_lowpart (QImode, operands[3]);")
9184 ;; %%% This used to optimize known byte-wide and operations to memory,
9185 ;; and sometimes to QImode registers. If this is considered useful,
9186 ;; it should be done with splitters.
9188 (define_expand "anddi3"
9189 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9190 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9191 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9193 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9195 (define_insn "*anddi_1_rex64"
9196 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9197 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9198 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9202 switch (get_attr_type (insn))
9206 enum machine_mode mode;
9208 gcc_assert (CONST_INT_P (operands[2]));
9209 if (INTVAL (operands[2]) == 0xff)
9213 gcc_assert (INTVAL (operands[2]) == 0xffff);
9217 operands[1] = gen_lowpart (mode, operands[1]);
9219 return "movz{bq|x}\t{%1,%0|%0, %1}";
9221 return "movz{wq|x}\t{%1,%0|%0, %1}";
9225 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9226 if (get_attr_mode (insn) == MODE_SI)
9227 return "and{l}\t{%k2, %k0|%k0, %k2}";
9229 return "and{q}\t{%2, %0|%0, %2}";
9232 [(set_attr "type" "alu,alu,alu,imovx")
9233 (set_attr "length_immediate" "*,*,*,0")
9234 (set_attr "mode" "SI,DI,DI,DI")])
9236 (define_insn "*anddi_2"
9237 [(set (reg FLAGS_REG)
9238 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9239 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9241 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9242 (and:DI (match_dup 1) (match_dup 2)))]
9243 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9244 && ix86_binary_operator_ok (AND, DImode, operands)"
9246 and{l}\t{%k2, %k0|%k0, %k2}
9247 and{q}\t{%2, %0|%0, %2}
9248 and{q}\t{%2, %0|%0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "SI,DI,DI")])
9252 (define_expand "andsi3"
9253 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9254 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9255 (match_operand:SI 2 "general_operand" "")))]
9257 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9259 (define_insn "*andsi_1"
9260 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9261 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9262 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9263 (clobber (reg:CC FLAGS_REG))]
9264 "ix86_binary_operator_ok (AND, SImode, operands)"
9266 switch (get_attr_type (insn))
9270 enum machine_mode mode;
9272 gcc_assert (CONST_INT_P (operands[2]));
9273 if (INTVAL (operands[2]) == 0xff)
9277 gcc_assert (INTVAL (operands[2]) == 0xffff);
9281 operands[1] = gen_lowpart (mode, operands[1]);
9283 return "movz{bl|x}\t{%1,%0|%0, %1}";
9285 return "movz{wl|x}\t{%1,%0|%0, %1}";
9289 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9290 return "and{l}\t{%2, %0|%0, %2}";
9293 [(set_attr "type" "alu,alu,imovx")
9294 (set_attr "length_immediate" "*,*,0")
9295 (set_attr "mode" "SI")])
9298 [(set (match_operand 0 "register_operand" "")
9300 (const_int -65536)))
9301 (clobber (reg:CC FLAGS_REG))]
9302 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9303 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9304 "operands[1] = gen_lowpart (HImode, operands[0]);")
9307 [(set (match_operand 0 "ext_register_operand" "")
9310 (clobber (reg:CC FLAGS_REG))]
9311 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9312 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9313 "operands[1] = gen_lowpart (QImode, operands[0]);")
9316 [(set (match_operand 0 "ext_register_operand" "")
9318 (const_int -65281)))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9321 [(parallel [(set (zero_extract:SI (match_dup 0)
9325 (zero_extract:SI (match_dup 0)
9328 (zero_extract:SI (match_dup 0)
9331 (clobber (reg:CC FLAGS_REG))])]
9332 "operands[0] = gen_lowpart (SImode, operands[0]);")
9334 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9335 (define_insn "*andsi_1_zext"
9336 [(set (match_operand:DI 0 "register_operand" "=r")
9338 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9339 (match_operand:SI 2 "general_operand" "g"))))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9342 "and{l}\t{%2, %k0|%k0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "SI")])
9346 (define_insn "*andsi_2"
9347 [(set (reg FLAGS_REG)
9348 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9349 (match_operand:SI 2 "general_operand" "g,ri"))
9351 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9352 (and:SI (match_dup 1) (match_dup 2)))]
9353 "ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (AND, SImode, operands)"
9355 "and{l}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9360 (define_insn "*andsi_2_zext"
9361 [(set (reg FLAGS_REG)
9362 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363 (match_operand:SI 2 "general_operand" "g"))
9365 (set (match_operand:DI 0 "register_operand" "=r")
9366 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9367 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368 && ix86_binary_operator_ok (AND, SImode, operands)"
9369 "and{l}\t{%2, %k0|%k0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "SI")])
9373 (define_expand "andhi3"
9374 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9375 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9376 (match_operand:HI 2 "general_operand" "")))]
9377 "TARGET_HIMODE_MATH"
9378 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9380 (define_insn "*andhi_1"
9381 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9382 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9383 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9384 (clobber (reg:CC FLAGS_REG))]
9385 "ix86_binary_operator_ok (AND, HImode, operands)"
9387 switch (get_attr_type (insn))
9390 gcc_assert (CONST_INT_P (operands[2]));
9391 gcc_assert (INTVAL (operands[2]) == 0xff);
9392 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9395 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9397 return "and{w}\t{%2, %0|%0, %2}";
9400 [(set_attr "type" "alu,alu,imovx")
9401 (set_attr "length_immediate" "*,*,0")
9402 (set_attr "mode" "HI,HI,SI")])
9404 (define_insn "*andhi_2"
9405 [(set (reg FLAGS_REG)
9406 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9407 (match_operand:HI 2 "general_operand" "rmn,rn"))
9409 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9410 (and:HI (match_dup 1) (match_dup 2)))]
9411 "ix86_match_ccmode (insn, CCNOmode)
9412 && ix86_binary_operator_ok (AND, HImode, operands)"
9413 "and{w}\t{%2, %0|%0, %2}"
9414 [(set_attr "type" "alu")
9415 (set_attr "mode" "HI")])
9417 (define_expand "andqi3"
9418 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9419 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9420 (match_operand:QI 2 "general_operand" "")))]
9421 "TARGET_QIMODE_MATH"
9422 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9424 ;; %%% Potential partial reg stall on alternative 2. What to do?
9425 (define_insn "*andqi_1"
9426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9427 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9428 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "ix86_binary_operator_ok (AND, QImode, operands)"
9432 and{b}\t{%2, %0|%0, %2}
9433 and{b}\t{%2, %0|%0, %2}
9434 and{l}\t{%k2, %k0|%k0, %k2}"
9435 [(set_attr "type" "alu")
9436 (set_attr "mode" "QI,QI,SI")])
9438 (define_insn "*andqi_1_slp"
9439 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9440 (and:QI (match_dup 0)
9441 (match_operand:QI 1 "general_operand" "qn,qmn")))
9442 (clobber (reg:CC FLAGS_REG))]
9443 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9445 "and{b}\t{%1, %0|%0, %1}"
9446 [(set_attr "type" "alu1")
9447 (set_attr "mode" "QI")])
9449 (define_insn "*andqi_2_maybe_si"
9450 [(set (reg FLAGS_REG)
9452 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9455 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9456 (and:QI (match_dup 1) (match_dup 2)))]
9457 "ix86_binary_operator_ok (AND, QImode, operands)
9458 && ix86_match_ccmode (insn,
9459 CONST_INT_P (operands[2])
9460 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9462 if (which_alternative == 2)
9464 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9465 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9466 return "and{l}\t{%2, %k0|%k0, %2}";
9468 return "and{b}\t{%2, %0|%0, %2}";
9470 [(set_attr "type" "alu")
9471 (set_attr "mode" "QI,QI,SI")])
9473 (define_insn "*andqi_2"
9474 [(set (reg FLAGS_REG)
9476 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9477 (match_operand:QI 2 "general_operand" "qmn,qn"))
9479 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9480 (and:QI (match_dup 1) (match_dup 2)))]
9481 "ix86_match_ccmode (insn, CCNOmode)
9482 && ix86_binary_operator_ok (AND, QImode, operands)"
9483 "and{b}\t{%2, %0|%0, %2}"
9484 [(set_attr "type" "alu")
9485 (set_attr "mode" "QI")])
9487 (define_insn "*andqi_2_slp"
9488 [(set (reg FLAGS_REG)
9490 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9491 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9493 (set (strict_low_part (match_dup 0))
9494 (and:QI (match_dup 0) (match_dup 1)))]
9495 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9496 && ix86_match_ccmode (insn, CCNOmode)
9497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9498 "and{b}\t{%1, %0|%0, %1}"
9499 [(set_attr "type" "alu1")
9500 (set_attr "mode" "QI")])
9502 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9503 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9504 ;; for a QImode operand, which of course failed.
9506 (define_insn "andqi_ext_0"
9507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512 (match_operand 1 "ext_register_operand" "0")
9515 (match_operand 2 "const_int_operand" "n")))
9516 (clobber (reg:CC FLAGS_REG))]
9518 "and{b}\t{%2, %h0|%h0, %2}"
9519 [(set_attr "type" "alu")
9520 (set_attr "length_immediate" "1")
9521 (set_attr "mode" "QI")])
9523 ;; Generated by peephole translating test to and. This shows up
9524 ;; often in fp comparisons.
9526 (define_insn "*andqi_ext_0_cc"
9527 [(set (reg FLAGS_REG)
9531 (match_operand 1 "ext_register_operand" "0")
9534 (match_operand 2 "const_int_operand" "n"))
9536 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9545 "ix86_match_ccmode (insn, CCNOmode)"
9546 "and{b}\t{%2, %h0|%h0, %2}"
9547 [(set_attr "type" "alu")
9548 (set_attr "length_immediate" "1")
9549 (set_attr "mode" "QI")])
9551 (define_insn "*andqi_ext_1"
9552 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9557 (match_operand 1 "ext_register_operand" "0")
9561 (match_operand:QI 2 "general_operand" "Qm"))))
9562 (clobber (reg:CC FLAGS_REG))]
9564 "and{b}\t{%2, %h0|%h0, %2}"
9565 [(set_attr "type" "alu")
9566 (set_attr "length_immediate" "0")
9567 (set_attr "mode" "QI")])
9569 (define_insn "*andqi_ext_1_rex64"
9570 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9575 (match_operand 1 "ext_register_operand" "0")
9579 (match_operand 2 "ext_register_operand" "Q"))))
9580 (clobber (reg:CC FLAGS_REG))]
9582 "and{b}\t{%2, %h0|%h0, %2}"
9583 [(set_attr "type" "alu")
9584 (set_attr "length_immediate" "0")
9585 (set_attr "mode" "QI")])
9587 (define_insn "*andqi_ext_2"
9588 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9593 (match_operand 1 "ext_register_operand" "%0")
9597 (match_operand 2 "ext_register_operand" "Q")
9600 (clobber (reg:CC FLAGS_REG))]
9602 "and{b}\t{%h2, %h0|%h0, %h2}"
9603 [(set_attr "type" "alu")
9604 (set_attr "length_immediate" "0")
9605 (set_attr "mode" "QI")])
9607 ;; Convert wide AND instructions with immediate operand to shorter QImode
9608 ;; equivalents when possible.
9609 ;; Don't do the splitting with memory operands, since it introduces risk
9610 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9611 ;; for size, but that can (should?) be handled by generic code instead.
9613 [(set (match_operand 0 "register_operand" "")
9614 (and (match_operand 1 "register_operand" "")
9615 (match_operand 2 "const_int_operand" "")))
9616 (clobber (reg:CC FLAGS_REG))]
9618 && QI_REG_P (operands[0])
9619 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9620 && !(~INTVAL (operands[2]) & ~(255 << 8))
9621 && GET_MODE (operands[0]) != QImode"
9622 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9623 (and:SI (zero_extract:SI (match_dup 1)
9624 (const_int 8) (const_int 8))
9626 (clobber (reg:CC FLAGS_REG))])]
9627 "operands[0] = gen_lowpart (SImode, operands[0]);
9628 operands[1] = gen_lowpart (SImode, operands[1]);
9629 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9631 ;; Since AND can be encoded with sign extended immediate, this is only
9632 ;; profitable when 7th bit is not set.
9634 [(set (match_operand 0 "register_operand" "")
9635 (and (match_operand 1 "general_operand" "")
9636 (match_operand 2 "const_int_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))]
9639 && ANY_QI_REG_P (operands[0])
9640 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9641 && !(~INTVAL (operands[2]) & ~255)
9642 && !(INTVAL (operands[2]) & 128)
9643 && GET_MODE (operands[0]) != QImode"
9644 [(parallel [(set (strict_low_part (match_dup 0))
9645 (and:QI (match_dup 1)
9647 (clobber (reg:CC FLAGS_REG))])]
9648 "operands[0] = gen_lowpart (QImode, operands[0]);
9649 operands[1] = gen_lowpart (QImode, operands[1]);
9650 operands[2] = gen_lowpart (QImode, operands[2]);")
9652 ;; Logical inclusive OR instructions
9654 ;; %%% This used to optimize known byte-wide and operations to memory.
9655 ;; If this is considered useful, it should be done with splitters.
9657 (define_expand "iordi3"
9658 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9659 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9660 (match_operand:DI 2 "x86_64_general_operand" "")))]
9662 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9664 (define_insn "*iordi_1_rex64"
9665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9666 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9667 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9668 (clobber (reg:CC FLAGS_REG))]
9670 && ix86_binary_operator_ok (IOR, DImode, operands)"
9671 "or{q}\t{%2, %0|%0, %2}"
9672 [(set_attr "type" "alu")
9673 (set_attr "mode" "DI")])
9675 (define_insn "*iordi_2_rex64"
9676 [(set (reg FLAGS_REG)
9677 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9678 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9680 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9681 (ior:DI (match_dup 1) (match_dup 2)))]
9683 && ix86_match_ccmode (insn, CCNOmode)
9684 && ix86_binary_operator_ok (IOR, DImode, operands)"
9685 "or{q}\t{%2, %0|%0, %2}"
9686 [(set_attr "type" "alu")
9687 (set_attr "mode" "DI")])
9689 (define_insn "*iordi_3_rex64"
9690 [(set (reg FLAGS_REG)
9691 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9692 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9694 (clobber (match_scratch:DI 0 "=r"))]
9696 && ix86_match_ccmode (insn, CCNOmode)
9697 && ix86_binary_operator_ok (IOR, DImode, operands)"
9698 "or{q}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "alu")
9700 (set_attr "mode" "DI")])
9703 (define_expand "iorsi3"
9704 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9705 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9706 (match_operand:SI 2 "general_operand" "")))]
9708 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9710 (define_insn "*iorsi_1"
9711 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9712 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9713 (match_operand:SI 2 "general_operand" "ri,g")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (IOR, SImode, operands)"
9716 "or{l}\t{%2, %0|%0, %2}"
9717 [(set_attr "type" "alu")
9718 (set_attr "mode" "SI")])
9720 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9721 (define_insn "*iorsi_1_zext"
9722 [(set (match_operand:DI 0 "register_operand" "=r")
9724 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9725 (match_operand:SI 2 "general_operand" "g"))))
9726 (clobber (reg:CC FLAGS_REG))]
9727 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9728 "or{l}\t{%2, %k0|%k0, %2}"
9729 [(set_attr "type" "alu")
9730 (set_attr "mode" "SI")])
9732 (define_insn "*iorsi_1_zext_imm"
9733 [(set (match_operand:DI 0 "register_operand" "=r")
9734 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9735 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9736 (clobber (reg:CC FLAGS_REG))]
9738 "or{l}\t{%2, %k0|%k0, %2}"
9739 [(set_attr "type" "alu")
9740 (set_attr "mode" "SI")])
9742 (define_insn "*iorsi_2"
9743 [(set (reg FLAGS_REG)
9744 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9745 (match_operand:SI 2 "general_operand" "g,ri"))
9747 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9748 (ior:SI (match_dup 1) (match_dup 2)))]
9749 "ix86_match_ccmode (insn, CCNOmode)
9750 && ix86_binary_operator_ok (IOR, SImode, operands)"
9751 "or{l}\t{%2, %0|%0, %2}"
9752 [(set_attr "type" "alu")
9753 (set_attr "mode" "SI")])
9755 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9756 ;; ??? Special case for immediate operand is missing - it is tricky.
9757 (define_insn "*iorsi_2_zext"
9758 [(set (reg FLAGS_REG)
9759 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9760 (match_operand:SI 2 "general_operand" "g"))
9762 (set (match_operand:DI 0 "register_operand" "=r")
9763 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9764 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9765 && ix86_binary_operator_ok (IOR, SImode, operands)"
9766 "or{l}\t{%2, %k0|%k0, %2}"
9767 [(set_attr "type" "alu")
9768 (set_attr "mode" "SI")])
9770 (define_insn "*iorsi_2_zext_imm"
9771 [(set (reg FLAGS_REG)
9772 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9773 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9775 (set (match_operand:DI 0 "register_operand" "=r")
9776 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9777 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9778 && ix86_binary_operator_ok (IOR, SImode, operands)"
9779 "or{l}\t{%2, %k0|%k0, %2}"
9780 [(set_attr "type" "alu")
9781 (set_attr "mode" "SI")])
9783 (define_insn "*iorsi_3"
9784 [(set (reg FLAGS_REG)
9785 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9786 (match_operand:SI 2 "general_operand" "g"))
9788 (clobber (match_scratch:SI 0 "=r"))]
9789 "ix86_match_ccmode (insn, CCNOmode)
9790 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9791 "or{l}\t{%2, %0|%0, %2}"
9792 [(set_attr "type" "alu")
9793 (set_attr "mode" "SI")])
9795 (define_expand "iorhi3"
9796 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9797 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9798 (match_operand:HI 2 "general_operand" "")))]
9799 "TARGET_HIMODE_MATH"
9800 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9802 (define_insn "*iorhi_1"
9803 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9804 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9805 (match_operand:HI 2 "general_operand" "rmn,rn")))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "ix86_binary_operator_ok (IOR, HImode, operands)"
9808 "or{w}\t{%2, %0|%0, %2}"
9809 [(set_attr "type" "alu")
9810 (set_attr "mode" "HI")])
9812 (define_insn "*iorhi_2"
9813 [(set (reg FLAGS_REG)
9814 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9815 (match_operand:HI 2 "general_operand" "rmn,rn"))
9817 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9818 (ior:HI (match_dup 1) (match_dup 2)))]
9819 "ix86_match_ccmode (insn, CCNOmode)
9820 && ix86_binary_operator_ok (IOR, HImode, operands)"
9821 "or{w}\t{%2, %0|%0, %2}"
9822 [(set_attr "type" "alu")
9823 (set_attr "mode" "HI")])
9825 (define_insn "*iorhi_3"
9826 [(set (reg FLAGS_REG)
9827 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9828 (match_operand:HI 2 "general_operand" "rmn"))
9830 (clobber (match_scratch:HI 0 "=r"))]
9831 "ix86_match_ccmode (insn, CCNOmode)
9832 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9833 "or{w}\t{%2, %0|%0, %2}"
9834 [(set_attr "type" "alu")
9835 (set_attr "mode" "HI")])
9837 (define_expand "iorqi3"
9838 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9839 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9840 (match_operand:QI 2 "general_operand" "")))]
9841 "TARGET_QIMODE_MATH"
9842 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9844 ;; %%% Potential partial reg stall on alternative 2. What to do?
9845 (define_insn "*iorqi_1"
9846 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9847 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9848 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "ix86_binary_operator_ok (IOR, QImode, operands)"
9852 or{b}\t{%2, %0|%0, %2}
9853 or{b}\t{%2, %0|%0, %2}
9854 or{l}\t{%k2, %k0|%k0, %k2}"
9855 [(set_attr "type" "alu")
9856 (set_attr "mode" "QI,QI,SI")])
9858 (define_insn "*iorqi_1_slp"
9859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9860 (ior:QI (match_dup 0)
9861 (match_operand:QI 1 "general_operand" "qmn,qn")))
9862 (clobber (reg:CC FLAGS_REG))]
9863 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9864 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9865 "or{b}\t{%1, %0|%0, %1}"
9866 [(set_attr "type" "alu1")
9867 (set_attr "mode" "QI")])
9869 (define_insn "*iorqi_2"
9870 [(set (reg FLAGS_REG)
9871 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9872 (match_operand:QI 2 "general_operand" "qmn,qn"))
9874 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9875 (ior:QI (match_dup 1) (match_dup 2)))]
9876 "ix86_match_ccmode (insn, CCNOmode)
9877 && ix86_binary_operator_ok (IOR, QImode, operands)"
9878 "or{b}\t{%2, %0|%0, %2}"
9879 [(set_attr "type" "alu")
9880 (set_attr "mode" "QI")])
9882 (define_insn "*iorqi_2_slp"
9883 [(set (reg FLAGS_REG)
9884 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9885 (match_operand:QI 1 "general_operand" "qmn,qn"))
9887 (set (strict_low_part (match_dup 0))
9888 (ior:QI (match_dup 0) (match_dup 1)))]
9889 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9890 && ix86_match_ccmode (insn, CCNOmode)
9891 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9892 "or{b}\t{%1, %0|%0, %1}"
9893 [(set_attr "type" "alu1")
9894 (set_attr "mode" "QI")])
9896 (define_insn "*iorqi_3"
9897 [(set (reg FLAGS_REG)
9898 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9899 (match_operand:QI 2 "general_operand" "qmn"))
9901 (clobber (match_scratch:QI 0 "=q"))]
9902 "ix86_match_ccmode (insn, CCNOmode)
9903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904 "or{b}\t{%2, %0|%0, %2}"
9905 [(set_attr "type" "alu")
9906 (set_attr "mode" "QI")])
9908 (define_insn "*iorqi_ext_0"
9909 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9914 (match_operand 1 "ext_register_operand" "0")
9917 (match_operand 2 "const_int_operand" "n")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9920 "or{b}\t{%2, %h0|%h0, %2}"
9921 [(set_attr "type" "alu")
9922 (set_attr "length_immediate" "1")
9923 (set_attr "mode" "QI")])
9925 (define_insn "*iorqi_ext_1"
9926 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9931 (match_operand 1 "ext_register_operand" "0")
9935 (match_operand:QI 2 "general_operand" "Qm"))))
9936 (clobber (reg:CC FLAGS_REG))]
9938 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9939 "or{b}\t{%2, %h0|%h0, %2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "length_immediate" "0")
9942 (set_attr "mode" "QI")])
9944 (define_insn "*iorqi_ext_1_rex64"
9945 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9950 (match_operand 1 "ext_register_operand" "0")
9954 (match_operand 2 "ext_register_operand" "Q"))))
9955 (clobber (reg:CC FLAGS_REG))]
9957 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9958 "or{b}\t{%2, %h0|%h0, %2}"
9959 [(set_attr "type" "alu")
9960 (set_attr "length_immediate" "0")
9961 (set_attr "mode" "QI")])
9963 (define_insn "*iorqi_ext_2"
9964 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9968 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9971 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9974 (clobber (reg:CC FLAGS_REG))]
9975 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9976 "ior{b}\t{%h2, %h0|%h0, %h2}"
9977 [(set_attr "type" "alu")
9978 (set_attr "length_immediate" "0")
9979 (set_attr "mode" "QI")])
9982 [(set (match_operand 0 "register_operand" "")
9983 (ior (match_operand 1 "register_operand" "")
9984 (match_operand 2 "const_int_operand" "")))
9985 (clobber (reg:CC FLAGS_REG))]
9987 && QI_REG_P (operands[0])
9988 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9989 && !(INTVAL (operands[2]) & ~(255 << 8))
9990 && GET_MODE (operands[0]) != QImode"
9991 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9992 (ior:SI (zero_extract:SI (match_dup 1)
9993 (const_int 8) (const_int 8))
9995 (clobber (reg:CC FLAGS_REG))])]
9996 "operands[0] = gen_lowpart (SImode, operands[0]);
9997 operands[1] = gen_lowpart (SImode, operands[1]);
9998 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10000 ;; Since OR can be encoded with sign extended immediate, this is only
10001 ;; profitable when 7th bit is set.
10003 [(set (match_operand 0 "register_operand" "")
10004 (ior (match_operand 1 "general_operand" "")
10005 (match_operand 2 "const_int_operand" "")))
10006 (clobber (reg:CC FLAGS_REG))]
10008 && ANY_QI_REG_P (operands[0])
10009 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10010 && !(INTVAL (operands[2]) & ~255)
10011 && (INTVAL (operands[2]) & 128)
10012 && GET_MODE (operands[0]) != QImode"
10013 [(parallel [(set (strict_low_part (match_dup 0))
10014 (ior:QI (match_dup 1)
10016 (clobber (reg:CC FLAGS_REG))])]
10017 "operands[0] = gen_lowpart (QImode, operands[0]);
10018 operands[1] = gen_lowpart (QImode, operands[1]);
10019 operands[2] = gen_lowpart (QImode, operands[2]);")
10021 ;; Logical XOR instructions
10023 ;; %%% This used to optimize known byte-wide and operations to memory.
10024 ;; If this is considered useful, it should be done with splitters.
10026 (define_expand "xordi3"
10027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10028 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10029 (match_operand:DI 2 "x86_64_general_operand" "")))]
10031 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10033 (define_insn "*xordi_1_rex64"
10034 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10035 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10036 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10037 (clobber (reg:CC FLAGS_REG))]
10039 && ix86_binary_operator_ok (XOR, DImode, operands)"
10040 "xor{q}\t{%2, %0|%0, %2}"
10041 [(set_attr "type" "alu")
10042 (set_attr "mode" "DI")])
10044 (define_insn "*xordi_2_rex64"
10045 [(set (reg FLAGS_REG)
10046 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10047 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10049 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10050 (xor:DI (match_dup 1) (match_dup 2)))]
10052 && ix86_match_ccmode (insn, CCNOmode)
10053 && ix86_binary_operator_ok (XOR, DImode, operands)"
10054 "xor{q}\t{%2, %0|%0, %2}"
10055 [(set_attr "type" "alu")
10056 (set_attr "mode" "DI")])
10058 (define_insn "*xordi_3_rex64"
10059 [(set (reg FLAGS_REG)
10060 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10061 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10063 (clobber (match_scratch:DI 0 "=r"))]
10065 && ix86_match_ccmode (insn, CCNOmode)
10066 && ix86_binary_operator_ok (XOR, DImode, operands)"
10067 "xor{q}\t{%2, %0|%0, %2}"
10068 [(set_attr "type" "alu")
10069 (set_attr "mode" "DI")])
10071 (define_expand "xorsi3"
10072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10073 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10074 (match_operand:SI 2 "general_operand" "")))]
10076 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10078 (define_insn "*xorsi_1"
10079 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10080 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10081 (match_operand:SI 2 "general_operand" "ri,rm")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "ix86_binary_operator_ok (XOR, SImode, operands)"
10084 "xor{l}\t{%2, %0|%0, %2}"
10085 [(set_attr "type" "alu")
10086 (set_attr "mode" "SI")])
10088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10089 ;; Add speccase for immediates
10090 (define_insn "*xorsi_1_zext"
10091 [(set (match_operand:DI 0 "register_operand" "=r")
10093 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10094 (match_operand:SI 2 "general_operand" "g"))))
10095 (clobber (reg:CC FLAGS_REG))]
10096 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10097 "xor{l}\t{%2, %k0|%k0, %2}"
10098 [(set_attr "type" "alu")
10099 (set_attr "mode" "SI")])
10101 (define_insn "*xorsi_1_zext_imm"
10102 [(set (match_operand:DI 0 "register_operand" "=r")
10103 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10104 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10105 (clobber (reg:CC FLAGS_REG))]
10106 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10107 "xor{l}\t{%2, %k0|%k0, %2}"
10108 [(set_attr "type" "alu")
10109 (set_attr "mode" "SI")])
10111 (define_insn "*xorsi_2"
10112 [(set (reg FLAGS_REG)
10113 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10114 (match_operand:SI 2 "general_operand" "g,ri"))
10116 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10117 (xor:SI (match_dup 1) (match_dup 2)))]
10118 "ix86_match_ccmode (insn, CCNOmode)
10119 && ix86_binary_operator_ok (XOR, SImode, operands)"
10120 "xor{l}\t{%2, %0|%0, %2}"
10121 [(set_attr "type" "alu")
10122 (set_attr "mode" "SI")])
10124 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10125 ;; ??? Special case for immediate operand is missing - it is tricky.
10126 (define_insn "*xorsi_2_zext"
10127 [(set (reg FLAGS_REG)
10128 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10129 (match_operand:SI 2 "general_operand" "g"))
10131 (set (match_operand:DI 0 "register_operand" "=r")
10132 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10134 && ix86_binary_operator_ok (XOR, SImode, operands)"
10135 "xor{l}\t{%2, %k0|%k0, %2}"
10136 [(set_attr "type" "alu")
10137 (set_attr "mode" "SI")])
10139 (define_insn "*xorsi_2_zext_imm"
10140 [(set (reg FLAGS_REG)
10141 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10142 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10144 (set (match_operand:DI 0 "register_operand" "=r")
10145 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10146 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10147 && ix86_binary_operator_ok (XOR, SImode, operands)"
10148 "xor{l}\t{%2, %k0|%k0, %2}"
10149 [(set_attr "type" "alu")
10150 (set_attr "mode" "SI")])
10152 (define_insn "*xorsi_3"
10153 [(set (reg FLAGS_REG)
10154 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10155 (match_operand:SI 2 "general_operand" "g"))
10157 (clobber (match_scratch:SI 0 "=r"))]
10158 "ix86_match_ccmode (insn, CCNOmode)
10159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10160 "xor{l}\t{%2, %0|%0, %2}"
10161 [(set_attr "type" "alu")
10162 (set_attr "mode" "SI")])
10164 (define_expand "xorhi3"
10165 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10166 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10167 (match_operand:HI 2 "general_operand" "")))]
10168 "TARGET_HIMODE_MATH"
10169 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10171 (define_insn "*xorhi_1"
10172 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10173 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10174 (match_operand:HI 2 "general_operand" "rmn,rn")))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "ix86_binary_operator_ok (XOR, HImode, operands)"
10177 "xor{w}\t{%2, %0|%0, %2}"
10178 [(set_attr "type" "alu")
10179 (set_attr "mode" "HI")])
10181 (define_insn "*xorhi_2"
10182 [(set (reg FLAGS_REG)
10183 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10184 (match_operand:HI 2 "general_operand" "rmn,rn"))
10186 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10187 (xor:HI (match_dup 1) (match_dup 2)))]
10188 "ix86_match_ccmode (insn, CCNOmode)
10189 && ix86_binary_operator_ok (XOR, HImode, operands)"
10190 "xor{w}\t{%2, %0|%0, %2}"
10191 [(set_attr "type" "alu")
10192 (set_attr "mode" "HI")])
10194 (define_insn "*xorhi_3"
10195 [(set (reg FLAGS_REG)
10196 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10197 (match_operand:HI 2 "general_operand" "rmn"))
10199 (clobber (match_scratch:HI 0 "=r"))]
10200 "ix86_match_ccmode (insn, CCNOmode)
10201 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10202 "xor{w}\t{%2, %0|%0, %2}"
10203 [(set_attr "type" "alu")
10204 (set_attr "mode" "HI")])
10206 (define_expand "xorqi3"
10207 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10208 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10209 (match_operand:QI 2 "general_operand" "")))]
10210 "TARGET_QIMODE_MATH"
10211 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10213 ;; %%% Potential partial reg stall on alternative 2. What to do?
10214 (define_insn "*xorqi_1"
10215 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10216 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10217 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "ix86_binary_operator_ok (XOR, QImode, operands)"
10221 xor{b}\t{%2, %0|%0, %2}
10222 xor{b}\t{%2, %0|%0, %2}
10223 xor{l}\t{%k2, %k0|%k0, %k2}"
10224 [(set_attr "type" "alu")
10225 (set_attr "mode" "QI,QI,SI")])
10227 (define_insn "*xorqi_1_slp"
10228 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10229 (xor:QI (match_dup 0)
10230 (match_operand:QI 1 "general_operand" "qn,qmn")))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10234 "xor{b}\t{%1, %0|%0, %1}"
10235 [(set_attr "type" "alu1")
10236 (set_attr "mode" "QI")])
10238 (define_insn "*xorqi_ext_0"
10239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10244 (match_operand 1 "ext_register_operand" "0")
10247 (match_operand 2 "const_int_operand" "n")))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10250 "xor{b}\t{%2, %h0|%h0, %2}"
10251 [(set_attr "type" "alu")
10252 (set_attr "length_immediate" "1")
10253 (set_attr "mode" "QI")])
10255 (define_insn "*xorqi_ext_1"
10256 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10261 (match_operand 1 "ext_register_operand" "0")
10265 (match_operand:QI 2 "general_operand" "Qm"))))
10266 (clobber (reg:CC FLAGS_REG))]
10268 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10269 "xor{b}\t{%2, %h0|%h0, %2}"
10270 [(set_attr "type" "alu")
10271 (set_attr "length_immediate" "0")
10272 (set_attr "mode" "QI")])
10274 (define_insn "*xorqi_ext_1_rex64"
10275 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10280 (match_operand 1 "ext_register_operand" "0")
10284 (match_operand 2 "ext_register_operand" "Q"))))
10285 (clobber (reg:CC FLAGS_REG))]
10287 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10288 "xor{b}\t{%2, %h0|%h0, %2}"
10289 [(set_attr "type" "alu")
10290 (set_attr "length_immediate" "0")
10291 (set_attr "mode" "QI")])
10293 (define_insn "*xorqi_ext_2"
10294 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10298 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10301 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10304 (clobber (reg:CC FLAGS_REG))]
10305 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10306 "xor{b}\t{%h2, %h0|%h0, %h2}"
10307 [(set_attr "type" "alu")
10308 (set_attr "length_immediate" "0")
10309 (set_attr "mode" "QI")])
10311 (define_insn "*xorqi_cc_1"
10312 [(set (reg FLAGS_REG)
10314 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10315 (match_operand:QI 2 "general_operand" "qmn,qn"))
10317 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10318 (xor:QI (match_dup 1) (match_dup 2)))]
10319 "ix86_match_ccmode (insn, CCNOmode)
10320 && ix86_binary_operator_ok (XOR, QImode, operands)"
10321 "xor{b}\t{%2, %0|%0, %2}"
10322 [(set_attr "type" "alu")
10323 (set_attr "mode" "QI")])
10325 (define_insn "*xorqi_2_slp"
10326 [(set (reg FLAGS_REG)
10327 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10328 (match_operand:QI 1 "general_operand" "qmn,qn"))
10330 (set (strict_low_part (match_dup 0))
10331 (xor:QI (match_dup 0) (match_dup 1)))]
10332 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333 && ix86_match_ccmode (insn, CCNOmode)
10334 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10335 "xor{b}\t{%1, %0|%0, %1}"
10336 [(set_attr "type" "alu1")
10337 (set_attr "mode" "QI")])
10339 (define_insn "*xorqi_cc_2"
10340 [(set (reg FLAGS_REG)
10342 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10343 (match_operand:QI 2 "general_operand" "qmn"))
10345 (clobber (match_scratch:QI 0 "=q"))]
10346 "ix86_match_ccmode (insn, CCNOmode)
10347 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10348 "xor{b}\t{%2, %0|%0, %2}"
10349 [(set_attr "type" "alu")
10350 (set_attr "mode" "QI")])
10352 (define_insn "*xorqi_cc_ext_1"
10353 [(set (reg FLAGS_REG)
10357 (match_operand 1 "ext_register_operand" "0")
10360 (match_operand:QI 2 "general_operand" "qmn"))
10362 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10366 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10368 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10369 "xor{b}\t{%2, %h0|%h0, %2}"
10370 [(set_attr "type" "alu")
10371 (set_attr "mode" "QI")])
10373 (define_insn "*xorqi_cc_ext_1_rex64"
10374 [(set (reg FLAGS_REG)
10378 (match_operand 1 "ext_register_operand" "0")
10381 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10383 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10387 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10389 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10390 "xor{b}\t{%2, %h0|%h0, %2}"
10391 [(set_attr "type" "alu")
10392 (set_attr "mode" "QI")])
10394 (define_expand "xorqi_cc_ext_1"
10396 (set (reg:CCNO FLAGS_REG)
10400 (match_operand 1 "ext_register_operand" "")
10403 (match_operand:QI 2 "general_operand" ""))
10405 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10409 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10415 [(set (match_operand 0 "register_operand" "")
10416 (xor (match_operand 1 "register_operand" "")
10417 (match_operand 2 "const_int_operand" "")))
10418 (clobber (reg:CC FLAGS_REG))]
10420 && QI_REG_P (operands[0])
10421 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10422 && !(INTVAL (operands[2]) & ~(255 << 8))
10423 && GET_MODE (operands[0]) != QImode"
10424 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10425 (xor:SI (zero_extract:SI (match_dup 1)
10426 (const_int 8) (const_int 8))
10428 (clobber (reg:CC FLAGS_REG))])]
10429 "operands[0] = gen_lowpart (SImode, operands[0]);
10430 operands[1] = gen_lowpart (SImode, operands[1]);
10431 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10433 ;; Since XOR can be encoded with sign extended immediate, this is only
10434 ;; profitable when 7th bit is set.
10436 [(set (match_operand 0 "register_operand" "")
10437 (xor (match_operand 1 "general_operand" "")
10438 (match_operand 2 "const_int_operand" "")))
10439 (clobber (reg:CC FLAGS_REG))]
10441 && ANY_QI_REG_P (operands[0])
10442 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10443 && !(INTVAL (operands[2]) & ~255)
10444 && (INTVAL (operands[2]) & 128)
10445 && GET_MODE (operands[0]) != QImode"
10446 [(parallel [(set (strict_low_part (match_dup 0))
10447 (xor:QI (match_dup 1)
10449 (clobber (reg:CC FLAGS_REG))])]
10450 "operands[0] = gen_lowpart (QImode, operands[0]);
10451 operands[1] = gen_lowpart (QImode, operands[1]);
10452 operands[2] = gen_lowpart (QImode, operands[2]);")
10454 ;; Negation instructions
10456 (define_expand "negti2"
10457 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10458 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10460 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10462 (define_insn "*negti2_1"
10463 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10464 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10465 (clobber (reg:CC FLAGS_REG))]
10467 && ix86_unary_operator_ok (NEG, TImode, operands)"
10471 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10472 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "TARGET_64BIT && reload_completed"
10476 [(set (reg:CCZ FLAGS_REG)
10477 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10478 (set (match_dup 0) (neg:DI (match_dup 1)))])
10480 [(set (match_dup 2)
10481 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10484 (clobber (reg:CC FLAGS_REG))])
10486 [(set (match_dup 2)
10487 (neg:DI (match_dup 2)))
10488 (clobber (reg:CC FLAGS_REG))])]
10489 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10491 (define_expand "negdi2"
10492 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10493 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10495 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10497 (define_insn "*negdi2_1"
10498 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10499 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10500 (clobber (reg:CC FLAGS_REG))]
10502 && ix86_unary_operator_ok (NEG, DImode, operands)"
10506 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10507 (neg:DI (match_operand:DI 1 "general_operand" "")))
10508 (clobber (reg:CC FLAGS_REG))]
10509 "!TARGET_64BIT && reload_completed"
10511 [(set (reg:CCZ FLAGS_REG)
10512 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10513 (set (match_dup 0) (neg:SI (match_dup 1)))])
10515 [(set (match_dup 2)
10516 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10519 (clobber (reg:CC FLAGS_REG))])
10521 [(set (match_dup 2)
10522 (neg:SI (match_dup 2)))
10523 (clobber (reg:CC FLAGS_REG))])]
10524 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10526 (define_insn "*negdi2_1_rex64"
10527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10528 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10529 (clobber (reg:CC FLAGS_REG))]
10530 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10532 [(set_attr "type" "negnot")
10533 (set_attr "mode" "DI")])
10535 ;; The problem with neg is that it does not perform (compare x 0),
10536 ;; it really performs (compare 0 x), which leaves us with the zero
10537 ;; flag being the only useful item.
10539 (define_insn "*negdi2_cmpz_rex64"
10540 [(set (reg:CCZ FLAGS_REG)
10541 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10543 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10544 (neg:DI (match_dup 1)))]
10545 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10547 [(set_attr "type" "negnot")
10548 (set_attr "mode" "DI")])
10551 (define_expand "negsi2"
10552 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10553 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10555 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10557 (define_insn "*negsi2_1"
10558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10559 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10560 (clobber (reg:CC FLAGS_REG))]
10561 "ix86_unary_operator_ok (NEG, SImode, operands)"
10563 [(set_attr "type" "negnot")
10564 (set_attr "mode" "SI")])
10566 ;; Combine is quite creative about this pattern.
10567 (define_insn "*negsi2_1_zext"
10568 [(set (match_operand:DI 0 "register_operand" "=r")
10569 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10572 (clobber (reg:CC FLAGS_REG))]
10573 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10575 [(set_attr "type" "negnot")
10576 (set_attr "mode" "SI")])
10578 ;; The problem with neg is that it does not perform (compare x 0),
10579 ;; it really performs (compare 0 x), which leaves us with the zero
10580 ;; flag being the only useful item.
10582 (define_insn "*negsi2_cmpz"
10583 [(set (reg:CCZ FLAGS_REG)
10584 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10586 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10587 (neg:SI (match_dup 1)))]
10588 "ix86_unary_operator_ok (NEG, SImode, operands)"
10590 [(set_attr "type" "negnot")
10591 (set_attr "mode" "SI")])
10593 (define_insn "*negsi2_cmpz_zext"
10594 [(set (reg:CCZ FLAGS_REG)
10595 (compare:CCZ (lshiftrt:DI
10597 (match_operand:DI 1 "register_operand" "0")
10601 (set (match_operand:DI 0 "register_operand" "=r")
10602 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10605 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10607 [(set_attr "type" "negnot")
10608 (set_attr "mode" "SI")])
10610 (define_expand "neghi2"
10611 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10612 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10613 "TARGET_HIMODE_MATH"
10614 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10616 (define_insn "*neghi2_1"
10617 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10618 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "ix86_unary_operator_ok (NEG, HImode, operands)"
10622 [(set_attr "type" "negnot")
10623 (set_attr "mode" "HI")])
10625 (define_insn "*neghi2_cmpz"
10626 [(set (reg:CCZ FLAGS_REG)
10627 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10629 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10630 (neg:HI (match_dup 1)))]
10631 "ix86_unary_operator_ok (NEG, HImode, operands)"
10633 [(set_attr "type" "negnot")
10634 (set_attr "mode" "HI")])
10636 (define_expand "negqi2"
10637 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10639 "TARGET_QIMODE_MATH"
10640 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10642 (define_insn "*negqi2_1"
10643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10644 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "ix86_unary_operator_ok (NEG, QImode, operands)"
10648 [(set_attr "type" "negnot")
10649 (set_attr "mode" "QI")])
10651 (define_insn "*negqi2_cmpz"
10652 [(set (reg:CCZ FLAGS_REG)
10653 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10655 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10656 (neg:QI (match_dup 1)))]
10657 "ix86_unary_operator_ok (NEG, QImode, operands)"
10659 [(set_attr "type" "negnot")
10660 (set_attr "mode" "QI")])
10662 ;; Changing of sign for FP values is doable using integer unit too.
10664 (define_expand "<code><mode>2"
10665 [(set (match_operand:X87MODEF 0 "register_operand" "")
10666 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10667 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10668 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10670 (define_insn "*absneg<mode>2_mixed"
10671 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10672 (match_operator:MODEF 3 "absneg_operator"
10673 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10674 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10675 (clobber (reg:CC FLAGS_REG))]
10676 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10679 (define_insn "*absneg<mode>2_sse"
10680 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10681 (match_operator:MODEF 3 "absneg_operator"
10682 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10683 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10684 (clobber (reg:CC FLAGS_REG))]
10685 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10688 (define_insn "*absneg<mode>2_i387"
10689 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10690 (match_operator:X87MODEF 3 "absneg_operator"
10691 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10692 (use (match_operand 2 "" ""))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10697 (define_expand "<code>tf2"
10698 [(set (match_operand:TF 0 "register_operand" "")
10699 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10701 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10703 (define_insn "*absnegtf2_sse"
10704 [(set (match_operand:TF 0 "register_operand" "=x,x")
10705 (match_operator:TF 3 "absneg_operator"
10706 [(match_operand:TF 1 "register_operand" "0,x")]))
10707 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10708 (clobber (reg:CC FLAGS_REG))]
10712 ;; Splitters for fp abs and neg.
10715 [(set (match_operand 0 "fp_register_operand" "")
10716 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10717 (use (match_operand 2 "" ""))
10718 (clobber (reg:CC FLAGS_REG))]
10720 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10723 [(set (match_operand 0 "register_operand" "")
10724 (match_operator 3 "absneg_operator"
10725 [(match_operand 1 "register_operand" "")]))
10726 (use (match_operand 2 "nonimmediate_operand" ""))
10727 (clobber (reg:CC FLAGS_REG))]
10728 "reload_completed && SSE_REG_P (operands[0])"
10729 [(set (match_dup 0) (match_dup 3))]
10731 enum machine_mode mode = GET_MODE (operands[0]);
10732 enum machine_mode vmode = GET_MODE (operands[2]);
10735 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10736 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10737 if (operands_match_p (operands[0], operands[2]))
10740 operands[1] = operands[2];
10743 if (GET_CODE (operands[3]) == ABS)
10744 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10746 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10751 [(set (match_operand:SF 0 "register_operand" "")
10752 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10753 (use (match_operand:V4SF 2 "" ""))
10754 (clobber (reg:CC FLAGS_REG))]
10756 [(parallel [(set (match_dup 0) (match_dup 1))
10757 (clobber (reg:CC FLAGS_REG))])]
10760 operands[0] = gen_lowpart (SImode, operands[0]);
10761 if (GET_CODE (operands[1]) == ABS)
10763 tmp = gen_int_mode (0x7fffffff, SImode);
10764 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10768 tmp = gen_int_mode (0x80000000, SImode);
10769 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10775 [(set (match_operand:DF 0 "register_operand" "")
10776 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10777 (use (match_operand 2 "" ""))
10778 (clobber (reg:CC FLAGS_REG))]
10780 [(parallel [(set (match_dup 0) (match_dup 1))
10781 (clobber (reg:CC FLAGS_REG))])]
10786 tmp = gen_lowpart (DImode, operands[0]);
10787 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10790 if (GET_CODE (operands[1]) == ABS)
10793 tmp = gen_rtx_NOT (DImode, tmp);
10797 operands[0] = gen_highpart (SImode, operands[0]);
10798 if (GET_CODE (operands[1]) == ABS)
10800 tmp = gen_int_mode (0x7fffffff, SImode);
10801 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10805 tmp = gen_int_mode (0x80000000, SImode);
10806 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10813 [(set (match_operand:XF 0 "register_operand" "")
10814 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10815 (use (match_operand 2 "" ""))
10816 (clobber (reg:CC FLAGS_REG))]
10818 [(parallel [(set (match_dup 0) (match_dup 1))
10819 (clobber (reg:CC FLAGS_REG))])]
10822 operands[0] = gen_rtx_REG (SImode,
10823 true_regnum (operands[0])
10824 + (TARGET_64BIT ? 1 : 2));
10825 if (GET_CODE (operands[1]) == ABS)
10827 tmp = GEN_INT (0x7fff);
10828 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10832 tmp = GEN_INT (0x8000);
10833 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10838 ;; Conditionalize these after reload. If they match before reload, we
10839 ;; lose the clobber and ability to use integer instructions.
10841 (define_insn "*<code><mode>2_1"
10842 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10843 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10845 && (reload_completed
10846 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10848 [(set_attr "type" "fsgn")
10849 (set_attr "mode" "<MODE>")])
10851 (define_insn "*<code>extendsfdf2"
10852 [(set (match_operand:DF 0 "register_operand" "=f")
10853 (absneg:DF (float_extend:DF
10854 (match_operand:SF 1 "register_operand" "0"))))]
10855 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10857 [(set_attr "type" "fsgn")
10858 (set_attr "mode" "DF")])
10860 (define_insn "*<code>extendsfxf2"
10861 [(set (match_operand:XF 0 "register_operand" "=f")
10862 (absneg:XF (float_extend:XF
10863 (match_operand:SF 1 "register_operand" "0"))))]
10866 [(set_attr "type" "fsgn")
10867 (set_attr "mode" "XF")])
10869 (define_insn "*<code>extenddfxf2"
10870 [(set (match_operand:XF 0 "register_operand" "=f")
10871 (absneg:XF (float_extend:XF
10872 (match_operand:DF 1 "register_operand" "0"))))]
10875 [(set_attr "type" "fsgn")
10876 (set_attr "mode" "XF")])
10878 ;; Copysign instructions
10880 (define_mode_iterator CSGNMODE [SF DF TF])
10881 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10883 (define_expand "copysign<mode>3"
10884 [(match_operand:CSGNMODE 0 "register_operand" "")
10885 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10886 (match_operand:CSGNMODE 2 "register_operand" "")]
10887 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10888 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10890 ix86_expand_copysign (operands);
10894 (define_insn_and_split "copysign<mode>3_const"
10895 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10897 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10898 (match_operand:CSGNMODE 2 "register_operand" "0")
10899 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10901 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10902 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10904 "&& reload_completed"
10907 ix86_split_copysign_const (operands);
10911 (define_insn "copysign<mode>3_var"
10912 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10914 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10915 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10916 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10917 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10919 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10920 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10921 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10925 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10927 [(match_operand:CSGNMODE 2 "register_operand" "")
10928 (match_operand:CSGNMODE 3 "register_operand" "")
10929 (match_operand:<CSGNVMODE> 4 "" "")
10930 (match_operand:<CSGNVMODE> 5 "" "")]
10932 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10933 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10934 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10935 && reload_completed"
10938 ix86_split_copysign_var (operands);
10942 ;; One complement instructions
10944 (define_expand "one_cmpldi2"
10945 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10946 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10948 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10950 (define_insn "*one_cmpldi2_1_rex64"
10951 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10952 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10953 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10955 [(set_attr "type" "negnot")
10956 (set_attr "mode" "DI")])
10958 (define_insn "*one_cmpldi2_2_rex64"
10959 [(set (reg FLAGS_REG)
10960 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10962 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10963 (not:DI (match_dup 1)))]
10964 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10965 && ix86_unary_operator_ok (NOT, DImode, operands)"
10967 [(set_attr "type" "alu1")
10968 (set_attr "mode" "DI")])
10971 [(set (match_operand 0 "flags_reg_operand" "")
10972 (match_operator 2 "compare_operator"
10973 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10975 (set (match_operand:DI 1 "nonimmediate_operand" "")
10976 (not:DI (match_dup 3)))]
10977 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10978 [(parallel [(set (match_dup 0)
10980 [(xor:DI (match_dup 3) (const_int -1))
10983 (xor:DI (match_dup 3) (const_int -1)))])]
10986 (define_expand "one_cmplsi2"
10987 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10988 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10990 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10992 (define_insn "*one_cmplsi2_1"
10993 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10994 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10995 "ix86_unary_operator_ok (NOT, SImode, operands)"
10997 [(set_attr "type" "negnot")
10998 (set_attr "mode" "SI")])
11000 ;; ??? Currently never generated - xor is used instead.
11001 (define_insn "*one_cmplsi2_1_zext"
11002 [(set (match_operand:DI 0 "register_operand" "=r")
11003 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11004 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11006 [(set_attr "type" "negnot")
11007 (set_attr "mode" "SI")])
11009 (define_insn "*one_cmplsi2_2"
11010 [(set (reg FLAGS_REG)
11011 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11013 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11014 (not:SI (match_dup 1)))]
11015 "ix86_match_ccmode (insn, CCNOmode)
11016 && ix86_unary_operator_ok (NOT, SImode, operands)"
11018 [(set_attr "type" "alu1")
11019 (set_attr "mode" "SI")])
11022 [(set (match_operand 0 "flags_reg_operand" "")
11023 (match_operator 2 "compare_operator"
11024 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11026 (set (match_operand:SI 1 "nonimmediate_operand" "")
11027 (not:SI (match_dup 3)))]
11028 "ix86_match_ccmode (insn, CCNOmode)"
11029 [(parallel [(set (match_dup 0)
11030 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11033 (xor:SI (match_dup 3) (const_int -1)))])]
11036 ;; ??? Currently never generated - xor is used instead.
11037 (define_insn "*one_cmplsi2_2_zext"
11038 [(set (reg FLAGS_REG)
11039 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11041 (set (match_operand:DI 0 "register_operand" "=r")
11042 (zero_extend:DI (not:SI (match_dup 1))))]
11043 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11044 && ix86_unary_operator_ok (NOT, SImode, operands)"
11046 [(set_attr "type" "alu1")
11047 (set_attr "mode" "SI")])
11050 [(set (match_operand 0 "flags_reg_operand" "")
11051 (match_operator 2 "compare_operator"
11052 [(not:SI (match_operand:SI 3 "register_operand" ""))
11054 (set (match_operand:DI 1 "register_operand" "")
11055 (zero_extend:DI (not:SI (match_dup 3))))]
11056 "ix86_match_ccmode (insn, CCNOmode)"
11057 [(parallel [(set (match_dup 0)
11058 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11061 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11064 (define_expand "one_cmplhi2"
11065 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11066 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11067 "TARGET_HIMODE_MATH"
11068 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11070 (define_insn "*one_cmplhi2_1"
11071 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11072 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11073 "ix86_unary_operator_ok (NOT, HImode, operands)"
11075 [(set_attr "type" "negnot")
11076 (set_attr "mode" "HI")])
11078 (define_insn "*one_cmplhi2_2"
11079 [(set (reg FLAGS_REG)
11080 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11082 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11083 (not:HI (match_dup 1)))]
11084 "ix86_match_ccmode (insn, CCNOmode)
11085 && ix86_unary_operator_ok (NEG, HImode, operands)"
11087 [(set_attr "type" "alu1")
11088 (set_attr "mode" "HI")])
11091 [(set (match_operand 0 "flags_reg_operand" "")
11092 (match_operator 2 "compare_operator"
11093 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11095 (set (match_operand:HI 1 "nonimmediate_operand" "")
11096 (not:HI (match_dup 3)))]
11097 "ix86_match_ccmode (insn, CCNOmode)"
11098 [(parallel [(set (match_dup 0)
11099 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11102 (xor:HI (match_dup 3) (const_int -1)))])]
11105 ;; %%% Potential partial reg stall on alternative 1. What to do?
11106 (define_expand "one_cmplqi2"
11107 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11108 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11109 "TARGET_QIMODE_MATH"
11110 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11112 (define_insn "*one_cmplqi2_1"
11113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11114 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11115 "ix86_unary_operator_ok (NOT, QImode, operands)"
11119 [(set_attr "type" "negnot")
11120 (set_attr "mode" "QI,SI")])
11122 (define_insn "*one_cmplqi2_2"
11123 [(set (reg FLAGS_REG)
11124 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11126 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11127 (not:QI (match_dup 1)))]
11128 "ix86_match_ccmode (insn, CCNOmode)
11129 && ix86_unary_operator_ok (NOT, QImode, operands)"
11131 [(set_attr "type" "alu1")
11132 (set_attr "mode" "QI")])
11135 [(set (match_operand 0 "flags_reg_operand" "")
11136 (match_operator 2 "compare_operator"
11137 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11139 (set (match_operand:QI 1 "nonimmediate_operand" "")
11140 (not:QI (match_dup 3)))]
11141 "ix86_match_ccmode (insn, CCNOmode)"
11142 [(parallel [(set (match_dup 0)
11143 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11146 (xor:QI (match_dup 3) (const_int -1)))])]
11149 ;; Arithmetic shift instructions
11151 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11152 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11153 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11154 ;; from the assembler input.
11156 ;; This instruction shifts the target reg/mem as usual, but instead of
11157 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11158 ;; is a left shift double, bits are taken from the high order bits of
11159 ;; reg, else if the insn is a shift right double, bits are taken from the
11160 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11161 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11163 ;; Since sh[lr]d does not change the `reg' operand, that is done
11164 ;; separately, making all shifts emit pairs of shift double and normal
11165 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11166 ;; support a 63 bit shift, each shift where the count is in a reg expands
11167 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11169 ;; If the shift count is a constant, we need never emit more than one
11170 ;; shift pair, instead using moves and sign extension for counts greater
11173 (define_expand "ashlti3"
11174 [(set (match_operand:TI 0 "register_operand" "")
11175 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11176 (match_operand:QI 2 "nonmemory_operand" "")))]
11178 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11180 ;; This pattern must be defined before *ashlti3_1 to prevent
11181 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11183 (define_insn "*avx_ashlti3"
11184 [(set (match_operand:TI 0 "register_operand" "=x")
11185 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11186 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11189 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11190 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11192 [(set_attr "type" "sseishft")
11193 (set_attr "prefix" "vex")
11194 (set_attr "mode" "TI")])
11196 (define_insn "sse2_ashlti3"
11197 [(set (match_operand:TI 0 "register_operand" "=x")
11198 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11199 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11202 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11203 return "pslldq\t{%2, %0|%0, %2}";
11205 [(set_attr "type" "sseishft")
11206 (set_attr "prefix_data16" "1")
11207 (set_attr "mode" "TI")])
11209 (define_insn "*ashlti3_1"
11210 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11211 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11212 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11213 (clobber (reg:CC FLAGS_REG))]
11216 [(set_attr "type" "multi")])
11219 [(match_scratch:DI 3 "r")
11220 (parallel [(set (match_operand:TI 0 "register_operand" "")
11221 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11222 (match_operand:QI 2 "nonmemory_operand" "")))
11223 (clobber (reg:CC FLAGS_REG))])
11227 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11230 [(set (match_operand:TI 0 "register_operand" "")
11231 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11232 (match_operand:QI 2 "nonmemory_operand" "")))
11233 (clobber (reg:CC FLAGS_REG))]
11234 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11235 ? epilogue_completed : reload_completed)"
11237 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11239 (define_insn "x86_64_shld"
11240 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11241 (ior:DI (ashift:DI (match_dup 0)
11242 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11243 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11244 (minus:QI (const_int 64) (match_dup 2)))))
11245 (clobber (reg:CC FLAGS_REG))]
11247 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11248 [(set_attr "type" "ishift")
11249 (set_attr "prefix_0f" "1")
11250 (set_attr "mode" "DI")
11251 (set_attr "athlon_decode" "vector")
11252 (set_attr "amdfam10_decode" "vector")])
11254 (define_expand "x86_64_shift_adj_1"
11255 [(set (reg:CCZ FLAGS_REG)
11256 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11259 (set (match_operand:DI 0 "register_operand" "")
11260 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11261 (match_operand:DI 1 "register_operand" "")
11264 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11265 (match_operand:DI 3 "register_operand" "r")
11270 (define_expand "x86_64_shift_adj_2"
11271 [(use (match_operand:DI 0 "register_operand" ""))
11272 (use (match_operand:DI 1 "register_operand" ""))
11273 (use (match_operand:QI 2 "register_operand" ""))]
11276 rtx label = gen_label_rtx ();
11279 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11281 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11282 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11283 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11284 gen_rtx_LABEL_REF (VOIDmode, label),
11286 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11287 JUMP_LABEL (tmp) = label;
11289 emit_move_insn (operands[0], operands[1]);
11290 ix86_expand_clear (operands[1]);
11292 emit_label (label);
11293 LABEL_NUSES (label) = 1;
11298 (define_expand "ashldi3"
11299 [(set (match_operand:DI 0 "shiftdi_operand" "")
11300 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11301 (match_operand:QI 2 "nonmemory_operand" "")))]
11303 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11305 (define_insn "*ashldi3_1_rex64"
11306 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11307 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11308 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11312 switch (get_attr_type (insn))
11315 gcc_assert (operands[2] == const1_rtx);
11316 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11317 return "add{q}\t%0, %0";
11320 gcc_assert (CONST_INT_P (operands[2]));
11321 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11322 operands[1] = gen_rtx_MULT (DImode, operands[1],
11323 GEN_INT (1 << INTVAL (operands[2])));
11324 return "lea{q}\t{%a1, %0|%0, %a1}";
11327 if (REG_P (operands[2]))
11328 return "sal{q}\t{%b2, %0|%0, %b2}";
11329 else if (operands[2] == const1_rtx
11330 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11331 return "sal{q}\t%0";
11333 return "sal{q}\t{%2, %0|%0, %2}";
11336 [(set (attr "type")
11337 (cond [(eq_attr "alternative" "1")
11338 (const_string "lea")
11339 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11341 (match_operand 0 "register_operand" ""))
11342 (match_operand 2 "const1_operand" ""))
11343 (const_string "alu")
11345 (const_string "ishift")))
11346 (set_attr "mode" "DI")])
11348 ;; Convert lea to the lea pattern to avoid flags dependency.
11350 [(set (match_operand:DI 0 "register_operand" "")
11351 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11352 (match_operand:QI 2 "immediate_operand" "")))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "TARGET_64BIT && reload_completed
11355 && true_regnum (operands[0]) != true_regnum (operands[1])"
11356 [(set (match_dup 0)
11357 (mult:DI (match_dup 1)
11359 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags. We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashldi3_cmp_rex64"
11365 [(set (reg FLAGS_REG)
11367 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11368 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11370 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11371 (ashift:DI (match_dup 1) (match_dup 2)))]
11373 && (optimize_function_for_size_p (cfun)
11374 || !TARGET_PARTIAL_FLAG_REG_STALL
11375 || (operands[2] == const1_rtx
11377 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11378 && ix86_match_ccmode (insn, CCGOCmode)
11379 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11381 switch (get_attr_type (insn))
11384 gcc_assert (operands[2] == const1_rtx);
11385 return "add{q}\t%0, %0";
11388 if (REG_P (operands[2]))
11389 return "sal{q}\t{%b2, %0|%0, %b2}";
11390 else if (operands[2] == const1_rtx
11391 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11392 return "sal{q}\t%0";
11394 return "sal{q}\t{%2, %0|%0, %2}";
11397 [(set (attr "type")
11398 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11400 (match_operand 0 "register_operand" ""))
11401 (match_operand 2 "const1_operand" ""))
11402 (const_string "alu")
11404 (const_string "ishift")))
11405 (set_attr "mode" "DI")])
11407 (define_insn "*ashldi3_cconly_rex64"
11408 [(set (reg FLAGS_REG)
11410 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11413 (clobber (match_scratch:DI 0 "=r"))]
11415 && (optimize_function_for_size_p (cfun)
11416 || !TARGET_PARTIAL_FLAG_REG_STALL
11417 || (operands[2] == const1_rtx
11419 || TARGET_DOUBLE_WITH_ADD)))
11420 && ix86_match_ccmode (insn, CCGOCmode)
11421 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11423 switch (get_attr_type (insn))
11426 gcc_assert (operands[2] == const1_rtx);
11427 return "add{q}\t%0, %0";
11430 if (REG_P (operands[2]))
11431 return "sal{q}\t{%b2, %0|%0, %b2}";
11432 else if (operands[2] == const1_rtx
11433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11434 return "sal{q}\t%0";
11436 return "sal{q}\t{%2, %0|%0, %2}";
11439 [(set (attr "type")
11440 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11442 (match_operand 0 "register_operand" ""))
11443 (match_operand 2 "const1_operand" ""))
11444 (const_string "alu")
11446 (const_string "ishift")))
11447 (set_attr "mode" "DI")])
11449 (define_insn "*ashldi3_1"
11450 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11451 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11452 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11453 (clobber (reg:CC FLAGS_REG))]
11456 [(set_attr "type" "multi")])
11458 ;; By default we don't ask for a scratch register, because when DImode
11459 ;; values are manipulated, registers are already at a premium. But if
11460 ;; we have one handy, we won't turn it away.
11462 [(match_scratch:SI 3 "r")
11463 (parallel [(set (match_operand:DI 0 "register_operand" "")
11464 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11465 (match_operand:QI 2 "nonmemory_operand" "")))
11466 (clobber (reg:CC FLAGS_REG))])
11468 "!TARGET_64BIT && TARGET_CMOVE"
11470 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11473 [(set (match_operand:DI 0 "register_operand" "")
11474 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11475 (match_operand:QI 2 "nonmemory_operand" "")))
11476 (clobber (reg:CC FLAGS_REG))]
11477 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11478 ? epilogue_completed : reload_completed)"
11480 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11482 (define_insn "x86_shld"
11483 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11484 (ior:SI (ashift:SI (match_dup 0)
11485 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11486 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11487 (minus:QI (const_int 32) (match_dup 2)))))
11488 (clobber (reg:CC FLAGS_REG))]
11490 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11491 [(set_attr "type" "ishift")
11492 (set_attr "prefix_0f" "1")
11493 (set_attr "mode" "SI")
11494 (set_attr "pent_pair" "np")
11495 (set_attr "athlon_decode" "vector")
11496 (set_attr "amdfam10_decode" "vector")])
11498 (define_expand "x86_shift_adj_1"
11499 [(set (reg:CCZ FLAGS_REG)
11500 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11503 (set (match_operand:SI 0 "register_operand" "")
11504 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11505 (match_operand:SI 1 "register_operand" "")
11508 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11509 (match_operand:SI 3 "register_operand" "r")
11514 (define_expand "x86_shift_adj_2"
11515 [(use (match_operand:SI 0 "register_operand" ""))
11516 (use (match_operand:SI 1 "register_operand" ""))
11517 (use (match_operand:QI 2 "register_operand" ""))]
11520 rtx label = gen_label_rtx ();
11523 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11525 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11526 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11527 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11528 gen_rtx_LABEL_REF (VOIDmode, label),
11530 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11531 JUMP_LABEL (tmp) = label;
11533 emit_move_insn (operands[0], operands[1]);
11534 ix86_expand_clear (operands[1]);
11536 emit_label (label);
11537 LABEL_NUSES (label) = 1;
11542 (define_expand "ashlsi3"
11543 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11544 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11545 (match_operand:QI 2 "nonmemory_operand" "")))]
11547 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11549 (define_insn "*ashlsi3_1"
11550 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11551 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11552 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11553 (clobber (reg:CC FLAGS_REG))]
11554 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11556 switch (get_attr_type (insn))
11559 gcc_assert (operands[2] == const1_rtx);
11560 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11561 return "add{l}\t%0, %0";
11567 if (REG_P (operands[2]))
11568 return "sal{l}\t{%b2, %0|%0, %b2}";
11569 else if (operands[2] == const1_rtx
11570 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11571 return "sal{l}\t%0";
11573 return "sal{l}\t{%2, %0|%0, %2}";
11576 [(set (attr "type")
11577 (cond [(eq_attr "alternative" "1")
11578 (const_string "lea")
11579 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581 (match_operand 0 "register_operand" ""))
11582 (match_operand 2 "const1_operand" ""))
11583 (const_string "alu")
11585 (const_string "ishift")))
11586 (set_attr "mode" "SI")])
11588 ;; Convert lea to the lea pattern to avoid flags dependency.
11590 [(set (match_operand 0 "register_operand" "")
11591 (ashift (match_operand 1 "index_register_operand" "")
11592 (match_operand:QI 2 "const_int_operand" "")))
11593 (clobber (reg:CC FLAGS_REG))]
11595 && true_regnum (operands[0]) != true_regnum (operands[1])
11596 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11600 enum machine_mode mode = GET_MODE (operands[0]);
11602 if (GET_MODE_SIZE (mode) < 4)
11603 operands[0] = gen_lowpart (SImode, operands[0]);
11605 operands[1] = gen_lowpart (Pmode, operands[1]);
11606 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11608 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11609 if (Pmode != SImode)
11610 pat = gen_rtx_SUBREG (SImode, pat, 0);
11611 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11615 ;; Rare case of shifting RSP is handled by generating move and shift
11617 [(set (match_operand 0 "register_operand" "")
11618 (ashift (match_operand 1 "register_operand" "")
11619 (match_operand:QI 2 "const_int_operand" "")))
11620 (clobber (reg:CC FLAGS_REG))]
11622 && true_regnum (operands[0]) != true_regnum (operands[1])"
11626 emit_move_insn (operands[0], operands[1]);
11627 pat = gen_rtx_SET (VOIDmode, operands[0],
11628 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11629 operands[0], operands[2]));
11630 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11631 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11635 (define_insn "*ashlsi3_1_zext"
11636 [(set (match_operand:DI 0 "register_operand" "=r,r")
11637 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11638 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11639 (clobber (reg:CC FLAGS_REG))]
11640 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11642 switch (get_attr_type (insn))
11645 gcc_assert (operands[2] == const1_rtx);
11646 return "add{l}\t%k0, %k0";
11652 if (REG_P (operands[2]))
11653 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11654 else if (operands[2] == const1_rtx
11655 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11656 return "sal{l}\t%k0";
11658 return "sal{l}\t{%2, %k0|%k0, %2}";
11661 [(set (attr "type")
11662 (cond [(eq_attr "alternative" "1")
11663 (const_string "lea")
11664 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11666 (match_operand 2 "const1_operand" ""))
11667 (const_string "alu")
11669 (const_string "ishift")))
11670 (set_attr "mode" "SI")])
11672 ;; Convert lea to the lea pattern to avoid flags dependency.
11674 [(set (match_operand:DI 0 "register_operand" "")
11675 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11676 (match_operand:QI 2 "const_int_operand" ""))))
11677 (clobber (reg:CC FLAGS_REG))]
11678 "TARGET_64BIT && reload_completed
11679 && true_regnum (operands[0]) != true_regnum (operands[1])"
11680 [(set (match_dup 0) (zero_extend:DI
11681 (subreg:SI (mult:SI (match_dup 1)
11682 (match_dup 2)) 0)))]
11684 operands[1] = gen_lowpart (Pmode, operands[1]);
11685 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11688 ;; This pattern can't accept a variable shift count, since shifts by
11689 ;; zero don't affect the flags. We assume that shifts by constant
11690 ;; zero are optimized away.
11691 (define_insn "*ashlsi3_cmp"
11692 [(set (reg FLAGS_REG)
11694 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11697 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11698 (ashift:SI (match_dup 1) (match_dup 2)))]
11699 "(optimize_function_for_size_p (cfun)
11700 || !TARGET_PARTIAL_FLAG_REG_STALL
11701 || (operands[2] == const1_rtx
11703 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11704 && ix86_match_ccmode (insn, CCGOCmode)
11705 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11707 switch (get_attr_type (insn))
11710 gcc_assert (operands[2] == const1_rtx);
11711 return "add{l}\t%0, %0";
11714 if (REG_P (operands[2]))
11715 return "sal{l}\t{%b2, %0|%0, %b2}";
11716 else if (operands[2] == const1_rtx
11717 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11718 return "sal{l}\t%0";
11720 return "sal{l}\t{%2, %0|%0, %2}";
11723 [(set (attr "type")
11724 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11726 (match_operand 0 "register_operand" ""))
11727 (match_operand 2 "const1_operand" ""))
11728 (const_string "alu")
11730 (const_string "ishift")))
11731 (set_attr "mode" "SI")])
11733 (define_insn "*ashlsi3_cconly"
11734 [(set (reg FLAGS_REG)
11736 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11737 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11739 (clobber (match_scratch:SI 0 "=r"))]
11740 "(optimize_function_for_size_p (cfun)
11741 || !TARGET_PARTIAL_FLAG_REG_STALL
11742 || (operands[2] == const1_rtx
11744 || TARGET_DOUBLE_WITH_ADD)))
11745 && ix86_match_ccmode (insn, CCGOCmode)
11746 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11748 switch (get_attr_type (insn))
11751 gcc_assert (operands[2] == const1_rtx);
11752 return "add{l}\t%0, %0";
11755 if (REG_P (operands[2]))
11756 return "sal{l}\t{%b2, %0|%0, %b2}";
11757 else if (operands[2] == const1_rtx
11758 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11759 return "sal{l}\t%0";
11761 return "sal{l}\t{%2, %0|%0, %2}";
11764 [(set (attr "type")
11765 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11767 (match_operand 0 "register_operand" ""))
11768 (match_operand 2 "const1_operand" ""))
11769 (const_string "alu")
11771 (const_string "ishift")))
11772 (set_attr "mode" "SI")])
11774 (define_insn "*ashlsi3_cmp_zext"
11775 [(set (reg FLAGS_REG)
11777 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11780 (set (match_operand:DI 0 "register_operand" "=r")
11781 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11783 && (optimize_function_for_size_p (cfun)
11784 || !TARGET_PARTIAL_FLAG_REG_STALL
11785 || (operands[2] == const1_rtx
11787 || TARGET_DOUBLE_WITH_ADD)))
11788 && ix86_match_ccmode (insn, CCGOCmode)
11789 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11791 switch (get_attr_type (insn))
11794 gcc_assert (operands[2] == const1_rtx);
11795 return "add{l}\t%k0, %k0";
11798 if (REG_P (operands[2]))
11799 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11800 else if (operands[2] == const1_rtx
11801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802 return "sal{l}\t%k0";
11804 return "sal{l}\t{%2, %k0|%k0, %2}";
11807 [(set (attr "type")
11808 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11810 (match_operand 2 "const1_operand" ""))
11811 (const_string "alu")
11813 (const_string "ishift")))
11814 (set_attr "mode" "SI")])
11816 (define_expand "ashlhi3"
11817 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11818 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11819 (match_operand:QI 2 "nonmemory_operand" "")))]
11820 "TARGET_HIMODE_MATH"
11821 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11823 (define_insn "*ashlhi3_1_lea"
11824 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11825 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11826 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "!TARGET_PARTIAL_REG_STALL
11829 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11831 switch (get_attr_type (insn))
11836 gcc_assert (operands[2] == const1_rtx);
11837 return "add{w}\t%0, %0";
11840 if (REG_P (operands[2]))
11841 return "sal{w}\t{%b2, %0|%0, %b2}";
11842 else if (operands[2] == const1_rtx
11843 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11844 return "sal{w}\t%0";
11846 return "sal{w}\t{%2, %0|%0, %2}";
11849 [(set (attr "type")
11850 (cond [(eq_attr "alternative" "1")
11851 (const_string "lea")
11852 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11854 (match_operand 0 "register_operand" ""))
11855 (match_operand 2 "const1_operand" ""))
11856 (const_string "alu")
11858 (const_string "ishift")))
11859 (set_attr "mode" "HI,SI")])
11861 (define_insn "*ashlhi3_1"
11862 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11863 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11864 (match_operand:QI 2 "nonmemory_operand" "cI")))
11865 (clobber (reg:CC FLAGS_REG))]
11866 "TARGET_PARTIAL_REG_STALL
11867 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11869 switch (get_attr_type (insn))
11872 gcc_assert (operands[2] == const1_rtx);
11873 return "add{w}\t%0, %0";
11876 if (REG_P (operands[2]))
11877 return "sal{w}\t{%b2, %0|%0, %b2}";
11878 else if (operands[2] == const1_rtx
11879 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11880 return "sal{w}\t%0";
11882 return "sal{w}\t{%2, %0|%0, %2}";
11885 [(set (attr "type")
11886 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11888 (match_operand 0 "register_operand" ""))
11889 (match_operand 2 "const1_operand" ""))
11890 (const_string "alu")
11892 (const_string "ishift")))
11893 (set_attr "mode" "HI")])
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags. We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*ashlhi3_cmp"
11899 [(set (reg FLAGS_REG)
11901 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11904 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905 (ashift:HI (match_dup 1) (match_dup 2)))]
11906 "(optimize_function_for_size_p (cfun)
11907 || !TARGET_PARTIAL_FLAG_REG_STALL
11908 || (operands[2] == const1_rtx
11910 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11911 && ix86_match_ccmode (insn, CCGOCmode)
11912 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11914 switch (get_attr_type (insn))
11917 gcc_assert (operands[2] == const1_rtx);
11918 return "add{w}\t%0, %0";
11921 if (REG_P (operands[2]))
11922 return "sal{w}\t{%b2, %0|%0, %b2}";
11923 else if (operands[2] == const1_rtx
11924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11925 return "sal{w}\t%0";
11927 return "sal{w}\t{%2, %0|%0, %2}";
11930 [(set (attr "type")
11931 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11933 (match_operand 0 "register_operand" ""))
11934 (match_operand 2 "const1_operand" ""))
11935 (const_string "alu")
11937 (const_string "ishift")))
11938 (set_attr "mode" "HI")])
11940 (define_insn "*ashlhi3_cconly"
11941 [(set (reg FLAGS_REG)
11943 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11944 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11946 (clobber (match_scratch:HI 0 "=r"))]
11947 "(optimize_function_for_size_p (cfun)
11948 || !TARGET_PARTIAL_FLAG_REG_STALL
11949 || (operands[2] == const1_rtx
11951 || TARGET_DOUBLE_WITH_ADD)))
11952 && ix86_match_ccmode (insn, CCGOCmode)
11953 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11955 switch (get_attr_type (insn))
11958 gcc_assert (operands[2] == const1_rtx);
11959 return "add{w}\t%0, %0";
11962 if (REG_P (operands[2]))
11963 return "sal{w}\t{%b2, %0|%0, %b2}";
11964 else if (operands[2] == const1_rtx
11965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11966 return "sal{w}\t%0";
11968 return "sal{w}\t{%2, %0|%0, %2}";
11971 [(set (attr "type")
11972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11974 (match_operand 0 "register_operand" ""))
11975 (match_operand 2 "const1_operand" ""))
11976 (const_string "alu")
11978 (const_string "ishift")))
11979 (set_attr "mode" "HI")])
11981 (define_expand "ashlqi3"
11982 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11983 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11984 (match_operand:QI 2 "nonmemory_operand" "")))]
11985 "TARGET_QIMODE_MATH"
11986 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11988 ;; %%% Potential partial reg stall on alternative 2. What to do?
11990 (define_insn "*ashlqi3_1_lea"
11991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11992 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11993 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "!TARGET_PARTIAL_REG_STALL
11996 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11998 switch (get_attr_type (insn))
12003 gcc_assert (operands[2] == const1_rtx);
12004 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12005 return "add{l}\t%k0, %k0";
12007 return "add{b}\t%0, %0";
12010 if (REG_P (operands[2]))
12012 if (get_attr_mode (insn) == MODE_SI)
12013 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12015 return "sal{b}\t{%b2, %0|%0, %b2}";
12017 else if (operands[2] == const1_rtx
12018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12020 if (get_attr_mode (insn) == MODE_SI)
12021 return "sal{l}\t%0";
12023 return "sal{b}\t%0";
12027 if (get_attr_mode (insn) == MODE_SI)
12028 return "sal{l}\t{%2, %k0|%k0, %2}";
12030 return "sal{b}\t{%2, %0|%0, %2}";
12034 [(set (attr "type")
12035 (cond [(eq_attr "alternative" "2")
12036 (const_string "lea")
12037 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12039 (match_operand 0 "register_operand" ""))
12040 (match_operand 2 "const1_operand" ""))
12041 (const_string "alu")
12043 (const_string "ishift")))
12044 (set_attr "mode" "QI,SI,SI")])
12046 (define_insn "*ashlqi3_1"
12047 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12048 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12049 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "TARGET_PARTIAL_REG_STALL
12052 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12054 switch (get_attr_type (insn))
12057 gcc_assert (operands[2] == const1_rtx);
12058 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12059 return "add{l}\t%k0, %k0";
12061 return "add{b}\t%0, %0";
12064 if (REG_P (operands[2]))
12066 if (get_attr_mode (insn) == MODE_SI)
12067 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12069 return "sal{b}\t{%b2, %0|%0, %b2}";
12071 else if (operands[2] == const1_rtx
12072 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12074 if (get_attr_mode (insn) == MODE_SI)
12075 return "sal{l}\t%0";
12077 return "sal{b}\t%0";
12081 if (get_attr_mode (insn) == MODE_SI)
12082 return "sal{l}\t{%2, %k0|%k0, %2}";
12084 return "sal{b}\t{%2, %0|%0, %2}";
12088 [(set (attr "type")
12089 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12091 (match_operand 0 "register_operand" ""))
12092 (match_operand 2 "const1_operand" ""))
12093 (const_string "alu")
12095 (const_string "ishift")))
12096 (set_attr "mode" "QI,SI")])
12098 ;; This pattern can't accept a variable shift count, since shifts by
12099 ;; zero don't affect the flags. We assume that shifts by constant
12100 ;; zero are optimized away.
12101 (define_insn "*ashlqi3_cmp"
12102 [(set (reg FLAGS_REG)
12104 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12105 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12107 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12108 (ashift:QI (match_dup 1) (match_dup 2)))]
12109 "(optimize_function_for_size_p (cfun)
12110 || !TARGET_PARTIAL_FLAG_REG_STALL
12111 || (operands[2] == const1_rtx
12113 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12114 && ix86_match_ccmode (insn, CCGOCmode)
12115 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12117 switch (get_attr_type (insn))
12120 gcc_assert (operands[2] == const1_rtx);
12121 return "add{b}\t%0, %0";
12124 if (REG_P (operands[2]))
12125 return "sal{b}\t{%b2, %0|%0, %b2}";
12126 else if (operands[2] == const1_rtx
12127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12128 return "sal{b}\t%0";
12130 return "sal{b}\t{%2, %0|%0, %2}";
12133 [(set (attr "type")
12134 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12136 (match_operand 0 "register_operand" ""))
12137 (match_operand 2 "const1_operand" ""))
12138 (const_string "alu")
12140 (const_string "ishift")))
12141 (set_attr "mode" "QI")])
12143 (define_insn "*ashlqi3_cconly"
12144 [(set (reg FLAGS_REG)
12146 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12147 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12149 (clobber (match_scratch:QI 0 "=q"))]
12150 "(optimize_function_for_size_p (cfun)
12151 || !TARGET_PARTIAL_FLAG_REG_STALL
12152 || (operands[2] == const1_rtx
12154 || TARGET_DOUBLE_WITH_ADD)))
12155 && ix86_match_ccmode (insn, CCGOCmode)
12156 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12158 switch (get_attr_type (insn))
12161 gcc_assert (operands[2] == const1_rtx);
12162 return "add{b}\t%0, %0";
12165 if (REG_P (operands[2]))
12166 return "sal{b}\t{%b2, %0|%0, %b2}";
12167 else if (operands[2] == const1_rtx
12168 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12169 return "sal{b}\t%0";
12171 return "sal{b}\t{%2, %0|%0, %2}";
12174 [(set (attr "type")
12175 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12177 (match_operand 0 "register_operand" ""))
12178 (match_operand 2 "const1_operand" ""))
12179 (const_string "alu")
12181 (const_string "ishift")))
12182 (set_attr "mode" "QI")])
12184 ;; See comment above `ashldi3' about how this works.
12186 (define_expand "ashrti3"
12187 [(set (match_operand:TI 0 "register_operand" "")
12188 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12189 (match_operand:QI 2 "nonmemory_operand" "")))]
12191 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12193 (define_insn "*ashrti3_1"
12194 [(set (match_operand:TI 0 "register_operand" "=r")
12195 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12196 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12197 (clobber (reg:CC FLAGS_REG))]
12200 [(set_attr "type" "multi")])
12203 [(match_scratch:DI 3 "r")
12204 (parallel [(set (match_operand:TI 0 "register_operand" "")
12205 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12206 (match_operand:QI 2 "nonmemory_operand" "")))
12207 (clobber (reg:CC FLAGS_REG))])
12211 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12214 [(set (match_operand:TI 0 "register_operand" "")
12215 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12216 (match_operand:QI 2 "nonmemory_operand" "")))
12217 (clobber (reg:CC FLAGS_REG))]
12218 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12219 ? epilogue_completed : reload_completed)"
12221 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12223 (define_insn "x86_64_shrd"
12224 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12225 (ior:DI (ashiftrt:DI (match_dup 0)
12226 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12227 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12228 (minus:QI (const_int 64) (match_dup 2)))))
12229 (clobber (reg:CC FLAGS_REG))]
12231 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12232 [(set_attr "type" "ishift")
12233 (set_attr "prefix_0f" "1")
12234 (set_attr "mode" "DI")
12235 (set_attr "athlon_decode" "vector")
12236 (set_attr "amdfam10_decode" "vector")])
12238 (define_expand "ashrdi3"
12239 [(set (match_operand:DI 0 "shiftdi_operand" "")
12240 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12241 (match_operand:QI 2 "nonmemory_operand" "")))]
12243 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12245 (define_expand "x86_64_shift_adj_3"
12246 [(use (match_operand:DI 0 "register_operand" ""))
12247 (use (match_operand:DI 1 "register_operand" ""))
12248 (use (match_operand:QI 2 "register_operand" ""))]
12251 rtx label = gen_label_rtx ();
12254 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12256 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12257 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12258 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12259 gen_rtx_LABEL_REF (VOIDmode, label),
12261 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12262 JUMP_LABEL (tmp) = label;
12264 emit_move_insn (operands[0], operands[1]);
12265 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12267 emit_label (label);
12268 LABEL_NUSES (label) = 1;
12273 (define_insn "ashrdi3_63_rex64"
12274 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12275 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12276 (match_operand:DI 2 "const_int_operand" "i,i")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "TARGET_64BIT && INTVAL (operands[2]) == 63
12279 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12280 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12283 sar{q}\t{%2, %0|%0, %2}"
12284 [(set_attr "type" "imovx,ishift")
12285 (set_attr "prefix_0f" "0,*")
12286 (set_attr "length_immediate" "0,*")
12287 (set_attr "modrm" "0,1")
12288 (set_attr "mode" "DI")])
12290 (define_insn "*ashrdi3_1_one_bit_rex64"
12291 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12292 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12293 (match_operand:QI 2 "const1_operand" "")))
12294 (clobber (reg:CC FLAGS_REG))]
12296 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12297 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12299 [(set_attr "type" "ishift")
12300 (set (attr "length")
12301 (if_then_else (match_operand:DI 0 "register_operand" "")
12303 (const_string "*")))])
12305 (define_insn "*ashrdi3_1_rex64"
12306 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12307 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12308 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12309 (clobber (reg:CC FLAGS_REG))]
12310 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12312 sar{q}\t{%2, %0|%0, %2}
12313 sar{q}\t{%b2, %0|%0, %b2}"
12314 [(set_attr "type" "ishift")
12315 (set_attr "mode" "DI")])
12317 ;; This pattern can't accept a variable shift count, since shifts by
12318 ;; zero don't affect the flags. We assume that shifts by constant
12319 ;; zero are optimized away.
12320 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12321 [(set (reg FLAGS_REG)
12323 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const1_operand" ""))
12326 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12327 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12329 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12330 && ix86_match_ccmode (insn, CCGOCmode)
12331 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12333 [(set_attr "type" "ishift")
12334 (set (attr "length")
12335 (if_then_else (match_operand:DI 0 "register_operand" "")
12337 (const_string "*")))])
12339 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12340 [(set (reg FLAGS_REG)
12342 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12343 (match_operand:QI 2 "const1_operand" ""))
12345 (clobber (match_scratch:DI 0 "=r"))]
12347 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12348 && ix86_match_ccmode (insn, CCGOCmode)
12349 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12351 [(set_attr "type" "ishift")
12352 (set_attr "length" "2")])
12354 ;; This pattern can't accept a variable shift count, since shifts by
12355 ;; zero don't affect the flags. We assume that shifts by constant
12356 ;; zero are optimized away.
12357 (define_insn "*ashrdi3_cmp_rex64"
12358 [(set (reg FLAGS_REG)
12360 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12361 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12363 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12364 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12366 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12367 && ix86_match_ccmode (insn, CCGOCmode)
12368 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12369 "sar{q}\t{%2, %0|%0, %2}"
12370 [(set_attr "type" "ishift")
12371 (set_attr "mode" "DI")])
12373 (define_insn "*ashrdi3_cconly_rex64"
12374 [(set (reg FLAGS_REG)
12376 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12379 (clobber (match_scratch:DI 0 "=r"))]
12381 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12382 && ix86_match_ccmode (insn, CCGOCmode)
12383 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12384 "sar{q}\t{%2, %0|%0, %2}"
12385 [(set_attr "type" "ishift")
12386 (set_attr "mode" "DI")])
12388 (define_insn "*ashrdi3_1"
12389 [(set (match_operand:DI 0 "register_operand" "=r")
12390 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12391 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12392 (clobber (reg:CC FLAGS_REG))]
12395 [(set_attr "type" "multi")])
12397 ;; By default we don't ask for a scratch register, because when DImode
12398 ;; values are manipulated, registers are already at a premium. But if
12399 ;; we have one handy, we won't turn it away.
12401 [(match_scratch:SI 3 "r")
12402 (parallel [(set (match_operand:DI 0 "register_operand" "")
12403 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12404 (match_operand:QI 2 "nonmemory_operand" "")))
12405 (clobber (reg:CC FLAGS_REG))])
12407 "!TARGET_64BIT && TARGET_CMOVE"
12409 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12412 [(set (match_operand:DI 0 "register_operand" "")
12413 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12414 (match_operand:QI 2 "nonmemory_operand" "")))
12415 (clobber (reg:CC FLAGS_REG))]
12416 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12417 ? epilogue_completed : reload_completed)"
12419 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12421 (define_insn "x86_shrd"
12422 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12423 (ior:SI (ashiftrt:SI (match_dup 0)
12424 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12425 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12426 (minus:QI (const_int 32) (match_dup 2)))))
12427 (clobber (reg:CC FLAGS_REG))]
12429 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12430 [(set_attr "type" "ishift")
12431 (set_attr "prefix_0f" "1")
12432 (set_attr "pent_pair" "np")
12433 (set_attr "mode" "SI")])
12435 (define_expand "x86_shift_adj_3"
12436 [(use (match_operand:SI 0 "register_operand" ""))
12437 (use (match_operand:SI 1 "register_operand" ""))
12438 (use (match_operand:QI 2 "register_operand" ""))]
12441 rtx label = gen_label_rtx ();
12444 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12446 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12447 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12448 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12449 gen_rtx_LABEL_REF (VOIDmode, label),
12451 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12452 JUMP_LABEL (tmp) = label;
12454 emit_move_insn (operands[0], operands[1]);
12455 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12457 emit_label (label);
12458 LABEL_NUSES (label) = 1;
12463 (define_expand "ashrsi3_31"
12464 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12465 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12466 (match_operand:SI 2 "const_int_operand" "i,i")))
12467 (clobber (reg:CC FLAGS_REG))])]
12470 (define_insn "*ashrsi3_31"
12471 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12472 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12473 (match_operand:SI 2 "const_int_operand" "i,i")))
12474 (clobber (reg:CC FLAGS_REG))]
12475 "INTVAL (operands[2]) == 31
12476 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12477 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12480 sar{l}\t{%2, %0|%0, %2}"
12481 [(set_attr "type" "imovx,ishift")
12482 (set_attr "prefix_0f" "0,*")
12483 (set_attr "length_immediate" "0,*")
12484 (set_attr "modrm" "0,1")
12485 (set_attr "mode" "SI")])
12487 (define_insn "*ashrsi3_31_zext"
12488 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12489 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12490 (match_operand:SI 2 "const_int_operand" "i,i"))))
12491 (clobber (reg:CC FLAGS_REG))]
12492 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12493 && INTVAL (operands[2]) == 31
12494 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12497 sar{l}\t{%2, %k0|%k0, %2}"
12498 [(set_attr "type" "imovx,ishift")
12499 (set_attr "prefix_0f" "0,*")
12500 (set_attr "length_immediate" "0,*")
12501 (set_attr "modrm" "0,1")
12502 (set_attr "mode" "SI")])
12504 (define_expand "ashrsi3"
12505 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12506 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12507 (match_operand:QI 2 "nonmemory_operand" "")))]
12509 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12511 (define_insn "*ashrsi3_1_one_bit"
12512 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12514 (match_operand:QI 2 "const1_operand" "")))
12515 (clobber (reg:CC FLAGS_REG))]
12516 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12517 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12519 [(set_attr "type" "ishift")
12520 (set (attr "length")
12521 (if_then_else (match_operand:SI 0 "register_operand" "")
12523 (const_string "*")))])
12525 (define_insn "*ashrsi3_1_one_bit_zext"
12526 [(set (match_operand:DI 0 "register_operand" "=r")
12527 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))))
12529 (clobber (reg:CC FLAGS_REG))]
12531 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12532 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12534 [(set_attr "type" "ishift")
12535 (set_attr "length" "2")])
12537 (define_insn "*ashrsi3_1"
12538 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12539 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12540 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12541 (clobber (reg:CC FLAGS_REG))]
12542 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12544 sar{l}\t{%2, %0|%0, %2}
12545 sar{l}\t{%b2, %0|%0, %b2}"
12546 [(set_attr "type" "ishift")
12547 (set_attr "mode" "SI")])
12549 (define_insn "*ashrsi3_1_zext"
12550 [(set (match_operand:DI 0 "register_operand" "=r,r")
12551 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12552 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12556 sar{l}\t{%2, %k0|%k0, %2}
12557 sar{l}\t{%b2, %k0|%k0, %b2}"
12558 [(set_attr "type" "ishift")
12559 (set_attr "mode" "SI")])
12561 ;; This pattern can't accept a variable shift count, since shifts by
12562 ;; zero don't affect the flags. We assume that shifts by constant
12563 ;; zero are optimized away.
12564 (define_insn "*ashrsi3_one_bit_cmp"
12565 [(set (reg FLAGS_REG)
12567 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12568 (match_operand:QI 2 "const1_operand" ""))
12570 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12571 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12572 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12573 && ix86_match_ccmode (insn, CCGOCmode)
12574 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12576 [(set_attr "type" "ishift")
12577 (set (attr "length")
12578 (if_then_else (match_operand:SI 0 "register_operand" "")
12580 (const_string "*")))])
12582 (define_insn "*ashrsi3_one_bit_cconly"
12583 [(set (reg FLAGS_REG)
12585 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586 (match_operand:QI 2 "const1_operand" ""))
12588 (clobber (match_scratch:SI 0 "=r"))]
12589 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12590 && ix86_match_ccmode (insn, CCGOCmode)
12591 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12593 [(set_attr "type" "ishift")
12594 (set_attr "length" "2")])
12596 (define_insn "*ashrsi3_one_bit_cmp_zext"
12597 [(set (reg FLAGS_REG)
12599 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12600 (match_operand:QI 2 "const1_operand" ""))
12602 (set (match_operand:DI 0 "register_operand" "=r")
12603 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12605 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12606 && ix86_match_ccmode (insn, CCmode)
12607 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12609 [(set_attr "type" "ishift")
12610 (set_attr "length" "2")])
12612 ;; This pattern can't accept a variable shift count, since shifts by
12613 ;; zero don't affect the flags. We assume that shifts by constant
12614 ;; zero are optimized away.
12615 (define_insn "*ashrsi3_cmp"
12616 [(set (reg FLAGS_REG)
12618 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12621 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12622 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12623 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12624 && ix86_match_ccmode (insn, CCGOCmode)
12625 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12626 "sar{l}\t{%2, %0|%0, %2}"
12627 [(set_attr "type" "ishift")
12628 (set_attr "mode" "SI")])
12630 (define_insn "*ashrsi3_cconly"
12631 [(set (reg FLAGS_REG)
12633 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12634 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12636 (clobber (match_scratch:SI 0 "=r"))]
12637 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12638 && ix86_match_ccmode (insn, CCGOCmode)
12639 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12640 "sar{l}\t{%2, %0|%0, %2}"
12641 [(set_attr "type" "ishift")
12642 (set_attr "mode" "SI")])
12644 (define_insn "*ashrsi3_cmp_zext"
12645 [(set (reg FLAGS_REG)
12647 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12648 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12650 (set (match_operand:DI 0 "register_operand" "=r")
12651 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12653 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12654 && ix86_match_ccmode (insn, CCGOCmode)
12655 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12656 "sar{l}\t{%2, %k0|%k0, %2}"
12657 [(set_attr "type" "ishift")
12658 (set_attr "mode" "SI")])
12660 (define_expand "ashrhi3"
12661 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12662 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12663 (match_operand:QI 2 "nonmemory_operand" "")))]
12664 "TARGET_HIMODE_MATH"
12665 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12667 (define_insn "*ashrhi3_1_one_bit"
12668 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12669 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12670 (match_operand:QI 2 "const1_operand" "")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12673 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12675 [(set_attr "type" "ishift")
12676 (set (attr "length")
12677 (if_then_else (match_operand 0 "register_operand" "")
12679 (const_string "*")))])
12681 (define_insn "*ashrhi3_1"
12682 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12683 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12684 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12688 sar{w}\t{%2, %0|%0, %2}
12689 sar{w}\t{%b2, %0|%0, %b2}"
12690 [(set_attr "type" "ishift")
12691 (set_attr "mode" "HI")])
12693 ;; This pattern can't accept a variable shift count, since shifts by
12694 ;; zero don't affect the flags. We assume that shifts by constant
12695 ;; zero are optimized away.
12696 (define_insn "*ashrhi3_one_bit_cmp"
12697 [(set (reg FLAGS_REG)
12699 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12700 (match_operand:QI 2 "const1_operand" ""))
12702 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12703 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12704 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12705 && ix86_match_ccmode (insn, CCGOCmode)
12706 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12708 [(set_attr "type" "ishift")
12709 (set (attr "length")
12710 (if_then_else (match_operand 0 "register_operand" "")
12712 (const_string "*")))])
12714 (define_insn "*ashrhi3_one_bit_cconly"
12715 [(set (reg FLAGS_REG)
12717 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12718 (match_operand:QI 2 "const1_operand" ""))
12720 (clobber (match_scratch:HI 0 "=r"))]
12721 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12722 && ix86_match_ccmode (insn, CCGOCmode)
12723 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12725 [(set_attr "type" "ishift")
12726 (set_attr "length" "2")])
12728 ;; This pattern can't accept a variable shift count, since shifts by
12729 ;; zero don't affect the flags. We assume that shifts by constant
12730 ;; zero are optimized away.
12731 (define_insn "*ashrhi3_cmp"
12732 [(set (reg FLAGS_REG)
12734 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12735 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12737 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12738 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12739 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12740 && ix86_match_ccmode (insn, CCGOCmode)
12741 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12742 "sar{w}\t{%2, %0|%0, %2}"
12743 [(set_attr "type" "ishift")
12744 (set_attr "mode" "HI")])
12746 (define_insn "*ashrhi3_cconly"
12747 [(set (reg FLAGS_REG)
12749 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12750 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12752 (clobber (match_scratch:HI 0 "=r"))]
12753 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12754 && ix86_match_ccmode (insn, CCGOCmode)
12755 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12756 "sar{w}\t{%2, %0|%0, %2}"
12757 [(set_attr "type" "ishift")
12758 (set_attr "mode" "HI")])
12760 (define_expand "ashrqi3"
12761 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12762 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12763 (match_operand:QI 2 "nonmemory_operand" "")))]
12764 "TARGET_QIMODE_MATH"
12765 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12767 (define_insn "*ashrqi3_1_one_bit"
12768 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12769 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12770 (match_operand:QI 2 "const1_operand" "")))
12771 (clobber (reg:CC FLAGS_REG))]
12772 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12773 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12775 [(set_attr "type" "ishift")
12776 (set (attr "length")
12777 (if_then_else (match_operand 0 "register_operand" "")
12779 (const_string "*")))])
12781 (define_insn "*ashrqi3_1_one_bit_slp"
12782 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12783 (ashiftrt:QI (match_dup 0)
12784 (match_operand:QI 1 "const1_operand" "")))
12785 (clobber (reg:CC FLAGS_REG))]
12786 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12787 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12788 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12790 [(set_attr "type" "ishift1")
12791 (set (attr "length")
12792 (if_then_else (match_operand 0 "register_operand" "")
12794 (const_string "*")))])
12796 (define_insn "*ashrqi3_1"
12797 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12798 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12799 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12800 (clobber (reg:CC FLAGS_REG))]
12801 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12803 sar{b}\t{%2, %0|%0, %2}
12804 sar{b}\t{%b2, %0|%0, %b2}"
12805 [(set_attr "type" "ishift")
12806 (set_attr "mode" "QI")])
12808 (define_insn "*ashrqi3_1_slp"
12809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12810 (ashiftrt:QI (match_dup 0)
12811 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12812 (clobber (reg:CC FLAGS_REG))]
12813 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12816 sar{b}\t{%1, %0|%0, %1}
12817 sar{b}\t{%b1, %0|%0, %b1}"
12818 [(set_attr "type" "ishift1")
12819 (set_attr "mode" "QI")])
12821 ;; This pattern can't accept a variable shift count, since shifts by
12822 ;; zero don't affect the flags. We assume that shifts by constant
12823 ;; zero are optimized away.
12824 (define_insn "*ashrqi3_one_bit_cmp"
12825 [(set (reg FLAGS_REG)
12827 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12828 (match_operand:QI 2 "const1_operand" "I"))
12830 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12831 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12832 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12833 && ix86_match_ccmode (insn, CCGOCmode)
12834 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12836 [(set_attr "type" "ishift")
12837 (set (attr "length")
12838 (if_then_else (match_operand 0 "register_operand" "")
12840 (const_string "*")))])
12842 (define_insn "*ashrqi3_one_bit_cconly"
12843 [(set (reg FLAGS_REG)
12845 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12846 (match_operand:QI 2 "const1_operand" ""))
12848 (clobber (match_scratch:QI 0 "=q"))]
12849 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12850 && ix86_match_ccmode (insn, CCGOCmode)
12851 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12853 [(set_attr "type" "ishift")
12854 (set_attr "length" "2")])
12856 ;; This pattern can't accept a variable shift count, since shifts by
12857 ;; zero don't affect the flags. We assume that shifts by constant
12858 ;; zero are optimized away.
12859 (define_insn "*ashrqi3_cmp"
12860 [(set (reg FLAGS_REG)
12862 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12865 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12866 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12867 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12868 && ix86_match_ccmode (insn, CCGOCmode)
12869 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12870 "sar{b}\t{%2, %0|%0, %2}"
12871 [(set_attr "type" "ishift")
12872 (set_attr "mode" "QI")])
12874 (define_insn "*ashrqi3_cconly"
12875 [(set (reg FLAGS_REG)
12877 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12878 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12880 (clobber (match_scratch:QI 0 "=q"))]
12881 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12882 && ix86_match_ccmode (insn, CCGOCmode)
12883 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12884 "sar{b}\t{%2, %0|%0, %2}"
12885 [(set_attr "type" "ishift")
12886 (set_attr "mode" "QI")])
12889 ;; Logical shift instructions
12891 ;; See comment above `ashldi3' about how this works.
12893 (define_expand "lshrti3"
12894 [(set (match_operand:TI 0 "register_operand" "")
12895 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12896 (match_operand:QI 2 "nonmemory_operand" "")))]
12898 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12900 ;; This pattern must be defined before *lshrti3_1 to prevent
12901 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12903 (define_insn "*avx_lshrti3"
12904 [(set (match_operand:TI 0 "register_operand" "=x")
12905 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12906 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12909 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12910 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12912 [(set_attr "type" "sseishft")
12913 (set_attr "prefix" "vex")
12914 (set_attr "mode" "TI")])
12916 (define_insn "sse2_lshrti3"
12917 [(set (match_operand:TI 0 "register_operand" "=x")
12918 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12919 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12922 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12923 return "psrldq\t{%2, %0|%0, %2}";
12925 [(set_attr "type" "sseishft")
12926 (set_attr "prefix_data16" "1")
12927 (set_attr "mode" "TI")])
12929 (define_insn "*lshrti3_1"
12930 [(set (match_operand:TI 0 "register_operand" "=r")
12931 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12932 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12933 (clobber (reg:CC FLAGS_REG))]
12936 [(set_attr "type" "multi")])
12939 [(match_scratch:DI 3 "r")
12940 (parallel [(set (match_operand:TI 0 "register_operand" "")
12941 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12942 (match_operand:QI 2 "nonmemory_operand" "")))
12943 (clobber (reg:CC FLAGS_REG))])
12947 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12950 [(set (match_operand:TI 0 "register_operand" "")
12951 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12952 (match_operand:QI 2 "nonmemory_operand" "")))
12953 (clobber (reg:CC FLAGS_REG))]
12954 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12955 ? epilogue_completed : reload_completed)"
12957 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12959 (define_expand "lshrdi3"
12960 [(set (match_operand:DI 0 "shiftdi_operand" "")
12961 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12962 (match_operand:QI 2 "nonmemory_operand" "")))]
12964 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12966 (define_insn "*lshrdi3_1_one_bit_rex64"
12967 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12968 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12969 (match_operand:QI 2 "const1_operand" "")))
12970 (clobber (reg:CC FLAGS_REG))]
12972 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12973 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12975 [(set_attr "type" "ishift")
12976 (set (attr "length")
12977 (if_then_else (match_operand:DI 0 "register_operand" "")
12979 (const_string "*")))])
12981 (define_insn "*lshrdi3_1_rex64"
12982 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12983 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12984 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12988 shr{q}\t{%2, %0|%0, %2}
12989 shr{q}\t{%b2, %0|%0, %b2}"
12990 [(set_attr "type" "ishift")
12991 (set_attr "mode" "DI")])
12993 ;; This pattern can't accept a variable shift count, since shifts by
12994 ;; zero don't affect the flags. We assume that shifts by constant
12995 ;; zero are optimized away.
12996 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12997 [(set (reg FLAGS_REG)
12999 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13000 (match_operand:QI 2 "const1_operand" ""))
13002 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13003 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13006 && ix86_match_ccmode (insn, CCGOCmode)
13007 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13009 [(set_attr "type" "ishift")
13010 (set (attr "length")
13011 (if_then_else (match_operand:DI 0 "register_operand" "")
13013 (const_string "*")))])
13015 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13016 [(set (reg FLAGS_REG)
13018 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13019 (match_operand:QI 2 "const1_operand" ""))
13021 (clobber (match_scratch:DI 0 "=r"))]
13023 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13024 && ix86_match_ccmode (insn, CCGOCmode)
13025 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 [(set_attr "type" "ishift")
13028 (set_attr "length" "2")])
13030 ;; This pattern can't accept a variable shift count, since shifts by
13031 ;; zero don't affect the flags. We assume that shifts by constant
13032 ;; zero are optimized away.
13033 (define_insn "*lshrdi3_cmp_rex64"
13034 [(set (reg FLAGS_REG)
13036 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13037 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13039 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13040 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13042 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13043 && ix86_match_ccmode (insn, CCGOCmode)
13044 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13045 "shr{q}\t{%2, %0|%0, %2}"
13046 [(set_attr "type" "ishift")
13047 (set_attr "mode" "DI")])
13049 (define_insn "*lshrdi3_cconly_rex64"
13050 [(set (reg FLAGS_REG)
13052 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13055 (clobber (match_scratch:DI 0 "=r"))]
13057 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060 "shr{q}\t{%2, %0|%0, %2}"
13061 [(set_attr "type" "ishift")
13062 (set_attr "mode" "DI")])
13064 (define_insn "*lshrdi3_1"
13065 [(set (match_operand:DI 0 "register_operand" "=r")
13066 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13067 (match_operand:QI 2 "nonmemory_operand" "Jc")))
13068 (clobber (reg:CC FLAGS_REG))]
13071 [(set_attr "type" "multi")])
13073 ;; By default we don't ask for a scratch register, because when DImode
13074 ;; values are manipulated, registers are already at a premium. But if
13075 ;; we have one handy, we won't turn it away.
13077 [(match_scratch:SI 3 "r")
13078 (parallel [(set (match_operand:DI 0 "register_operand" "")
13079 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13080 (match_operand:QI 2 "nonmemory_operand" "")))
13081 (clobber (reg:CC FLAGS_REG))])
13083 "!TARGET_64BIT && TARGET_CMOVE"
13085 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13088 [(set (match_operand:DI 0 "register_operand" "")
13089 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13090 (match_operand:QI 2 "nonmemory_operand" "")))
13091 (clobber (reg:CC FLAGS_REG))]
13092 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13093 ? epilogue_completed : reload_completed)"
13095 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13097 (define_expand "lshrsi3"
13098 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13099 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13100 (match_operand:QI 2 "nonmemory_operand" "")))]
13102 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13104 (define_insn "*lshrsi3_1_one_bit"
13105 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13107 (match_operand:QI 2 "const1_operand" "")))
13108 (clobber (reg:CC FLAGS_REG))]
13109 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13112 [(set_attr "type" "ishift")
13113 (set (attr "length")
13114 (if_then_else (match_operand:SI 0 "register_operand" "")
13116 (const_string "*")))])
13118 (define_insn "*lshrsi3_1_one_bit_zext"
13119 [(set (match_operand:DI 0 "register_operand" "=r")
13120 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13121 (match_operand:QI 2 "const1_operand" "")))
13122 (clobber (reg:CC FLAGS_REG))]
13124 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13125 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13127 [(set_attr "type" "ishift")
13128 (set_attr "length" "2")])
13130 (define_insn "*lshrsi3_1"
13131 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13132 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13133 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13134 (clobber (reg:CC FLAGS_REG))]
13135 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13137 shr{l}\t{%2, %0|%0, %2}
13138 shr{l}\t{%b2, %0|%0, %b2}"
13139 [(set_attr "type" "ishift")
13140 (set_attr "mode" "SI")])
13142 (define_insn "*lshrsi3_1_zext"
13143 [(set (match_operand:DI 0 "register_operand" "=r,r")
13145 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13146 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13147 (clobber (reg:CC FLAGS_REG))]
13148 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13150 shr{l}\t{%2, %k0|%k0, %2}
13151 shr{l}\t{%b2, %k0|%k0, %b2}"
13152 [(set_attr "type" "ishift")
13153 (set_attr "mode" "SI")])
13155 ;; This pattern can't accept a variable shift count, since shifts by
13156 ;; zero don't affect the flags. We assume that shifts by constant
13157 ;; zero are optimized away.
13158 (define_insn "*lshrsi3_one_bit_cmp"
13159 [(set (reg FLAGS_REG)
13161 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162 (match_operand:QI 2 "const1_operand" ""))
13164 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13165 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13166 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13167 && ix86_match_ccmode (insn, CCGOCmode)
13168 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13170 [(set_attr "type" "ishift")
13171 (set (attr "length")
13172 (if_then_else (match_operand:SI 0 "register_operand" "")
13174 (const_string "*")))])
13176 (define_insn "*lshrsi3_one_bit_cconly"
13177 [(set (reg FLAGS_REG)
13179 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180 (match_operand:QI 2 "const1_operand" ""))
13182 (clobber (match_scratch:SI 0 "=r"))]
13183 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13184 && ix86_match_ccmode (insn, CCGOCmode)
13185 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13187 [(set_attr "type" "ishift")
13188 (set_attr "length" "2")])
13190 (define_insn "*lshrsi3_cmp_one_bit_zext"
13191 [(set (reg FLAGS_REG)
13193 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13194 (match_operand:QI 2 "const1_operand" ""))
13196 (set (match_operand:DI 0 "register_operand" "=r")
13197 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13199 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13200 && ix86_match_ccmode (insn, CCGOCmode)
13201 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13203 [(set_attr "type" "ishift")
13204 (set_attr "length" "2")])
13206 ;; This pattern can't accept a variable shift count, since shifts by
13207 ;; zero don't affect the flags. We assume that shifts by constant
13208 ;; zero are optimized away.
13209 (define_insn "*lshrsi3_cmp"
13210 [(set (reg FLAGS_REG)
13212 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13213 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13215 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13216 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13217 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13218 && ix86_match_ccmode (insn, CCGOCmode)
13219 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13220 "shr{l}\t{%2, %0|%0, %2}"
13221 [(set_attr "type" "ishift")
13222 (set_attr "mode" "SI")])
13224 (define_insn "*lshrsi3_cconly"
13225 [(set (reg FLAGS_REG)
13227 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13228 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13230 (clobber (match_scratch:SI 0 "=r"))]
13231 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13232 && ix86_match_ccmode (insn, CCGOCmode)
13233 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13234 "shr{l}\t{%2, %0|%0, %2}"
13235 [(set_attr "type" "ishift")
13236 (set_attr "mode" "SI")])
13238 (define_insn "*lshrsi3_cmp_zext"
13239 [(set (reg FLAGS_REG)
13241 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13242 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13244 (set (match_operand:DI 0 "register_operand" "=r")
13245 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13247 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13248 && ix86_match_ccmode (insn, CCGOCmode)
13249 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13250 "shr{l}\t{%2, %k0|%k0, %2}"
13251 [(set_attr "type" "ishift")
13252 (set_attr "mode" "SI")])
13254 (define_expand "lshrhi3"
13255 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13256 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13257 (match_operand:QI 2 "nonmemory_operand" "")))]
13258 "TARGET_HIMODE_MATH"
13259 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13261 (define_insn "*lshrhi3_1_one_bit"
13262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13263 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13264 (match_operand:QI 2 "const1_operand" "")))
13265 (clobber (reg:CC FLAGS_REG))]
13266 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13267 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13269 [(set_attr "type" "ishift")
13270 (set (attr "length")
13271 (if_then_else (match_operand 0 "register_operand" "")
13273 (const_string "*")))])
13275 (define_insn "*lshrhi3_1"
13276 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13277 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13278 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13279 (clobber (reg:CC FLAGS_REG))]
13280 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13282 shr{w}\t{%2, %0|%0, %2}
13283 shr{w}\t{%b2, %0|%0, %b2}"
13284 [(set_attr "type" "ishift")
13285 (set_attr "mode" "HI")])
13287 ;; This pattern can't accept a variable shift count, since shifts by
13288 ;; zero don't affect the flags. We assume that shifts by constant
13289 ;; zero are optimized away.
13290 (define_insn "*lshrhi3_one_bit_cmp"
13291 [(set (reg FLAGS_REG)
13293 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13294 (match_operand:QI 2 "const1_operand" ""))
13296 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13297 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13298 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13299 && ix86_match_ccmode (insn, CCGOCmode)
13300 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13302 [(set_attr "type" "ishift")
13303 (set (attr "length")
13304 (if_then_else (match_operand:SI 0 "register_operand" "")
13306 (const_string "*")))])
13308 (define_insn "*lshrhi3_one_bit_cconly"
13309 [(set (reg FLAGS_REG)
13311 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13312 (match_operand:QI 2 "const1_operand" ""))
13314 (clobber (match_scratch:HI 0 "=r"))]
13315 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316 && ix86_match_ccmode (insn, CCGOCmode)
13317 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13319 [(set_attr "type" "ishift")
13320 (set_attr "length" "2")])
13322 ;; This pattern can't accept a variable shift count, since shifts by
13323 ;; zero don't affect the flags. We assume that shifts by constant
13324 ;; zero are optimized away.
13325 (define_insn "*lshrhi3_cmp"
13326 [(set (reg FLAGS_REG)
13328 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13329 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13331 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13332 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13333 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13334 && ix86_match_ccmode (insn, CCGOCmode)
13335 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13336 "shr{w}\t{%2, %0|%0, %2}"
13337 [(set_attr "type" "ishift")
13338 (set_attr "mode" "HI")])
13340 (define_insn "*lshrhi3_cconly"
13341 [(set (reg FLAGS_REG)
13343 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13344 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13346 (clobber (match_scratch:HI 0 "=r"))]
13347 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13348 && ix86_match_ccmode (insn, CCGOCmode)
13349 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13350 "shr{w}\t{%2, %0|%0, %2}"
13351 [(set_attr "type" "ishift")
13352 (set_attr "mode" "HI")])
13354 (define_expand "lshrqi3"
13355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13356 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13357 (match_operand:QI 2 "nonmemory_operand" "")))]
13358 "TARGET_QIMODE_MATH"
13359 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13361 (define_insn "*lshrqi3_1_one_bit"
13362 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13363 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13364 (match_operand:QI 2 "const1_operand" "")))
13365 (clobber (reg:CC FLAGS_REG))]
13366 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13367 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13369 [(set_attr "type" "ishift")
13370 (set (attr "length")
13371 (if_then_else (match_operand 0 "register_operand" "")
13373 (const_string "*")))])
13375 (define_insn "*lshrqi3_1_one_bit_slp"
13376 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13377 (lshiftrt:QI (match_dup 0)
13378 (match_operand:QI 1 "const1_operand" "")))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13381 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13383 [(set_attr "type" "ishift1")
13384 (set (attr "length")
13385 (if_then_else (match_operand 0 "register_operand" "")
13387 (const_string "*")))])
13389 (define_insn "*lshrqi3_1"
13390 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13391 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13392 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13393 (clobber (reg:CC FLAGS_REG))]
13394 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13396 shr{b}\t{%2, %0|%0, %2}
13397 shr{b}\t{%b2, %0|%0, %b2}"
13398 [(set_attr "type" "ishift")
13399 (set_attr "mode" "QI")])
13401 (define_insn "*lshrqi3_1_slp"
13402 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13403 (lshiftrt:QI (match_dup 0)
13404 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13405 (clobber (reg:CC FLAGS_REG))]
13406 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13407 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13409 shr{b}\t{%1, %0|%0, %1}
13410 shr{b}\t{%b1, %0|%0, %b1}"
13411 [(set_attr "type" "ishift1")
13412 (set_attr "mode" "QI")])
13414 ;; This pattern can't accept a variable shift count, since shifts by
13415 ;; zero don't affect the flags. We assume that shifts by constant
13416 ;; zero are optimized away.
13417 (define_insn "*lshrqi2_one_bit_cmp"
13418 [(set (reg FLAGS_REG)
13420 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13421 (match_operand:QI 2 "const1_operand" ""))
13423 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13424 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13425 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13426 && ix86_match_ccmode (insn, CCGOCmode)
13427 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13429 [(set_attr "type" "ishift")
13430 (set (attr "length")
13431 (if_then_else (match_operand:SI 0 "register_operand" "")
13433 (const_string "*")))])
13435 (define_insn "*lshrqi2_one_bit_cconly"
13436 [(set (reg FLAGS_REG)
13438 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13439 (match_operand:QI 2 "const1_operand" ""))
13441 (clobber (match_scratch:QI 0 "=q"))]
13442 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13443 && ix86_match_ccmode (insn, CCGOCmode)
13444 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13446 [(set_attr "type" "ishift")
13447 (set_attr "length" "2")])
13449 ;; This pattern can't accept a variable shift count, since shifts by
13450 ;; zero don't affect the flags. We assume that shifts by constant
13451 ;; zero are optimized away.
13452 (define_insn "*lshrqi2_cmp"
13453 [(set (reg FLAGS_REG)
13455 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13456 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13458 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13459 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13460 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13461 && ix86_match_ccmode (insn, CCGOCmode)
13462 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13463 "shr{b}\t{%2, %0|%0, %2}"
13464 [(set_attr "type" "ishift")
13465 (set_attr "mode" "QI")])
13467 (define_insn "*lshrqi2_cconly"
13468 [(set (reg FLAGS_REG)
13470 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13471 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13473 (clobber (match_scratch:QI 0 "=q"))]
13474 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13475 && ix86_match_ccmode (insn, CCGOCmode)
13476 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13477 "shr{b}\t{%2, %0|%0, %2}"
13478 [(set_attr "type" "ishift")
13479 (set_attr "mode" "QI")])
13481 ;; Rotate instructions
13483 (define_expand "rotldi3"
13484 [(set (match_operand:DI 0 "shiftdi_operand" "")
13485 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13486 (match_operand:QI 2 "nonmemory_operand" "")))]
13491 ix86_expand_binary_operator (ROTATE, DImode, operands);
13494 if (!const_1_to_31_operand (operands[2], VOIDmode))
13496 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13500 ;; Implement rotation using two double-precision shift instructions
13501 ;; and a scratch register.
13502 (define_insn_and_split "ix86_rotldi3"
13503 [(set (match_operand:DI 0 "register_operand" "=r")
13504 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13505 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13506 (clobber (reg:CC FLAGS_REG))
13507 (clobber (match_scratch:SI 3 "=&r"))]
13510 "&& reload_completed"
13511 [(set (match_dup 3) (match_dup 4))
13513 [(set (match_dup 4)
13514 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13515 (lshiftrt:SI (match_dup 5)
13516 (minus:QI (const_int 32) (match_dup 2)))))
13517 (clobber (reg:CC FLAGS_REG))])
13519 [(set (match_dup 5)
13520 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13521 (lshiftrt:SI (match_dup 3)
13522 (minus:QI (const_int 32) (match_dup 2)))))
13523 (clobber (reg:CC FLAGS_REG))])]
13524 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13526 (define_insn "*rotlsi3_1_one_bit_rex64"
13527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13528 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13529 (match_operand:QI 2 "const1_operand" "")))
13530 (clobber (reg:CC FLAGS_REG))]
13532 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13533 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13535 [(set_attr "type" "rotate")
13536 (set (attr "length")
13537 (if_then_else (match_operand:DI 0 "register_operand" "")
13539 (const_string "*")))])
13541 (define_insn "*rotldi3_1_rex64"
13542 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13543 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13544 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13545 (clobber (reg:CC FLAGS_REG))]
13546 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13548 rol{q}\t{%2, %0|%0, %2}
13549 rol{q}\t{%b2, %0|%0, %b2}"
13550 [(set_attr "type" "rotate")
13551 (set_attr "mode" "DI")])
13553 (define_expand "rotlsi3"
13554 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13555 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13556 (match_operand:QI 2 "nonmemory_operand" "")))]
13558 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13560 (define_insn "*rotlsi3_1_one_bit"
13561 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13562 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13563 (match_operand:QI 2 "const1_operand" "")))
13564 (clobber (reg:CC FLAGS_REG))]
13565 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13566 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13568 [(set_attr "type" "rotate")
13569 (set (attr "length")
13570 (if_then_else (match_operand:SI 0 "register_operand" "")
13572 (const_string "*")))])
13574 (define_insn "*rotlsi3_1_one_bit_zext"
13575 [(set (match_operand:DI 0 "register_operand" "=r")
13577 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13578 (match_operand:QI 2 "const1_operand" ""))))
13579 (clobber (reg:CC FLAGS_REG))]
13581 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13582 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13584 [(set_attr "type" "rotate")
13585 (set_attr "length" "2")])
13587 (define_insn "*rotlsi3_1"
13588 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13589 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13590 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13591 (clobber (reg:CC FLAGS_REG))]
13592 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13594 rol{l}\t{%2, %0|%0, %2}
13595 rol{l}\t{%b2, %0|%0, %b2}"
13596 [(set_attr "type" "rotate")
13597 (set_attr "mode" "SI")])
13599 (define_insn "*rotlsi3_1_zext"
13600 [(set (match_operand:DI 0 "register_operand" "=r,r")
13602 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13603 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13604 (clobber (reg:CC FLAGS_REG))]
13605 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13607 rol{l}\t{%2, %k0|%k0, %2}
13608 rol{l}\t{%b2, %k0|%k0, %b2}"
13609 [(set_attr "type" "rotate")
13610 (set_attr "mode" "SI")])
13612 (define_expand "rotlhi3"
13613 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13614 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13615 (match_operand:QI 2 "nonmemory_operand" "")))]
13616 "TARGET_HIMODE_MATH"
13617 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13619 (define_insn "*rotlhi3_1_one_bit"
13620 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13621 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13622 (match_operand:QI 2 "const1_operand" "")))
13623 (clobber (reg:CC FLAGS_REG))]
13624 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13625 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13627 [(set_attr "type" "rotate")
13628 (set (attr "length")
13629 (if_then_else (match_operand 0 "register_operand" "")
13631 (const_string "*")))])
13633 (define_insn "*rotlhi3_1"
13634 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13635 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13636 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13637 (clobber (reg:CC FLAGS_REG))]
13638 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13640 rol{w}\t{%2, %0|%0, %2}
13641 rol{w}\t{%b2, %0|%0, %b2}"
13642 [(set_attr "type" "rotate")
13643 (set_attr "mode" "HI")])
13646 [(set (match_operand:HI 0 "register_operand" "")
13647 (rotate:HI (match_dup 0) (const_int 8)))
13648 (clobber (reg:CC FLAGS_REG))]
13650 [(parallel [(set (strict_low_part (match_dup 0))
13651 (bswap:HI (match_dup 0)))
13652 (clobber (reg:CC FLAGS_REG))])]
13655 (define_expand "rotlqi3"
13656 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13657 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13658 (match_operand:QI 2 "nonmemory_operand" "")))]
13659 "TARGET_QIMODE_MATH"
13660 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13662 (define_insn "*rotlqi3_1_one_bit_slp"
13663 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13664 (rotate:QI (match_dup 0)
13665 (match_operand:QI 1 "const1_operand" "")))
13666 (clobber (reg:CC FLAGS_REG))]
13667 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13668 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13670 [(set_attr "type" "rotate1")
13671 (set (attr "length")
13672 (if_then_else (match_operand 0 "register_operand" "")
13674 (const_string "*")))])
13676 (define_insn "*rotlqi3_1_one_bit"
13677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13678 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13679 (match_operand:QI 2 "const1_operand" "")))
13680 (clobber (reg:CC FLAGS_REG))]
13681 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13682 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13684 [(set_attr "type" "rotate")
13685 (set (attr "length")
13686 (if_then_else (match_operand 0 "register_operand" "")
13688 (const_string "*")))])
13690 (define_insn "*rotlqi3_1_slp"
13691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13692 (rotate:QI (match_dup 0)
13693 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13694 (clobber (reg:CC FLAGS_REG))]
13695 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13698 rol{b}\t{%1, %0|%0, %1}
13699 rol{b}\t{%b1, %0|%0, %b1}"
13700 [(set_attr "type" "rotate1")
13701 (set_attr "mode" "QI")])
13703 (define_insn "*rotlqi3_1"
13704 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13705 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13706 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13707 (clobber (reg:CC FLAGS_REG))]
13708 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13710 rol{b}\t{%2, %0|%0, %2}
13711 rol{b}\t{%b2, %0|%0, %b2}"
13712 [(set_attr "type" "rotate")
13713 (set_attr "mode" "QI")])
13715 (define_expand "rotrdi3"
13716 [(set (match_operand:DI 0 "shiftdi_operand" "")
13717 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13718 (match_operand:QI 2 "nonmemory_operand" "")))]
13723 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13726 if (!const_1_to_31_operand (operands[2], VOIDmode))
13728 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13732 ;; Implement rotation using two double-precision shift instructions
13733 ;; and a scratch register.
13734 (define_insn_and_split "ix86_rotrdi3"
13735 [(set (match_operand:DI 0 "register_operand" "=r")
13736 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13737 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13738 (clobber (reg:CC FLAGS_REG))
13739 (clobber (match_scratch:SI 3 "=&r"))]
13742 "&& reload_completed"
13743 [(set (match_dup 3) (match_dup 4))
13745 [(set (match_dup 4)
13746 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13747 (ashift:SI (match_dup 5)
13748 (minus:QI (const_int 32) (match_dup 2)))))
13749 (clobber (reg:CC FLAGS_REG))])
13751 [(set (match_dup 5)
13752 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13753 (ashift:SI (match_dup 3)
13754 (minus:QI (const_int 32) (match_dup 2)))))
13755 (clobber (reg:CC FLAGS_REG))])]
13756 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13758 (define_insn "*rotrdi3_1_one_bit_rex64"
13759 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13760 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13761 (match_operand:QI 2 "const1_operand" "")))
13762 (clobber (reg:CC FLAGS_REG))]
13764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13765 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13767 [(set_attr "type" "rotate")
13768 (set (attr "length")
13769 (if_then_else (match_operand:DI 0 "register_operand" "")
13771 (const_string "*")))])
13773 (define_insn "*rotrdi3_1_rex64"
13774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13775 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13776 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13777 (clobber (reg:CC FLAGS_REG))]
13778 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13780 ror{q}\t{%2, %0|%0, %2}
13781 ror{q}\t{%b2, %0|%0, %b2}"
13782 [(set_attr "type" "rotate")
13783 (set_attr "mode" "DI")])
13785 (define_expand "rotrsi3"
13786 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13787 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13788 (match_operand:QI 2 "nonmemory_operand" "")))]
13790 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13792 (define_insn "*rotrsi3_1_one_bit"
13793 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13794 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13795 (match_operand:QI 2 "const1_operand" "")))
13796 (clobber (reg:CC FLAGS_REG))]
13797 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13798 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13800 [(set_attr "type" "rotate")
13801 (set (attr "length")
13802 (if_then_else (match_operand:SI 0 "register_operand" "")
13804 (const_string "*")))])
13806 (define_insn "*rotrsi3_1_one_bit_zext"
13807 [(set (match_operand:DI 0 "register_operand" "=r")
13809 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13810 (match_operand:QI 2 "const1_operand" ""))))
13811 (clobber (reg:CC FLAGS_REG))]
13813 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13814 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13816 [(set_attr "type" "rotate")
13817 (set (attr "length")
13818 (if_then_else (match_operand:SI 0 "register_operand" "")
13820 (const_string "*")))])
13822 (define_insn "*rotrsi3_1"
13823 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13824 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13825 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13826 (clobber (reg:CC FLAGS_REG))]
13827 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13829 ror{l}\t{%2, %0|%0, %2}
13830 ror{l}\t{%b2, %0|%0, %b2}"
13831 [(set_attr "type" "rotate")
13832 (set_attr "mode" "SI")])
13834 (define_insn "*rotrsi3_1_zext"
13835 [(set (match_operand:DI 0 "register_operand" "=r,r")
13837 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13838 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13839 (clobber (reg:CC FLAGS_REG))]
13840 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13842 ror{l}\t{%2, %k0|%k0, %2}
13843 ror{l}\t{%b2, %k0|%k0, %b2}"
13844 [(set_attr "type" "rotate")
13845 (set_attr "mode" "SI")])
13847 (define_expand "rotrhi3"
13848 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13849 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13850 (match_operand:QI 2 "nonmemory_operand" "")))]
13851 "TARGET_HIMODE_MATH"
13852 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13854 (define_insn "*rotrhi3_one_bit"
13855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13856 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13857 (match_operand:QI 2 "const1_operand" "")))
13858 (clobber (reg:CC FLAGS_REG))]
13859 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13860 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13862 [(set_attr "type" "rotate")
13863 (set (attr "length")
13864 (if_then_else (match_operand 0 "register_operand" "")
13866 (const_string "*")))])
13868 (define_insn "*rotrhi3_1"
13869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13870 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13871 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13872 (clobber (reg:CC FLAGS_REG))]
13873 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13875 ror{w}\t{%2, %0|%0, %2}
13876 ror{w}\t{%b2, %0|%0, %b2}"
13877 [(set_attr "type" "rotate")
13878 (set_attr "mode" "HI")])
13881 [(set (match_operand:HI 0 "register_operand" "")
13882 (rotatert:HI (match_dup 0) (const_int 8)))
13883 (clobber (reg:CC FLAGS_REG))]
13885 [(parallel [(set (strict_low_part (match_dup 0))
13886 (bswap:HI (match_dup 0)))
13887 (clobber (reg:CC FLAGS_REG))])]
13890 (define_expand "rotrqi3"
13891 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13892 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13893 (match_operand:QI 2 "nonmemory_operand" "")))]
13894 "TARGET_QIMODE_MATH"
13895 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13897 (define_insn "*rotrqi3_1_one_bit"
13898 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13899 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13900 (match_operand:QI 2 "const1_operand" "")))
13901 (clobber (reg:CC FLAGS_REG))]
13902 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13903 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13905 [(set_attr "type" "rotate")
13906 (set (attr "length")
13907 (if_then_else (match_operand 0 "register_operand" "")
13909 (const_string "*")))])
13911 (define_insn "*rotrqi3_1_one_bit_slp"
13912 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13913 (rotatert:QI (match_dup 0)
13914 (match_operand:QI 1 "const1_operand" "")))
13915 (clobber (reg:CC FLAGS_REG))]
13916 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13917 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13919 [(set_attr "type" "rotate1")
13920 (set (attr "length")
13921 (if_then_else (match_operand 0 "register_operand" "")
13923 (const_string "*")))])
13925 (define_insn "*rotrqi3_1"
13926 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13927 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13928 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13929 (clobber (reg:CC FLAGS_REG))]
13930 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13932 ror{b}\t{%2, %0|%0, %2}
13933 ror{b}\t{%b2, %0|%0, %b2}"
13934 [(set_attr "type" "rotate")
13935 (set_attr "mode" "QI")])
13937 (define_insn "*rotrqi3_1_slp"
13938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13939 (rotatert:QI (match_dup 0)
13940 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13941 (clobber (reg:CC FLAGS_REG))]
13942 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13943 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13945 ror{b}\t{%1, %0|%0, %1}
13946 ror{b}\t{%b1, %0|%0, %b1}"
13947 [(set_attr "type" "rotate1")
13948 (set_attr "mode" "QI")])
13950 ;; Bit set / bit test instructions
13952 (define_expand "extv"
13953 [(set (match_operand:SI 0 "register_operand" "")
13954 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13955 (match_operand:SI 2 "const8_operand" "")
13956 (match_operand:SI 3 "const8_operand" "")))]
13959 /* Handle extractions from %ah et al. */
13960 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13963 /* From mips.md: extract_bit_field doesn't verify that our source
13964 matches the predicate, so check it again here. */
13965 if (! ext_register_operand (operands[1], VOIDmode))
13969 (define_expand "extzv"
13970 [(set (match_operand:SI 0 "register_operand" "")
13971 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13972 (match_operand:SI 2 "const8_operand" "")
13973 (match_operand:SI 3 "const8_operand" "")))]
13976 /* Handle extractions from %ah et al. */
13977 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13980 /* From mips.md: extract_bit_field doesn't verify that our source
13981 matches the predicate, so check it again here. */
13982 if (! ext_register_operand (operands[1], VOIDmode))
13986 (define_expand "insv"
13987 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13988 (match_operand 1 "const8_operand" "")
13989 (match_operand 2 "const8_operand" ""))
13990 (match_operand 3 "register_operand" ""))]
13993 /* Handle insertions to %ah et al. */
13994 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13997 /* From mips.md: insert_bit_field doesn't verify that our source
13998 matches the predicate, so check it again here. */
13999 if (! ext_register_operand (operands[0], VOIDmode))
14003 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14005 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14010 ;; %%% bts, btr, btc, bt.
14011 ;; In general these instructions are *slow* when applied to memory,
14012 ;; since they enforce atomic operation. When applied to registers,
14013 ;; it depends on the cpu implementation. They're never faster than
14014 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14015 ;; no point. But in 64-bit, we can't hold the relevant immediates
14016 ;; within the instruction itself, so operating on bits in the high
14017 ;; 32-bits of a register becomes easier.
14019 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
14020 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14021 ;; negdf respectively, so they can never be disabled entirely.
14023 (define_insn "*btsq"
14024 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14026 (match_operand:DI 1 "const_0_to_63_operand" ""))
14028 (clobber (reg:CC FLAGS_REG))]
14029 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14030 "bts{q}\t{%1, %0|%0, %1}"
14031 [(set_attr "type" "alu1")])
14033 (define_insn "*btrq"
14034 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14036 (match_operand:DI 1 "const_0_to_63_operand" ""))
14038 (clobber (reg:CC FLAGS_REG))]
14039 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14040 "btr{q}\t{%1, %0|%0, %1}"
14041 [(set_attr "type" "alu1")])
14043 (define_insn "*btcq"
14044 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14046 (match_operand:DI 1 "const_0_to_63_operand" ""))
14047 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14048 (clobber (reg:CC FLAGS_REG))]
14049 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14050 "btc{q}\t{%1, %0|%0, %1}"
14051 [(set_attr "type" "alu1")])
14053 ;; Allow Nocona to avoid these instructions if a register is available.
14056 [(match_scratch:DI 2 "r")
14057 (parallel [(set (zero_extract:DI
14058 (match_operand:DI 0 "register_operand" "")
14060 (match_operand:DI 1 "const_0_to_63_operand" ""))
14062 (clobber (reg:CC FLAGS_REG))])]
14063 "TARGET_64BIT && !TARGET_USE_BT"
14066 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14069 if (HOST_BITS_PER_WIDE_INT >= 64)
14070 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14071 else if (i < HOST_BITS_PER_WIDE_INT)
14072 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14074 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14076 op1 = immed_double_const (lo, hi, DImode);
14079 emit_move_insn (operands[2], op1);
14083 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14088 [(match_scratch:DI 2 "r")
14089 (parallel [(set (zero_extract:DI
14090 (match_operand:DI 0 "register_operand" "")
14092 (match_operand:DI 1 "const_0_to_63_operand" ""))
14094 (clobber (reg:CC FLAGS_REG))])]
14095 "TARGET_64BIT && !TARGET_USE_BT"
14098 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14101 if (HOST_BITS_PER_WIDE_INT >= 64)
14102 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14103 else if (i < HOST_BITS_PER_WIDE_INT)
14104 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14106 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14108 op1 = immed_double_const (~lo, ~hi, DImode);
14111 emit_move_insn (operands[2], op1);
14115 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14120 [(match_scratch:DI 2 "r")
14121 (parallel [(set (zero_extract:DI
14122 (match_operand:DI 0 "register_operand" "")
14124 (match_operand:DI 1 "const_0_to_63_operand" ""))
14125 (not:DI (zero_extract:DI
14126 (match_dup 0) (const_int 1) (match_dup 1))))
14127 (clobber (reg:CC FLAGS_REG))])]
14128 "TARGET_64BIT && !TARGET_USE_BT"
14131 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14134 if (HOST_BITS_PER_WIDE_INT >= 64)
14135 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14136 else if (i < HOST_BITS_PER_WIDE_INT)
14137 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14139 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14141 op1 = immed_double_const (lo, hi, DImode);
14144 emit_move_insn (operands[2], op1);
14148 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14152 (define_insn "*btdi_rex64"
14153 [(set (reg:CCC FLAGS_REG)
14156 (match_operand:DI 0 "register_operand" "r")
14158 (match_operand:DI 1 "nonmemory_operand" "rN"))
14160 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14161 "bt{q}\t{%1, %0|%0, %1}"
14162 [(set_attr "type" "alu1")])
14164 (define_insn "*btsi"
14165 [(set (reg:CCC FLAGS_REG)
14168 (match_operand:SI 0 "register_operand" "r")
14170 (match_operand:SI 1 "nonmemory_operand" "rN"))
14172 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14173 "bt{l}\t{%1, %0|%0, %1}"
14174 [(set_attr "type" "alu1")])
14176 ;; Store-flag instructions.
14178 ;; For all sCOND expanders, also expand the compare or test insn that
14179 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14181 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14182 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14183 ;; way, which can later delete the movzx if only QImode is needed.
14185 (define_expand "s<code>"
14186 [(set (match_operand:QI 0 "register_operand" "")
14187 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14189 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14191 (define_expand "s<code>"
14192 [(set (match_operand:QI 0 "register_operand" "")
14193 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14194 "TARGET_80387 || TARGET_SSE"
14195 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14197 (define_insn "*setcc_1"
14198 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14199 (match_operator:QI 1 "ix86_comparison_operator"
14200 [(reg FLAGS_REG) (const_int 0)]))]
14203 [(set_attr "type" "setcc")
14204 (set_attr "mode" "QI")])
14206 (define_insn "*setcc_2"
14207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14208 (match_operator:QI 1 "ix86_comparison_operator"
14209 [(reg FLAGS_REG) (const_int 0)]))]
14212 [(set_attr "type" "setcc")
14213 (set_attr "mode" "QI")])
14215 ;; In general it is not safe to assume too much about CCmode registers,
14216 ;; so simplify-rtx stops when it sees a second one. Under certain
14217 ;; conditions this is safe on x86, so help combine not create
14224 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14225 (ne:QI (match_operator 1 "ix86_comparison_operator"
14226 [(reg FLAGS_REG) (const_int 0)])
14229 [(set (match_dup 0) (match_dup 1))]
14231 PUT_MODE (operands[1], QImode);
14235 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14236 (ne:QI (match_operator 1 "ix86_comparison_operator"
14237 [(reg FLAGS_REG) (const_int 0)])
14240 [(set (match_dup 0) (match_dup 1))]
14242 PUT_MODE (operands[1], QImode);
14246 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14247 (eq:QI (match_operator 1 "ix86_comparison_operator"
14248 [(reg FLAGS_REG) (const_int 0)])
14251 [(set (match_dup 0) (match_dup 1))]
14253 rtx new_op1 = copy_rtx (operands[1]);
14254 operands[1] = new_op1;
14255 PUT_MODE (new_op1, QImode);
14256 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14257 GET_MODE (XEXP (new_op1, 0))));
14259 /* Make sure that (a) the CCmode we have for the flags is strong
14260 enough for the reversed compare or (b) we have a valid FP compare. */
14261 if (! ix86_comparison_operator (new_op1, VOIDmode))
14266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14267 (eq:QI (match_operator 1 "ix86_comparison_operator"
14268 [(reg FLAGS_REG) (const_int 0)])
14271 [(set (match_dup 0) (match_dup 1))]
14273 rtx new_op1 = copy_rtx (operands[1]);
14274 operands[1] = new_op1;
14275 PUT_MODE (new_op1, QImode);
14276 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14277 GET_MODE (XEXP (new_op1, 0))));
14279 /* Make sure that (a) the CCmode we have for the flags is strong
14280 enough for the reversed compare or (b) we have a valid FP compare. */
14281 if (! ix86_comparison_operator (new_op1, VOIDmode))
14285 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14286 ;; subsequent logical operations are used to imitate conditional moves.
14287 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14290 (define_insn "*avx_setcc<mode>"
14291 [(set (match_operand:MODEF 0 "register_operand" "=x")
14292 (match_operator:MODEF 1 "avx_comparison_float_operator"
14293 [(match_operand:MODEF 2 "register_operand" "x")
14294 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14296 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14297 [(set_attr "type" "ssecmp")
14298 (set_attr "prefix" "vex")
14299 (set_attr "mode" "<MODE>")])
14301 (define_insn "*sse_setcc<mode>"
14302 [(set (match_operand:MODEF 0 "register_operand" "=x")
14303 (match_operator:MODEF 1 "sse_comparison_operator"
14304 [(match_operand:MODEF 2 "register_operand" "0")
14305 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14306 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14307 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14308 [(set_attr "type" "ssecmp")
14309 (set_attr "mode" "<MODE>")])
14311 (define_insn "*sse5_setcc<mode>"
14312 [(set (match_operand:MODEF 0 "register_operand" "=x")
14313 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14314 [(match_operand:MODEF 2 "register_operand" "x")
14315 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14317 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14318 [(set_attr "type" "sse4arg")
14319 (set_attr "mode" "<MODE>")])
14322 ;; Basic conditional jump instructions.
14323 ;; We ignore the overflow flag for signed branch instructions.
14325 ;; For all bCOND expanders, also expand the compare or test insn that
14326 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14328 (define_expand "b<code>"
14330 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14332 (label_ref (match_operand 0 ""))
14335 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14337 (define_expand "b<code>"
14339 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14341 (label_ref (match_operand 0 ""))
14343 "TARGET_80387 || TARGET_SSE_MATH"
14344 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14346 (define_insn "*jcc_1"
14348 (if_then_else (match_operator 1 "ix86_comparison_operator"
14349 [(reg FLAGS_REG) (const_int 0)])
14350 (label_ref (match_operand 0 "" ""))
14354 [(set_attr "type" "ibr")
14355 (set_attr "modrm" "0")
14356 (set (attr "length")
14357 (if_then_else (and (ge (minus (match_dup 0) (pc))
14359 (lt (minus (match_dup 0) (pc))
14364 (define_insn "*jcc_2"
14366 (if_then_else (match_operator 1 "ix86_comparison_operator"
14367 [(reg FLAGS_REG) (const_int 0)])
14369 (label_ref (match_operand 0 "" ""))))]
14372 [(set_attr "type" "ibr")
14373 (set_attr "modrm" "0")
14374 (set (attr "length")
14375 (if_then_else (and (ge (minus (match_dup 0) (pc))
14377 (lt (minus (match_dup 0) (pc))
14382 ;; In general it is not safe to assume too much about CCmode registers,
14383 ;; so simplify-rtx stops when it sees a second one. Under certain
14384 ;; conditions this is safe on x86, so help combine not create
14392 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14393 [(reg FLAGS_REG) (const_int 0)])
14395 (label_ref (match_operand 1 "" ""))
14399 (if_then_else (match_dup 0)
14400 (label_ref (match_dup 1))
14403 PUT_MODE (operands[0], VOIDmode);
14408 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14409 [(reg FLAGS_REG) (const_int 0)])
14411 (label_ref (match_operand 1 "" ""))
14415 (if_then_else (match_dup 0)
14416 (label_ref (match_dup 1))
14419 rtx new_op0 = copy_rtx (operands[0]);
14420 operands[0] = new_op0;
14421 PUT_MODE (new_op0, VOIDmode);
14422 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14423 GET_MODE (XEXP (new_op0, 0))));
14425 /* Make sure that (a) the CCmode we have for the flags is strong
14426 enough for the reversed compare or (b) we have a valid FP compare. */
14427 if (! ix86_comparison_operator (new_op0, VOIDmode))
14431 ;; zero_extend in SImode is correct, since this is what combine pass
14432 ;; generates from shift insn with QImode operand. Actually, the mode of
14433 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14434 ;; appropriate modulo of the bit offset value.
14436 (define_insn_and_split "*jcc_btdi_rex64"
14438 (if_then_else (match_operator 0 "bt_comparison_operator"
14440 (match_operand:DI 1 "register_operand" "r")
14443 (match_operand:QI 2 "register_operand" "r")))
14445 (label_ref (match_operand 3 "" ""))
14447 (clobber (reg:CC FLAGS_REG))]
14448 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14451 [(set (reg:CCC FLAGS_REG)
14459 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14460 (label_ref (match_dup 3))
14463 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14465 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14468 ;; avoid useless masking of bit offset operand
14469 (define_insn_and_split "*jcc_btdi_mask_rex64"
14471 (if_then_else (match_operator 0 "bt_comparison_operator"
14473 (match_operand:DI 1 "register_operand" "r")
14476 (match_operand:SI 2 "register_operand" "r")
14477 (match_operand:SI 3 "const_int_operand" "n")))])
14478 (label_ref (match_operand 4 "" ""))
14480 (clobber (reg:CC FLAGS_REG))]
14481 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14482 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14485 [(set (reg:CCC FLAGS_REG)
14493 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14494 (label_ref (match_dup 4))
14497 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14499 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14502 (define_insn_and_split "*jcc_btsi"
14504 (if_then_else (match_operator 0 "bt_comparison_operator"
14506 (match_operand:SI 1 "register_operand" "r")
14509 (match_operand:QI 2 "register_operand" "r")))
14511 (label_ref (match_operand 3 "" ""))
14513 (clobber (reg:CC FLAGS_REG))]
14514 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14517 [(set (reg:CCC FLAGS_REG)
14525 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14526 (label_ref (match_dup 3))
14529 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14531 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14534 ;; avoid useless masking of bit offset operand
14535 (define_insn_and_split "*jcc_btsi_mask"
14537 (if_then_else (match_operator 0 "bt_comparison_operator"
14539 (match_operand:SI 1 "register_operand" "r")
14542 (match_operand:SI 2 "register_operand" "r")
14543 (match_operand:SI 3 "const_int_operand" "n")))])
14544 (label_ref (match_operand 4 "" ""))
14546 (clobber (reg:CC FLAGS_REG))]
14547 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14548 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14551 [(set (reg:CCC FLAGS_REG)
14559 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14560 (label_ref (match_dup 4))
14562 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14564 (define_insn_and_split "*jcc_btsi_1"
14566 (if_then_else (match_operator 0 "bt_comparison_operator"
14569 (match_operand:SI 1 "register_operand" "r")
14570 (match_operand:QI 2 "register_operand" "r"))
14573 (label_ref (match_operand 3 "" ""))
14575 (clobber (reg:CC FLAGS_REG))]
14576 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14579 [(set (reg:CCC FLAGS_REG)
14587 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14588 (label_ref (match_dup 3))
14591 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14593 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14596 ;; avoid useless masking of bit offset operand
14597 (define_insn_and_split "*jcc_btsi_mask_1"
14600 (match_operator 0 "bt_comparison_operator"
14603 (match_operand:SI 1 "register_operand" "r")
14606 (match_operand:SI 2 "register_operand" "r")
14607 (match_operand:SI 3 "const_int_operand" "n")) 0))
14610 (label_ref (match_operand 4 "" ""))
14612 (clobber (reg:CC FLAGS_REG))]
14613 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14614 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14617 [(set (reg:CCC FLAGS_REG)
14625 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14626 (label_ref (match_dup 4))
14628 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14630 ;; Define combination compare-and-branch fp compare instructions to use
14631 ;; during early optimization. Splitting the operation apart early makes
14632 ;; for bad code when we want to reverse the operation.
14634 (define_insn "*fp_jcc_1_mixed"
14636 (if_then_else (match_operator 0 "comparison_operator"
14637 [(match_operand 1 "register_operand" "f,x")
14638 (match_operand 2 "nonimmediate_operand" "f,xm")])
14639 (label_ref (match_operand 3 "" ""))
14641 (clobber (reg:CCFP FPSR_REG))
14642 (clobber (reg:CCFP FLAGS_REG))]
14643 "TARGET_MIX_SSE_I387
14644 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14645 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14649 (define_insn "*fp_jcc_1_sse"
14651 (if_then_else (match_operator 0 "comparison_operator"
14652 [(match_operand 1 "register_operand" "x")
14653 (match_operand 2 "nonimmediate_operand" "xm")])
14654 (label_ref (match_operand 3 "" ""))
14656 (clobber (reg:CCFP FPSR_REG))
14657 (clobber (reg:CCFP FLAGS_REG))]
14659 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14660 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14661 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14664 (define_insn "*fp_jcc_1_387"
14666 (if_then_else (match_operator 0 "comparison_operator"
14667 [(match_operand 1 "register_operand" "f")
14668 (match_operand 2 "register_operand" "f")])
14669 (label_ref (match_operand 3 "" ""))
14671 (clobber (reg:CCFP FPSR_REG))
14672 (clobber (reg:CCFP FLAGS_REG))]
14673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14675 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14676 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14679 (define_insn "*fp_jcc_2_mixed"
14681 (if_then_else (match_operator 0 "comparison_operator"
14682 [(match_operand 1 "register_operand" "f,x")
14683 (match_operand 2 "nonimmediate_operand" "f,xm")])
14685 (label_ref (match_operand 3 "" ""))))
14686 (clobber (reg:CCFP FPSR_REG))
14687 (clobber (reg:CCFP FLAGS_REG))]
14688 "TARGET_MIX_SSE_I387
14689 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14690 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14691 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14694 (define_insn "*fp_jcc_2_sse"
14696 (if_then_else (match_operator 0 "comparison_operator"
14697 [(match_operand 1 "register_operand" "x")
14698 (match_operand 2 "nonimmediate_operand" "xm")])
14700 (label_ref (match_operand 3 "" ""))))
14701 (clobber (reg:CCFP FPSR_REG))
14702 (clobber (reg:CCFP FLAGS_REG))]
14704 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14705 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14706 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14709 (define_insn "*fp_jcc_2_387"
14711 (if_then_else (match_operator 0 "comparison_operator"
14712 [(match_operand 1 "register_operand" "f")
14713 (match_operand 2 "register_operand" "f")])
14715 (label_ref (match_operand 3 "" ""))))
14716 (clobber (reg:CCFP FPSR_REG))
14717 (clobber (reg:CCFP FLAGS_REG))]
14718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14720 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14721 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14724 (define_insn "*fp_jcc_3_387"
14726 (if_then_else (match_operator 0 "comparison_operator"
14727 [(match_operand 1 "register_operand" "f")
14728 (match_operand 2 "nonimmediate_operand" "fm")])
14729 (label_ref (match_operand 3 "" ""))
14731 (clobber (reg:CCFP FPSR_REG))
14732 (clobber (reg:CCFP FLAGS_REG))
14733 (clobber (match_scratch:HI 4 "=a"))]
14735 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14736 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14737 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14738 && SELECT_CC_MODE (GET_CODE (operands[0]),
14739 operands[1], operands[2]) == CCFPmode
14740 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14743 (define_insn "*fp_jcc_4_387"
14745 (if_then_else (match_operator 0 "comparison_operator"
14746 [(match_operand 1 "register_operand" "f")
14747 (match_operand 2 "nonimmediate_operand" "fm")])
14749 (label_ref (match_operand 3 "" ""))))
14750 (clobber (reg:CCFP FPSR_REG))
14751 (clobber (reg:CCFP FLAGS_REG))
14752 (clobber (match_scratch:HI 4 "=a"))]
14754 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14756 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14757 && SELECT_CC_MODE (GET_CODE (operands[0]),
14758 operands[1], operands[2]) == CCFPmode
14759 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14762 (define_insn "*fp_jcc_5_387"
14764 (if_then_else (match_operator 0 "comparison_operator"
14765 [(match_operand 1 "register_operand" "f")
14766 (match_operand 2 "register_operand" "f")])
14767 (label_ref (match_operand 3 "" ""))
14769 (clobber (reg:CCFP FPSR_REG))
14770 (clobber (reg:CCFP FLAGS_REG))
14771 (clobber (match_scratch:HI 4 "=a"))]
14772 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14773 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14777 (define_insn "*fp_jcc_6_387"
14779 (if_then_else (match_operator 0 "comparison_operator"
14780 [(match_operand 1 "register_operand" "f")
14781 (match_operand 2 "register_operand" "f")])
14783 (label_ref (match_operand 3 "" ""))))
14784 (clobber (reg:CCFP FPSR_REG))
14785 (clobber (reg:CCFP FLAGS_REG))
14786 (clobber (match_scratch:HI 4 "=a"))]
14787 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14789 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14792 (define_insn "*fp_jcc_7_387"
14794 (if_then_else (match_operator 0 "comparison_operator"
14795 [(match_operand 1 "register_operand" "f")
14796 (match_operand 2 "const0_operand" "")])
14797 (label_ref (match_operand 3 "" ""))
14799 (clobber (reg:CCFP FPSR_REG))
14800 (clobber (reg:CCFP FLAGS_REG))
14801 (clobber (match_scratch:HI 4 "=a"))]
14802 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14803 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14804 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14805 && SELECT_CC_MODE (GET_CODE (operands[0]),
14806 operands[1], operands[2]) == CCFPmode
14807 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14810 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14811 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14812 ;; with a precedence over other operators and is always put in the first
14813 ;; place. Swap condition and operands to match ficom instruction.
14815 (define_insn "*fp_jcc_8<mode>_387"
14817 (if_then_else (match_operator 0 "comparison_operator"
14818 [(match_operator 1 "float_operator"
14819 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14820 (match_operand 3 "register_operand" "f,f")])
14821 (label_ref (match_operand 4 "" ""))
14823 (clobber (reg:CCFP FPSR_REG))
14824 (clobber (reg:CCFP FLAGS_REG))
14825 (clobber (match_scratch:HI 5 "=a,a"))]
14826 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14827 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14828 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14829 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14830 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14831 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14836 (if_then_else (match_operator 0 "comparison_operator"
14837 [(match_operand 1 "register_operand" "")
14838 (match_operand 2 "nonimmediate_operand" "")])
14839 (match_operand 3 "" "")
14840 (match_operand 4 "" "")))
14841 (clobber (reg:CCFP FPSR_REG))
14842 (clobber (reg:CCFP FLAGS_REG))]
14846 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14847 operands[3], operands[4], NULL_RTX, NULL_RTX);
14853 (if_then_else (match_operator 0 "comparison_operator"
14854 [(match_operand 1 "register_operand" "")
14855 (match_operand 2 "general_operand" "")])
14856 (match_operand 3 "" "")
14857 (match_operand 4 "" "")))
14858 (clobber (reg:CCFP FPSR_REG))
14859 (clobber (reg:CCFP FLAGS_REG))
14860 (clobber (match_scratch:HI 5 "=a"))]
14864 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14865 operands[3], operands[4], operands[5], NULL_RTX);
14871 (if_then_else (match_operator 0 "comparison_operator"
14872 [(match_operator 1 "float_operator"
14873 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14874 (match_operand 3 "register_operand" "")])
14875 (match_operand 4 "" "")
14876 (match_operand 5 "" "")))
14877 (clobber (reg:CCFP FPSR_REG))
14878 (clobber (reg:CCFP FLAGS_REG))
14879 (clobber (match_scratch:HI 6 "=a"))]
14883 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14884 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14885 operands[3], operands[7],
14886 operands[4], operands[5], operands[6], NULL_RTX);
14890 ;; %%% Kill this when reload knows how to do it.
14893 (if_then_else (match_operator 0 "comparison_operator"
14894 [(match_operator 1 "float_operator"
14895 [(match_operand:X87MODEI12 2 "register_operand" "")])
14896 (match_operand 3 "register_operand" "")])
14897 (match_operand 4 "" "")
14898 (match_operand 5 "" "")))
14899 (clobber (reg:CCFP FPSR_REG))
14900 (clobber (reg:CCFP FLAGS_REG))
14901 (clobber (match_scratch:HI 6 "=a"))]
14905 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14906 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14907 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14908 operands[3], operands[7],
14909 operands[4], operands[5], operands[6], operands[2]);
14913 ;; Unconditional and other jump instructions
14915 (define_insn "jump"
14917 (label_ref (match_operand 0 "" "")))]
14920 [(set_attr "type" "ibr")
14921 (set (attr "length")
14922 (if_then_else (and (ge (minus (match_dup 0) (pc))
14924 (lt (minus (match_dup 0) (pc))
14928 (set_attr "modrm" "0")])
14930 (define_expand "indirect_jump"
14931 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14935 (define_insn "*indirect_jump"
14936 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14939 [(set_attr "type" "ibr")
14940 (set_attr "length_immediate" "0")])
14942 (define_expand "tablejump"
14943 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14944 (use (label_ref (match_operand 1 "" "")))])]
14947 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14948 relative. Convert the relative address to an absolute address. */
14952 enum rtx_code code;
14954 /* We can't use @GOTOFF for text labels on VxWorks;
14955 see gotoff_operand. */
14956 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14960 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14962 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14966 op1 = pic_offset_table_rtx;
14971 op0 = pic_offset_table_rtx;
14975 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14980 (define_insn "*tablejump_1"
14981 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14982 (use (label_ref (match_operand 1 "" "")))]
14985 [(set_attr "type" "ibr")
14986 (set_attr "length_immediate" "0")])
14988 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14991 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14992 (set (match_operand:QI 1 "register_operand" "")
14993 (match_operator:QI 2 "ix86_comparison_operator"
14994 [(reg FLAGS_REG) (const_int 0)]))
14995 (set (match_operand 3 "q_regs_operand" "")
14996 (zero_extend (match_dup 1)))]
14997 "(peep2_reg_dead_p (3, operands[1])
14998 || operands_match_p (operands[1], operands[3]))
14999 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15000 [(set (match_dup 4) (match_dup 0))
15001 (set (strict_low_part (match_dup 5))
15004 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15005 operands[5] = gen_lowpart (QImode, operands[3]);
15006 ix86_expand_clear (operands[3]);
15009 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15012 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15013 (set (match_operand:QI 1 "register_operand" "")
15014 (match_operator:QI 2 "ix86_comparison_operator"
15015 [(reg FLAGS_REG) (const_int 0)]))
15016 (parallel [(set (match_operand 3 "q_regs_operand" "")
15017 (zero_extend (match_dup 1)))
15018 (clobber (reg:CC FLAGS_REG))])]
15019 "(peep2_reg_dead_p (3, operands[1])
15020 || operands_match_p (operands[1], operands[3]))
15021 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15022 [(set (match_dup 4) (match_dup 0))
15023 (set (strict_low_part (match_dup 5))
15026 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15027 operands[5] = gen_lowpart (QImode, operands[3]);
15028 ix86_expand_clear (operands[3]);
15031 ;; Call instructions.
15033 ;; The predicates normally associated with named expanders are not properly
15034 ;; checked for calls. This is a bug in the generic code, but it isn't that
15035 ;; easy to fix. Ignore it for now and be prepared to fix things up.
15037 ;; Call subroutine returning no value.
15039 (define_expand "call_pop"
15040 [(parallel [(call (match_operand:QI 0 "" "")
15041 (match_operand:SI 1 "" ""))
15042 (set (reg:SI SP_REG)
15043 (plus:SI (reg:SI SP_REG)
15044 (match_operand:SI 3 "" "")))])]
15047 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15051 (define_insn "*call_pop_0"
15052 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15053 (match_operand:SI 1 "" ""))
15054 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15055 (match_operand:SI 2 "immediate_operand" "")))]
15058 if (SIBLING_CALL_P (insn))
15061 return "call\t%P0";
15063 [(set_attr "type" "call")])
15065 (define_insn "*call_pop_1"
15066 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15067 (match_operand:SI 1 "" ""))
15068 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15069 (match_operand:SI 2 "immediate_operand" "i")))]
15072 if (constant_call_address_operand (operands[0], Pmode))
15074 if (SIBLING_CALL_P (insn))
15077 return "call\t%P0";
15079 if (SIBLING_CALL_P (insn))
15082 return "call\t%A0";
15084 [(set_attr "type" "call")])
15086 (define_expand "call"
15087 [(call (match_operand:QI 0 "" "")
15088 (match_operand 1 "" ""))
15089 (use (match_operand 2 "" ""))]
15092 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15096 (define_expand "sibcall"
15097 [(call (match_operand:QI 0 "" "")
15098 (match_operand 1 "" ""))
15099 (use (match_operand 2 "" ""))]
15102 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15106 (define_insn "*call_0"
15107 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15108 (match_operand 1 "" ""))]
15111 if (SIBLING_CALL_P (insn))
15114 return "call\t%P0";
15116 [(set_attr "type" "call")])
15118 (define_insn "*call_1"
15119 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15120 (match_operand 1 "" ""))]
15121 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15123 if (constant_call_address_operand (operands[0], Pmode))
15124 return "call\t%P0";
15125 return "call\t%A0";
15127 [(set_attr "type" "call")])
15129 (define_insn "*sibcall_1"
15130 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15131 (match_operand 1 "" ""))]
15132 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15134 if (constant_call_address_operand (operands[0], Pmode))
15138 [(set_attr "type" "call")])
15140 (define_insn "*call_1_rex64"
15141 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15142 (match_operand 1 "" ""))]
15143 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15144 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15146 if (constant_call_address_operand (operands[0], Pmode))
15147 return "call\t%P0";
15148 return "call\t%A0";
15150 [(set_attr "type" "call")])
15152 (define_insn "*call_1_rex64_ms_sysv"
15153 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15154 (match_operand 1 "" ""))
15155 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15156 (clobber (reg:TI XMM6_REG))
15157 (clobber (reg:TI XMM7_REG))
15158 (clobber (reg:TI XMM8_REG))
15159 (clobber (reg:TI XMM9_REG))
15160 (clobber (reg:TI XMM10_REG))
15161 (clobber (reg:TI XMM11_REG))
15162 (clobber (reg:TI XMM12_REG))
15163 (clobber (reg:TI XMM13_REG))
15164 (clobber (reg:TI XMM14_REG))
15165 (clobber (reg:TI XMM15_REG))
15166 (clobber (reg:DI SI_REG))
15167 (clobber (reg:DI DI_REG))]
15168 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15170 if (constant_call_address_operand (operands[0], Pmode))
15171 return "call\t%P0";
15172 return "call\t%A0";
15174 [(set_attr "type" "call")])
15176 (define_insn "*call_1_rex64_large"
15177 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15178 (match_operand 1 "" ""))]
15179 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15181 [(set_attr "type" "call")])
15183 (define_insn "*sibcall_1_rex64"
15184 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15185 (match_operand 1 "" ""))]
15186 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15188 [(set_attr "type" "call")])
15190 (define_insn "*sibcall_1_rex64_v"
15191 [(call (mem:QI (reg:DI R11_REG))
15192 (match_operand 0 "" ""))]
15193 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15195 [(set_attr "type" "call")])
15198 ;; Call subroutine, returning value in operand 0
15200 (define_expand "call_value_pop"
15201 [(parallel [(set (match_operand 0 "" "")
15202 (call (match_operand:QI 1 "" "")
15203 (match_operand:SI 2 "" "")))
15204 (set (reg:SI SP_REG)
15205 (plus:SI (reg:SI SP_REG)
15206 (match_operand:SI 4 "" "")))])]
15209 ix86_expand_call (operands[0], operands[1], operands[2],
15210 operands[3], operands[4], 0);
15214 (define_expand "call_value"
15215 [(set (match_operand 0 "" "")
15216 (call (match_operand:QI 1 "" "")
15217 (match_operand:SI 2 "" "")))
15218 (use (match_operand:SI 3 "" ""))]
15219 ;; Operand 2 not used on the i386.
15222 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15226 (define_expand "sibcall_value"
15227 [(set (match_operand 0 "" "")
15228 (call (match_operand:QI 1 "" "")
15229 (match_operand:SI 2 "" "")))
15230 (use (match_operand:SI 3 "" ""))]
15231 ;; Operand 2 not used on the i386.
15234 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15238 ;; Call subroutine returning any type.
15240 (define_expand "untyped_call"
15241 [(parallel [(call (match_operand 0 "" "")
15243 (match_operand 1 "" "")
15244 (match_operand 2 "" "")])]
15249 /* In order to give reg-stack an easier job in validating two
15250 coprocessor registers as containing a possible return value,
15251 simply pretend the untyped call returns a complex long double
15254 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15255 and should have the default ABI. */
15257 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15258 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15259 operands[0], const0_rtx,
15260 GEN_INT ((TARGET_64BIT
15261 ? (ix86_abi == SYSV_ABI
15262 ? X86_64_SSE_REGPARM_MAX
15263 : X64_SSE_REGPARM_MAX)
15264 : X86_32_SSE_REGPARM_MAX)
15268 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15270 rtx set = XVECEXP (operands[2], 0, i);
15271 emit_move_insn (SET_DEST (set), SET_SRC (set));
15274 /* The optimizer does not know that the call sets the function value
15275 registers we stored in the result block. We avoid problems by
15276 claiming that all hard registers are used and clobbered at this
15278 emit_insn (gen_blockage ());
15283 ;; Prologue and epilogue instructions
15285 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15286 ;; all of memory. This blocks insns from being moved across this point.
15288 (define_insn "blockage"
15289 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15292 [(set_attr "length" "0")])
15294 ;; Do not schedule instructions accessing memory across this point.
15296 (define_expand "memory_blockage"
15297 [(set (match_dup 0)
15298 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15301 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15302 MEM_VOLATILE_P (operands[0]) = 1;
15305 (define_insn "*memory_blockage"
15306 [(set (match_operand:BLK 0 "" "")
15307 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15310 [(set_attr "length" "0")])
15312 ;; As USE insns aren't meaningful after reload, this is used instead
15313 ;; to prevent deleting instructions setting registers for PIC code
15314 (define_insn "prologue_use"
15315 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15318 [(set_attr "length" "0")])
15320 ;; Insn emitted into the body of a function to return from a function.
15321 ;; This is only done if the function's epilogue is known to be simple.
15322 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15324 (define_expand "return"
15326 "ix86_can_use_return_insn_p ()"
15328 if (crtl->args.pops_args)
15330 rtx popc = GEN_INT (crtl->args.pops_args);
15331 emit_jump_insn (gen_return_pop_internal (popc));
15336 (define_insn "return_internal"
15340 [(set_attr "length" "1")
15341 (set_attr "atom_unit" "jeu")
15342 (set_attr "length_immediate" "0")
15343 (set_attr "modrm" "0")])
15345 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15346 ;; instruction Athlon and K8 have.
15348 (define_insn "return_internal_long"
15350 (unspec [(const_int 0)] UNSPEC_REP)]
15353 [(set_attr "length" "1")
15354 (set_attr "atom_unit" "jeu")
15355 (set_attr "length_immediate" "0")
15356 (set_attr "prefix_rep" "1")
15357 (set_attr "modrm" "0")])
15359 (define_insn "return_pop_internal"
15361 (use (match_operand:SI 0 "const_int_operand" ""))]
15364 [(set_attr "length" "3")
15365 (set_attr "atom_unit" "jeu")
15366 (set_attr "length_immediate" "2")
15367 (set_attr "modrm" "0")])
15369 (define_insn "return_indirect_internal"
15371 (use (match_operand:SI 0 "register_operand" "r"))]
15374 [(set_attr "type" "ibr")
15375 (set_attr "length_immediate" "0")])
15381 [(set_attr "length" "1")
15382 (set_attr "length_immediate" "0")
15383 (set_attr "modrm" "0")])
15385 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15386 ;; branch prediction penalty for the third jump in a 16-byte
15389 (define_insn "align"
15390 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15393 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15394 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15396 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15397 The align insn is used to avoid 3 jump instructions in the row to improve
15398 branch prediction and the benefits hardly outweigh the cost of extra 8
15399 nops on the average inserted by full alignment pseudo operation. */
15403 [(set_attr "length" "16")])
15405 (define_expand "prologue"
15408 "ix86_expand_prologue (); DONE;")
15410 (define_insn "set_got"
15411 [(set (match_operand:SI 0 "register_operand" "=r")
15412 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15413 (clobber (reg:CC FLAGS_REG))]
15415 { return output_set_got (operands[0], NULL_RTX); }
15416 [(set_attr "type" "multi")
15417 (set_attr "length" "12")])
15419 (define_insn "set_got_labelled"
15420 [(set (match_operand:SI 0 "register_operand" "=r")
15421 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15423 (clobber (reg:CC FLAGS_REG))]
15425 { return output_set_got (operands[0], operands[1]); }
15426 [(set_attr "type" "multi")
15427 (set_attr "length" "12")])
15429 (define_insn "set_got_rex64"
15430 [(set (match_operand:DI 0 "register_operand" "=r")
15431 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15433 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15434 [(set_attr "type" "lea")
15435 (set_attr "length" "6")])
15437 (define_insn "set_rip_rex64"
15438 [(set (match_operand:DI 0 "register_operand" "=r")
15439 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15441 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15442 [(set_attr "type" "lea")
15443 (set_attr "length" "6")])
15445 (define_insn "set_got_offset_rex64"
15446 [(set (match_operand:DI 0 "register_operand" "=r")
15448 [(label_ref (match_operand 1 "" ""))]
15449 UNSPEC_SET_GOT_OFFSET))]
15451 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15452 [(set_attr "type" "imov")
15453 (set_attr "length" "11")])
15455 (define_expand "epilogue"
15458 "ix86_expand_epilogue (1); DONE;")
15460 (define_expand "sibcall_epilogue"
15463 "ix86_expand_epilogue (0); DONE;")
15465 (define_expand "eh_return"
15466 [(use (match_operand 0 "register_operand" ""))]
15469 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15471 /* Tricky bit: we write the address of the handler to which we will
15472 be returning into someone else's stack frame, one word below the
15473 stack address we wish to restore. */
15474 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15475 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15476 tmp = gen_rtx_MEM (Pmode, tmp);
15477 emit_move_insn (tmp, ra);
15479 if (Pmode == SImode)
15480 emit_jump_insn (gen_eh_return_si (sa));
15482 emit_jump_insn (gen_eh_return_di (sa));
15487 (define_insn_and_split "eh_return_<mode>"
15489 (unspec [(match_operand:P 0 "register_operand" "c")]
15490 UNSPEC_EH_RETURN))]
15495 "ix86_expand_epilogue (2); DONE;")
15497 (define_insn "leave"
15498 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15499 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15500 (clobber (mem:BLK (scratch)))]
15503 [(set_attr "type" "leave")])
15505 (define_insn "leave_rex64"
15506 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15507 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15508 (clobber (mem:BLK (scratch)))]
15511 [(set_attr "type" "leave")])
15513 (define_expand "ffssi2"
15515 [(set (match_operand:SI 0 "register_operand" "")
15516 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15517 (clobber (match_scratch:SI 2 ""))
15518 (clobber (reg:CC FLAGS_REG))])]
15523 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15528 (define_expand "ffs_cmove"
15529 [(set (match_dup 2) (const_int -1))
15530 (parallel [(set (reg:CCZ FLAGS_REG)
15531 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15533 (set (match_operand:SI 0 "register_operand" "")
15534 (ctz:SI (match_dup 1)))])
15535 (set (match_dup 0) (if_then_else:SI
15536 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15539 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15540 (clobber (reg:CC FLAGS_REG))])]
15542 "operands[2] = gen_reg_rtx (SImode);")
15544 (define_insn_and_split "*ffs_no_cmove"
15545 [(set (match_operand:SI 0 "register_operand" "=r")
15546 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15547 (clobber (match_scratch:SI 2 "=&q"))
15548 (clobber (reg:CC FLAGS_REG))]
15551 "&& reload_completed"
15552 [(parallel [(set (reg:CCZ FLAGS_REG)
15553 (compare:CCZ (match_dup 1) (const_int 0)))
15554 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15555 (set (strict_low_part (match_dup 3))
15556 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15557 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15558 (clobber (reg:CC FLAGS_REG))])
15559 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15560 (clobber (reg:CC FLAGS_REG))])
15561 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15562 (clobber (reg:CC FLAGS_REG))])]
15564 operands[3] = gen_lowpart (QImode, operands[2]);
15565 ix86_expand_clear (operands[2]);
15568 (define_insn "*ffssi_1"
15569 [(set (reg:CCZ FLAGS_REG)
15570 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15572 (set (match_operand:SI 0 "register_operand" "=r")
15573 (ctz:SI (match_dup 1)))]
15575 "bsf{l}\t{%1, %0|%0, %1}"
15576 [(set_attr "prefix_0f" "1")])
15578 (define_expand "ffsdi2"
15579 [(set (match_dup 2) (const_int -1))
15580 (parallel [(set (reg:CCZ FLAGS_REG)
15581 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15583 (set (match_operand:DI 0 "register_operand" "")
15584 (ctz:DI (match_dup 1)))])
15585 (set (match_dup 0) (if_then_else:DI
15586 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15589 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15590 (clobber (reg:CC FLAGS_REG))])]
15592 "operands[2] = gen_reg_rtx (DImode);")
15594 (define_insn "*ffsdi_1"
15595 [(set (reg:CCZ FLAGS_REG)
15596 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15598 (set (match_operand:DI 0 "register_operand" "=r")
15599 (ctz:DI (match_dup 1)))]
15601 "bsf{q}\t{%1, %0|%0, %1}"
15602 [(set_attr "prefix_0f" "1")])
15604 (define_insn "ctzsi2"
15605 [(set (match_operand:SI 0 "register_operand" "=r")
15606 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15607 (clobber (reg:CC FLAGS_REG))]
15609 "bsf{l}\t{%1, %0|%0, %1}"
15610 [(set_attr "prefix_0f" "1")])
15612 (define_insn "ctzdi2"
15613 [(set (match_operand:DI 0 "register_operand" "=r")
15614 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15615 (clobber (reg:CC FLAGS_REG))]
15617 "bsf{q}\t{%1, %0|%0, %1}"
15618 [(set_attr "prefix_0f" "1")])
15620 (define_expand "clzsi2"
15622 [(set (match_operand:SI 0 "register_operand" "")
15623 (minus:SI (const_int 31)
15624 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15625 (clobber (reg:CC FLAGS_REG))])
15627 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15628 (clobber (reg:CC FLAGS_REG))])]
15633 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15638 (define_insn "clzsi2_abm"
15639 [(set (match_operand:SI 0 "register_operand" "=r")
15640 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15641 (clobber (reg:CC FLAGS_REG))]
15643 "lzcnt{l}\t{%1, %0|%0, %1}"
15644 [(set_attr "prefix_rep" "1")
15645 (set_attr "type" "bitmanip")
15646 (set_attr "mode" "SI")])
15648 (define_insn "*bsr"
15649 [(set (match_operand:SI 0 "register_operand" "=r")
15650 (minus:SI (const_int 31)
15651 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15652 (clobber (reg:CC FLAGS_REG))]
15654 "bsr{l}\t{%1, %0|%0, %1}"
15655 [(set_attr "prefix_0f" "1")
15656 (set_attr "mode" "SI")])
15658 (define_insn "popcount<mode>2"
15659 [(set (match_operand:SWI248 0 "register_operand" "=r")
15661 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15662 (clobber (reg:CC FLAGS_REG))]
15666 return "popcnt\t{%1, %0|%0, %1}";
15668 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15671 [(set_attr "prefix_rep" "1")
15672 (set_attr "type" "bitmanip")
15673 (set_attr "mode" "<MODE>")])
15675 (define_insn "*popcount<mode>2_cmp"
15676 [(set (reg FLAGS_REG)
15679 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15681 (set (match_operand:SWI248 0 "register_operand" "=r")
15682 (popcount:SWI248 (match_dup 1)))]
15683 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15686 return "popcnt\t{%1, %0|%0, %1}";
15688 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15691 [(set_attr "prefix_rep" "1")
15692 (set_attr "type" "bitmanip")
15693 (set_attr "mode" "<MODE>")])
15695 (define_insn "*popcountsi2_cmp_zext"
15696 [(set (reg FLAGS_REG)
15698 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15700 (set (match_operand:DI 0 "register_operand" "=r")
15701 (zero_extend:DI(popcount:SI (match_dup 1))))]
15702 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15705 return "popcnt\t{%1, %0|%0, %1}";
15707 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15710 [(set_attr "prefix_rep" "1")
15711 (set_attr "type" "bitmanip")
15712 (set_attr "mode" "SI")])
15714 (define_expand "bswapsi2"
15715 [(set (match_operand:SI 0 "register_operand" "")
15716 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15721 rtx x = operands[0];
15723 emit_move_insn (x, operands[1]);
15724 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15725 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15726 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15731 (define_insn "*bswapsi_1"
15732 [(set (match_operand:SI 0 "register_operand" "=r")
15733 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15736 [(set_attr "prefix_0f" "1")
15737 (set_attr "length" "2")])
15739 (define_insn "*bswaphi_lowpart_1"
15740 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15741 (bswap:HI (match_dup 0)))
15742 (clobber (reg:CC FLAGS_REG))]
15743 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15745 xchg{b}\t{%h0, %b0|%b0, %h0}
15746 rol{w}\t{$8, %0|%0, 8}"
15747 [(set_attr "length" "2,4")
15748 (set_attr "mode" "QI,HI")])
15750 (define_insn "bswaphi_lowpart"
15751 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15752 (bswap:HI (match_dup 0)))
15753 (clobber (reg:CC FLAGS_REG))]
15755 "rol{w}\t{$8, %0|%0, 8}"
15756 [(set_attr "length" "4")
15757 (set_attr "mode" "HI")])
15759 (define_insn "bswapdi2"
15760 [(set (match_operand:DI 0 "register_operand" "=r")
15761 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15764 [(set_attr "prefix_0f" "1")
15765 (set_attr "length" "3")])
15767 (define_expand "clzdi2"
15769 [(set (match_operand:DI 0 "register_operand" "")
15770 (minus:DI (const_int 63)
15771 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15772 (clobber (reg:CC FLAGS_REG))])
15774 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15775 (clobber (reg:CC FLAGS_REG))])]
15780 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15785 (define_insn "clzdi2_abm"
15786 [(set (match_operand:DI 0 "register_operand" "=r")
15787 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15788 (clobber (reg:CC FLAGS_REG))]
15789 "TARGET_64BIT && TARGET_ABM"
15790 "lzcnt{q}\t{%1, %0|%0, %1}"
15791 [(set_attr "prefix_rep" "1")
15792 (set_attr "type" "bitmanip")
15793 (set_attr "mode" "DI")])
15795 (define_insn "*bsr_rex64"
15796 [(set (match_operand:DI 0 "register_operand" "=r")
15797 (minus:DI (const_int 63)
15798 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15799 (clobber (reg:CC FLAGS_REG))]
15801 "bsr{q}\t{%1, %0|%0, %1}"
15802 [(set_attr "prefix_0f" "1")
15803 (set_attr "mode" "DI")])
15805 (define_expand "clzhi2"
15807 [(set (match_operand:HI 0 "register_operand" "")
15808 (minus:HI (const_int 15)
15809 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15810 (clobber (reg:CC FLAGS_REG))])
15812 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15813 (clobber (reg:CC FLAGS_REG))])]
15818 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15823 (define_insn "clzhi2_abm"
15824 [(set (match_operand:HI 0 "register_operand" "=r")
15825 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15826 (clobber (reg:CC FLAGS_REG))]
15828 "lzcnt{w}\t{%1, %0|%0, %1}"
15829 [(set_attr "prefix_rep" "1")
15830 (set_attr "type" "bitmanip")
15831 (set_attr "mode" "HI")])
15833 (define_insn "*bsrhi"
15834 [(set (match_operand:HI 0 "register_operand" "=r")
15835 (minus:HI (const_int 15)
15836 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15837 (clobber (reg:CC FLAGS_REG))]
15839 "bsr{w}\t{%1, %0|%0, %1}"
15840 [(set_attr "prefix_0f" "1")
15841 (set_attr "mode" "HI")])
15843 (define_expand "paritydi2"
15844 [(set (match_operand:DI 0 "register_operand" "")
15845 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15848 rtx scratch = gen_reg_rtx (QImode);
15851 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15852 NULL_RTX, operands[1]));
15854 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15855 gen_rtx_REG (CCmode, FLAGS_REG),
15857 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15860 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15863 rtx tmp = gen_reg_rtx (SImode);
15865 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15866 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15871 (define_insn_and_split "paritydi2_cmp"
15872 [(set (reg:CC FLAGS_REG)
15873 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15874 (clobber (match_scratch:DI 0 "=r"))
15875 (clobber (match_scratch:SI 1 "=&r"))
15876 (clobber (match_scratch:HI 2 "=Q"))]
15879 "&& reload_completed"
15881 [(set (match_dup 1)
15882 (xor:SI (match_dup 1) (match_dup 4)))
15883 (clobber (reg:CC FLAGS_REG))])
15885 [(set (reg:CC FLAGS_REG)
15886 (parity:CC (match_dup 1)))
15887 (clobber (match_dup 1))
15888 (clobber (match_dup 2))])]
15890 operands[4] = gen_lowpart (SImode, operands[3]);
15894 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15895 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15898 operands[1] = gen_highpart (SImode, operands[3]);
15901 (define_expand "paritysi2"
15902 [(set (match_operand:SI 0 "register_operand" "")
15903 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15906 rtx scratch = gen_reg_rtx (QImode);
15909 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15911 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15912 gen_rtx_REG (CCmode, FLAGS_REG),
15914 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15916 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15920 (define_insn_and_split "paritysi2_cmp"
15921 [(set (reg:CC FLAGS_REG)
15922 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15923 (clobber (match_scratch:SI 0 "=r"))
15924 (clobber (match_scratch:HI 1 "=&Q"))]
15927 "&& reload_completed"
15929 [(set (match_dup 1)
15930 (xor:HI (match_dup 1) (match_dup 3)))
15931 (clobber (reg:CC FLAGS_REG))])
15933 [(set (reg:CC FLAGS_REG)
15934 (parity:CC (match_dup 1)))
15935 (clobber (match_dup 1))])]
15937 operands[3] = gen_lowpart (HImode, operands[2]);
15939 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15940 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15943 (define_insn "*parityhi2_cmp"
15944 [(set (reg:CC FLAGS_REG)
15945 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15946 (clobber (match_scratch:HI 0 "=Q"))]
15948 "xor{b}\t{%h0, %b0|%b0, %h0}"
15949 [(set_attr "length" "2")
15950 (set_attr "mode" "HI")])
15952 (define_insn "*parityqi2_cmp"
15953 [(set (reg:CC FLAGS_REG)
15954 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15957 [(set_attr "length" "2")
15958 (set_attr "mode" "QI")])
15960 ;; Thread-local storage patterns for ELF.
15962 ;; Note that these code sequences must appear exactly as shown
15963 ;; in order to allow linker relaxation.
15965 (define_insn "*tls_global_dynamic_32_gnu"
15966 [(set (match_operand:SI 0 "register_operand" "=a")
15967 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15968 (match_operand:SI 2 "tls_symbolic_operand" "")
15969 (match_operand:SI 3 "call_insn_operand" "")]
15971 (clobber (match_scratch:SI 4 "=d"))
15972 (clobber (match_scratch:SI 5 "=c"))
15973 (clobber (reg:CC FLAGS_REG))]
15974 "!TARGET_64BIT && TARGET_GNU_TLS"
15975 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15976 [(set_attr "type" "multi")
15977 (set_attr "length" "12")])
15979 (define_insn "*tls_global_dynamic_32_sun"
15980 [(set (match_operand:SI 0 "register_operand" "=a")
15981 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15982 (match_operand:SI 2 "tls_symbolic_operand" "")
15983 (match_operand:SI 3 "call_insn_operand" "")]
15985 (clobber (match_scratch:SI 4 "=d"))
15986 (clobber (match_scratch:SI 5 "=c"))
15987 (clobber (reg:CC FLAGS_REG))]
15988 "!TARGET_64BIT && TARGET_SUN_TLS"
15989 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15990 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15991 [(set_attr "type" "multi")
15992 (set_attr "length" "14")])
15994 (define_expand "tls_global_dynamic_32"
15995 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15998 (match_operand:SI 1 "tls_symbolic_operand" "")
16001 (clobber (match_scratch:SI 4 ""))
16002 (clobber (match_scratch:SI 5 ""))
16003 (clobber (reg:CC FLAGS_REG))])]
16007 operands[2] = pic_offset_table_rtx;
16010 operands[2] = gen_reg_rtx (Pmode);
16011 emit_insn (gen_set_got (operands[2]));
16013 if (TARGET_GNU2_TLS)
16015 emit_insn (gen_tls_dynamic_gnu2_32
16016 (operands[0], operands[1], operands[2]));
16019 operands[3] = ix86_tls_get_addr ();
16022 (define_insn "*tls_global_dynamic_64"
16023 [(set (match_operand:DI 0 "register_operand" "=a")
16024 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16025 (match_operand:DI 3 "" "")))
16026 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16029 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16030 [(set_attr "type" "multi")
16031 (set_attr "length" "16")])
16033 (define_expand "tls_global_dynamic_64"
16034 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16035 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16036 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16040 if (TARGET_GNU2_TLS)
16042 emit_insn (gen_tls_dynamic_gnu2_64
16043 (operands[0], operands[1]));
16046 operands[2] = ix86_tls_get_addr ();
16049 (define_insn "*tls_local_dynamic_base_32_gnu"
16050 [(set (match_operand:SI 0 "register_operand" "=a")
16051 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16052 (match_operand:SI 2 "call_insn_operand" "")]
16053 UNSPEC_TLS_LD_BASE))
16054 (clobber (match_scratch:SI 3 "=d"))
16055 (clobber (match_scratch:SI 4 "=c"))
16056 (clobber (reg:CC FLAGS_REG))]
16057 "!TARGET_64BIT && TARGET_GNU_TLS"
16058 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16059 [(set_attr "type" "multi")
16060 (set_attr "length" "11")])
16062 (define_insn "*tls_local_dynamic_base_32_sun"
16063 [(set (match_operand:SI 0 "register_operand" "=a")
16064 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16065 (match_operand:SI 2 "call_insn_operand" "")]
16066 UNSPEC_TLS_LD_BASE))
16067 (clobber (match_scratch:SI 3 "=d"))
16068 (clobber (match_scratch:SI 4 "=c"))
16069 (clobber (reg:CC FLAGS_REG))]
16070 "!TARGET_64BIT && TARGET_SUN_TLS"
16071 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16072 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16073 [(set_attr "type" "multi")
16074 (set_attr "length" "13")])
16076 (define_expand "tls_local_dynamic_base_32"
16077 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16078 (unspec:SI [(match_dup 1) (match_dup 2)]
16079 UNSPEC_TLS_LD_BASE))
16080 (clobber (match_scratch:SI 3 ""))
16081 (clobber (match_scratch:SI 4 ""))
16082 (clobber (reg:CC FLAGS_REG))])]
16086 operands[1] = pic_offset_table_rtx;
16089 operands[1] = gen_reg_rtx (Pmode);
16090 emit_insn (gen_set_got (operands[1]));
16092 if (TARGET_GNU2_TLS)
16094 emit_insn (gen_tls_dynamic_gnu2_32
16095 (operands[0], ix86_tls_module_base (), operands[1]));
16098 operands[2] = ix86_tls_get_addr ();
16101 (define_insn "*tls_local_dynamic_base_64"
16102 [(set (match_operand:DI 0 "register_operand" "=a")
16103 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16104 (match_operand:DI 2 "" "")))
16105 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16107 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16108 [(set_attr "type" "multi")
16109 (set_attr "length" "12")])
16111 (define_expand "tls_local_dynamic_base_64"
16112 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16113 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16114 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16117 if (TARGET_GNU2_TLS)
16119 emit_insn (gen_tls_dynamic_gnu2_64
16120 (operands[0], ix86_tls_module_base ()));
16123 operands[1] = ix86_tls_get_addr ();
16126 ;; Local dynamic of a single variable is a lose. Show combine how
16127 ;; to convert that back to global dynamic.
16129 (define_insn_and_split "*tls_local_dynamic_32_once"
16130 [(set (match_operand:SI 0 "register_operand" "=a")
16131 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16132 (match_operand:SI 2 "call_insn_operand" "")]
16133 UNSPEC_TLS_LD_BASE)
16134 (const:SI (unspec:SI
16135 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16137 (clobber (match_scratch:SI 4 "=d"))
16138 (clobber (match_scratch:SI 5 "=c"))
16139 (clobber (reg:CC FLAGS_REG))]
16143 [(parallel [(set (match_dup 0)
16144 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16146 (clobber (match_dup 4))
16147 (clobber (match_dup 5))
16148 (clobber (reg:CC FLAGS_REG))])]
16151 ;; Load and add the thread base pointer from %gs:0.
16153 (define_insn "*load_tp_si"
16154 [(set (match_operand:SI 0 "register_operand" "=r")
16155 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16157 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16158 [(set_attr "type" "imov")
16159 (set_attr "modrm" "0")
16160 (set_attr "length" "7")
16161 (set_attr "memory" "load")
16162 (set_attr "imm_disp" "false")])
16164 (define_insn "*add_tp_si"
16165 [(set (match_operand:SI 0 "register_operand" "=r")
16166 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16167 (match_operand:SI 1 "register_operand" "0")))
16168 (clobber (reg:CC FLAGS_REG))]
16170 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16171 [(set_attr "type" "alu")
16172 (set_attr "modrm" "0")
16173 (set_attr "length" "7")
16174 (set_attr "memory" "load")
16175 (set_attr "imm_disp" "false")])
16177 (define_insn "*load_tp_di"
16178 [(set (match_operand:DI 0 "register_operand" "=r")
16179 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16181 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16182 [(set_attr "type" "imov")
16183 (set_attr "modrm" "0")
16184 (set_attr "length" "7")
16185 (set_attr "memory" "load")
16186 (set_attr "imm_disp" "false")])
16188 (define_insn "*add_tp_di"
16189 [(set (match_operand:DI 0 "register_operand" "=r")
16190 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16191 (match_operand:DI 1 "register_operand" "0")))
16192 (clobber (reg:CC FLAGS_REG))]
16194 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16195 [(set_attr "type" "alu")
16196 (set_attr "modrm" "0")
16197 (set_attr "length" "7")
16198 (set_attr "memory" "load")
16199 (set_attr "imm_disp" "false")])
16201 ;; GNU2 TLS patterns can be split.
16203 (define_expand "tls_dynamic_gnu2_32"
16204 [(set (match_dup 3)
16205 (plus:SI (match_operand:SI 2 "register_operand" "")
16207 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16210 [(set (match_operand:SI 0 "register_operand" "")
16211 (unspec:SI [(match_dup 1) (match_dup 3)
16212 (match_dup 2) (reg:SI SP_REG)]
16214 (clobber (reg:CC FLAGS_REG))])]
16215 "!TARGET_64BIT && TARGET_GNU2_TLS"
16217 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16218 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16221 (define_insn "*tls_dynamic_lea_32"
16222 [(set (match_operand:SI 0 "register_operand" "=r")
16223 (plus:SI (match_operand:SI 1 "register_operand" "b")
16225 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16226 UNSPEC_TLSDESC))))]
16227 "!TARGET_64BIT && TARGET_GNU2_TLS"
16228 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16229 [(set_attr "type" "lea")
16230 (set_attr "mode" "SI")
16231 (set_attr "length" "6")
16232 (set_attr "length_address" "4")])
16234 (define_insn "*tls_dynamic_call_32"
16235 [(set (match_operand:SI 0 "register_operand" "=a")
16236 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16237 (match_operand:SI 2 "register_operand" "0")
16238 ;; we have to make sure %ebx still points to the GOT
16239 (match_operand:SI 3 "register_operand" "b")
16242 (clobber (reg:CC FLAGS_REG))]
16243 "!TARGET_64BIT && TARGET_GNU2_TLS"
16244 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16245 [(set_attr "type" "call")
16246 (set_attr "length" "2")
16247 (set_attr "length_address" "0")])
16249 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16250 [(set (match_operand:SI 0 "register_operand" "=&a")
16252 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16253 (match_operand:SI 4 "" "")
16254 (match_operand:SI 2 "register_operand" "b")
16257 (const:SI (unspec:SI
16258 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16260 (clobber (reg:CC FLAGS_REG))]
16261 "!TARGET_64BIT && TARGET_GNU2_TLS"
16264 [(set (match_dup 0) (match_dup 5))]
16266 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16267 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16270 (define_expand "tls_dynamic_gnu2_64"
16271 [(set (match_dup 2)
16272 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16275 [(set (match_operand:DI 0 "register_operand" "")
16276 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16278 (clobber (reg:CC FLAGS_REG))])]
16279 "TARGET_64BIT && TARGET_GNU2_TLS"
16281 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16282 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16285 (define_insn "*tls_dynamic_lea_64"
16286 [(set (match_operand:DI 0 "register_operand" "=r")
16287 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16289 "TARGET_64BIT && TARGET_GNU2_TLS"
16290 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16291 [(set_attr "type" "lea")
16292 (set_attr "mode" "DI")
16293 (set_attr "length" "7")
16294 (set_attr "length_address" "4")])
16296 (define_insn "*tls_dynamic_call_64"
16297 [(set (match_operand:DI 0 "register_operand" "=a")
16298 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16299 (match_operand:DI 2 "register_operand" "0")
16302 (clobber (reg:CC FLAGS_REG))]
16303 "TARGET_64BIT && TARGET_GNU2_TLS"
16304 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16305 [(set_attr "type" "call")
16306 (set_attr "length" "2")
16307 (set_attr "length_address" "0")])
16309 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16310 [(set (match_operand:DI 0 "register_operand" "=&a")
16312 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16313 (match_operand:DI 3 "" "")
16316 (const:DI (unspec:DI
16317 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16319 (clobber (reg:CC FLAGS_REG))]
16320 "TARGET_64BIT && TARGET_GNU2_TLS"
16323 [(set (match_dup 0) (match_dup 4))]
16325 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16326 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16331 ;; These patterns match the binary 387 instructions for addM3, subM3,
16332 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16333 ;; SFmode. The first is the normal insn, the second the same insn but
16334 ;; with one operand a conversion, and the third the same insn but with
16335 ;; the other operand a conversion. The conversion may be SFmode or
16336 ;; SImode if the target mode DFmode, but only SImode if the target mode
16339 ;; Gcc is slightly more smart about handling normal two address instructions
16340 ;; so use special patterns for add and mull.
16342 (define_insn "*fop_<mode>_comm_mixed_avx"
16343 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16344 (match_operator:MODEF 3 "binary_fp_operator"
16345 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16346 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16347 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16348 && COMMUTATIVE_ARITH_P (operands[3])
16349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16350 "* return output_387_binary_op (insn, operands);"
16351 [(set (attr "type")
16352 (if_then_else (eq_attr "alternative" "1")
16353 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16354 (const_string "ssemul")
16355 (const_string "sseadd"))
16356 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16357 (const_string "fmul")
16358 (const_string "fop"))))
16359 (set_attr "prefix" "orig,maybe_vex")
16360 (set_attr "mode" "<MODE>")])
16362 (define_insn "*fop_<mode>_comm_mixed"
16363 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16364 (match_operator:MODEF 3 "binary_fp_operator"
16365 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16366 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16367 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16368 && COMMUTATIVE_ARITH_P (operands[3])
16369 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16370 "* return output_387_binary_op (insn, operands);"
16371 [(set (attr "type")
16372 (if_then_else (eq_attr "alternative" "1")
16373 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16374 (const_string "ssemul")
16375 (const_string "sseadd"))
16376 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16377 (const_string "fmul")
16378 (const_string "fop"))))
16379 (set_attr "mode" "<MODE>")])
16381 (define_insn "*fop_<mode>_comm_avx"
16382 [(set (match_operand:MODEF 0 "register_operand" "=x")
16383 (match_operator:MODEF 3 "binary_fp_operator"
16384 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16385 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16386 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16387 && COMMUTATIVE_ARITH_P (operands[3])
16388 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16389 "* return output_387_binary_op (insn, operands);"
16390 [(set (attr "type")
16391 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16392 (const_string "ssemul")
16393 (const_string "sseadd")))
16394 (set_attr "prefix" "vex")
16395 (set_attr "mode" "<MODE>")])
16397 (define_insn "*fop_<mode>_comm_sse"
16398 [(set (match_operand:MODEF 0 "register_operand" "=x")
16399 (match_operator:MODEF 3 "binary_fp_operator"
16400 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16401 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16402 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16403 && COMMUTATIVE_ARITH_P (operands[3])
16404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16405 "* return output_387_binary_op (insn, operands);"
16406 [(set (attr "type")
16407 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16408 (const_string "ssemul")
16409 (const_string "sseadd")))
16410 (set_attr "mode" "<MODE>")])
16412 (define_insn "*fop_<mode>_comm_i387"
16413 [(set (match_operand:MODEF 0 "register_operand" "=f")
16414 (match_operator:MODEF 3 "binary_fp_operator"
16415 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16416 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16417 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16418 && COMMUTATIVE_ARITH_P (operands[3])
16419 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16420 "* return output_387_binary_op (insn, operands);"
16421 [(set (attr "type")
16422 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16423 (const_string "fmul")
16424 (const_string "fop")))
16425 (set_attr "mode" "<MODE>")])
16427 (define_insn "*fop_<mode>_1_mixed_avx"
16428 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16429 (match_operator:MODEF 3 "binary_fp_operator"
16430 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16431 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16432 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16433 && !COMMUTATIVE_ARITH_P (operands[3])
16434 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16435 "* return output_387_binary_op (insn, operands);"
16436 [(set (attr "type")
16437 (cond [(and (eq_attr "alternative" "2")
16438 (match_operand:MODEF 3 "mult_operator" ""))
16439 (const_string "ssemul")
16440 (and (eq_attr "alternative" "2")
16441 (match_operand:MODEF 3 "div_operator" ""))
16442 (const_string "ssediv")
16443 (eq_attr "alternative" "2")
16444 (const_string "sseadd")
16445 (match_operand:MODEF 3 "mult_operator" "")
16446 (const_string "fmul")
16447 (match_operand:MODEF 3 "div_operator" "")
16448 (const_string "fdiv")
16450 (const_string "fop")))
16451 (set_attr "prefix" "orig,orig,maybe_vex")
16452 (set_attr "mode" "<MODE>")])
16454 (define_insn "*fop_<mode>_1_mixed"
16455 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16456 (match_operator:MODEF 3 "binary_fp_operator"
16457 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16458 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16459 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16460 && !COMMUTATIVE_ARITH_P (operands[3])
16461 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16462 "* return output_387_binary_op (insn, operands);"
16463 [(set (attr "type")
16464 (cond [(and (eq_attr "alternative" "2")
16465 (match_operand:MODEF 3 "mult_operator" ""))
16466 (const_string "ssemul")
16467 (and (eq_attr "alternative" "2")
16468 (match_operand:MODEF 3 "div_operator" ""))
16469 (const_string "ssediv")
16470 (eq_attr "alternative" "2")
16471 (const_string "sseadd")
16472 (match_operand:MODEF 3 "mult_operator" "")
16473 (const_string "fmul")
16474 (match_operand:MODEF 3 "div_operator" "")
16475 (const_string "fdiv")
16477 (const_string "fop")))
16478 (set_attr "mode" "<MODE>")])
16480 (define_insn "*rcpsf2_sse"
16481 [(set (match_operand:SF 0 "register_operand" "=x")
16482 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16485 "%vrcpss\t{%1, %d0|%d0, %1}"
16486 [(set_attr "type" "sse")
16487 (set_attr "atom_sse_attr" "rcp")
16488 (set_attr "prefix" "maybe_vex")
16489 (set_attr "mode" "SF")])
16491 (define_insn "*fop_<mode>_1_avx"
16492 [(set (match_operand:MODEF 0 "register_operand" "=x")
16493 (match_operator:MODEF 3 "binary_fp_operator"
16494 [(match_operand:MODEF 1 "register_operand" "x")
16495 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16496 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16497 && !COMMUTATIVE_ARITH_P (operands[3])"
16498 "* return output_387_binary_op (insn, operands);"
16499 [(set (attr "type")
16500 (cond [(match_operand:MODEF 3 "mult_operator" "")
16501 (const_string "ssemul")
16502 (match_operand:MODEF 3 "div_operator" "")
16503 (const_string "ssediv")
16505 (const_string "sseadd")))
16506 (set_attr "prefix" "vex")
16507 (set_attr "mode" "<MODE>")])
16509 (define_insn "*fop_<mode>_1_sse"
16510 [(set (match_operand:MODEF 0 "register_operand" "=x")
16511 (match_operator:MODEF 3 "binary_fp_operator"
16512 [(match_operand:MODEF 1 "register_operand" "0")
16513 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16514 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16515 && !COMMUTATIVE_ARITH_P (operands[3])"
16516 "* return output_387_binary_op (insn, operands);"
16517 [(set (attr "type")
16518 (cond [(match_operand:MODEF 3 "mult_operator" "")
16519 (const_string "ssemul")
16520 (match_operand:MODEF 3 "div_operator" "")
16521 (const_string "ssediv")
16523 (const_string "sseadd")))
16524 (set_attr "mode" "<MODE>")])
16526 ;; This pattern is not fully shadowed by the pattern above.
16527 (define_insn "*fop_<mode>_1_i387"
16528 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16529 (match_operator:MODEF 3 "binary_fp_operator"
16530 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16531 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16532 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16533 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16534 && !COMMUTATIVE_ARITH_P (operands[3])
16535 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16536 "* return output_387_binary_op (insn, operands);"
16537 [(set (attr "type")
16538 (cond [(match_operand:MODEF 3 "mult_operator" "")
16539 (const_string "fmul")
16540 (match_operand:MODEF 3 "div_operator" "")
16541 (const_string "fdiv")
16543 (const_string "fop")))
16544 (set_attr "mode" "<MODE>")])
16546 ;; ??? Add SSE splitters for these!
16547 (define_insn "*fop_<MODEF:mode>_2_i387"
16548 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16549 (match_operator:MODEF 3 "binary_fp_operator"
16551 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16552 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16553 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16554 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16555 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557 [(set (attr "type")
16558 (cond [(match_operand:MODEF 3 "mult_operator" "")
16559 (const_string "fmul")
16560 (match_operand:MODEF 3 "div_operator" "")
16561 (const_string "fdiv")
16563 (const_string "fop")))
16564 (set_attr "fp_int_src" "true")
16565 (set_attr "mode" "<X87MODEI12:MODE>")])
16567 (define_insn "*fop_<MODEF:mode>_3_i387"
16568 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16569 (match_operator:MODEF 3 "binary_fp_operator"
16570 [(match_operand:MODEF 1 "register_operand" "0,0")
16572 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16573 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16574 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16575 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16576 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16577 [(set (attr "type")
16578 (cond [(match_operand:MODEF 3 "mult_operator" "")
16579 (const_string "fmul")
16580 (match_operand:MODEF 3 "div_operator" "")
16581 (const_string "fdiv")
16583 (const_string "fop")))
16584 (set_attr "fp_int_src" "true")
16585 (set_attr "mode" "<MODE>")])
16587 (define_insn "*fop_df_4_i387"
16588 [(set (match_operand:DF 0 "register_operand" "=f,f")
16589 (match_operator:DF 3 "binary_fp_operator"
16591 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16592 (match_operand:DF 2 "register_operand" "0,f")]))]
16593 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16594 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16595 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16596 "* return output_387_binary_op (insn, operands);"
16597 [(set (attr "type")
16598 (cond [(match_operand:DF 3 "mult_operator" "")
16599 (const_string "fmul")
16600 (match_operand:DF 3 "div_operator" "")
16601 (const_string "fdiv")
16603 (const_string "fop")))
16604 (set_attr "mode" "SF")])
16606 (define_insn "*fop_df_5_i387"
16607 [(set (match_operand:DF 0 "register_operand" "=f,f")
16608 (match_operator:DF 3 "binary_fp_operator"
16609 [(match_operand:DF 1 "register_operand" "0,f")
16611 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16612 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16613 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16614 "* return output_387_binary_op (insn, operands);"
16615 [(set (attr "type")
16616 (cond [(match_operand:DF 3 "mult_operator" "")
16617 (const_string "fmul")
16618 (match_operand:DF 3 "div_operator" "")
16619 (const_string "fdiv")
16621 (const_string "fop")))
16622 (set_attr "mode" "SF")])
16624 (define_insn "*fop_df_6_i387"
16625 [(set (match_operand:DF 0 "register_operand" "=f,f")
16626 (match_operator:DF 3 "binary_fp_operator"
16628 (match_operand:SF 1 "register_operand" "0,f"))
16630 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16631 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16632 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16633 "* return output_387_binary_op (insn, operands);"
16634 [(set (attr "type")
16635 (cond [(match_operand:DF 3 "mult_operator" "")
16636 (const_string "fmul")
16637 (match_operand:DF 3 "div_operator" "")
16638 (const_string "fdiv")
16640 (const_string "fop")))
16641 (set_attr "mode" "SF")])
16643 (define_insn "*fop_xf_comm_i387"
16644 [(set (match_operand:XF 0 "register_operand" "=f")
16645 (match_operator:XF 3 "binary_fp_operator"
16646 [(match_operand:XF 1 "register_operand" "%0")
16647 (match_operand:XF 2 "register_operand" "f")]))]
16649 && COMMUTATIVE_ARITH_P (operands[3])"
16650 "* return output_387_binary_op (insn, operands);"
16651 [(set (attr "type")
16652 (if_then_else (match_operand:XF 3 "mult_operator" "")
16653 (const_string "fmul")
16654 (const_string "fop")))
16655 (set_attr "mode" "XF")])
16657 (define_insn "*fop_xf_1_i387"
16658 [(set (match_operand:XF 0 "register_operand" "=f,f")
16659 (match_operator:XF 3 "binary_fp_operator"
16660 [(match_operand:XF 1 "register_operand" "0,f")
16661 (match_operand:XF 2 "register_operand" "f,0")]))]
16663 && !COMMUTATIVE_ARITH_P (operands[3])"
16664 "* return output_387_binary_op (insn, operands);"
16665 [(set (attr "type")
16666 (cond [(match_operand:XF 3 "mult_operator" "")
16667 (const_string "fmul")
16668 (match_operand:XF 3 "div_operator" "")
16669 (const_string "fdiv")
16671 (const_string "fop")))
16672 (set_attr "mode" "XF")])
16674 (define_insn "*fop_xf_2_i387"
16675 [(set (match_operand:XF 0 "register_operand" "=f,f")
16676 (match_operator:XF 3 "binary_fp_operator"
16678 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16679 (match_operand:XF 2 "register_operand" "0,0")]))]
16680 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16681 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16682 [(set (attr "type")
16683 (cond [(match_operand:XF 3 "mult_operator" "")
16684 (const_string "fmul")
16685 (match_operand:XF 3 "div_operator" "")
16686 (const_string "fdiv")
16688 (const_string "fop")))
16689 (set_attr "fp_int_src" "true")
16690 (set_attr "mode" "<MODE>")])
16692 (define_insn "*fop_xf_3_i387"
16693 [(set (match_operand:XF 0 "register_operand" "=f,f")
16694 (match_operator:XF 3 "binary_fp_operator"
16695 [(match_operand:XF 1 "register_operand" "0,0")
16697 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16698 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16699 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16700 [(set (attr "type")
16701 (cond [(match_operand:XF 3 "mult_operator" "")
16702 (const_string "fmul")
16703 (match_operand:XF 3 "div_operator" "")
16704 (const_string "fdiv")
16706 (const_string "fop")))
16707 (set_attr "fp_int_src" "true")
16708 (set_attr "mode" "<MODE>")])
16710 (define_insn "*fop_xf_4_i387"
16711 [(set (match_operand:XF 0 "register_operand" "=f,f")
16712 (match_operator:XF 3 "binary_fp_operator"
16714 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16715 (match_operand:XF 2 "register_operand" "0,f")]))]
16717 "* return output_387_binary_op (insn, operands);"
16718 [(set (attr "type")
16719 (cond [(match_operand:XF 3 "mult_operator" "")
16720 (const_string "fmul")
16721 (match_operand:XF 3 "div_operator" "")
16722 (const_string "fdiv")
16724 (const_string "fop")))
16725 (set_attr "mode" "<MODE>")])
16727 (define_insn "*fop_xf_5_i387"
16728 [(set (match_operand:XF 0 "register_operand" "=f,f")
16729 (match_operator:XF 3 "binary_fp_operator"
16730 [(match_operand:XF 1 "register_operand" "0,f")
16732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16734 "* return output_387_binary_op (insn, operands);"
16735 [(set (attr "type")
16736 (cond [(match_operand:XF 3 "mult_operator" "")
16737 (const_string "fmul")
16738 (match_operand:XF 3 "div_operator" "")
16739 (const_string "fdiv")
16741 (const_string "fop")))
16742 (set_attr "mode" "<MODE>")])
16744 (define_insn "*fop_xf_6_i387"
16745 [(set (match_operand:XF 0 "register_operand" "=f,f")
16746 (match_operator:XF 3 "binary_fp_operator"
16748 (match_operand:MODEF 1 "register_operand" "0,f"))
16750 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16752 "* return output_387_binary_op (insn, operands);"
16753 [(set (attr "type")
16754 (cond [(match_operand:XF 3 "mult_operator" "")
16755 (const_string "fmul")
16756 (match_operand:XF 3 "div_operator" "")
16757 (const_string "fdiv")
16759 (const_string "fop")))
16760 (set_attr "mode" "<MODE>")])
16763 [(set (match_operand 0 "register_operand" "")
16764 (match_operator 3 "binary_fp_operator"
16765 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16766 (match_operand 2 "register_operand" "")]))]
16768 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16769 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16772 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16773 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16774 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16775 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16776 GET_MODE (operands[3]),
16779 ix86_free_from_memory (GET_MODE (operands[1]));
16784 [(set (match_operand 0 "register_operand" "")
16785 (match_operator 3 "binary_fp_operator"
16786 [(match_operand 1 "register_operand" "")
16787 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16789 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16790 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16793 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16794 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16795 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16796 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16797 GET_MODE (operands[3]),
16800 ix86_free_from_memory (GET_MODE (operands[2]));
16804 ;; FPU special functions.
16806 ;; This pattern implements a no-op XFmode truncation for
16807 ;; all fancy i386 XFmode math functions.
16809 (define_insn "truncxf<mode>2_i387_noop_unspec"
16810 [(set (match_operand:MODEF 0 "register_operand" "=f")
16811 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16812 UNSPEC_TRUNC_NOOP))]
16813 "TARGET_USE_FANCY_MATH_387"
16814 "* return output_387_reg_move (insn, operands);"
16815 [(set_attr "type" "fmov")
16816 (set_attr "mode" "<MODE>")])
16818 (define_insn "sqrtxf2"
16819 [(set (match_operand:XF 0 "register_operand" "=f")
16820 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16821 "TARGET_USE_FANCY_MATH_387"
16823 [(set_attr "type" "fpspc")
16824 (set_attr "mode" "XF")
16825 (set_attr "athlon_decode" "direct")
16826 (set_attr "amdfam10_decode" "direct")])
16828 (define_insn "sqrt_extend<mode>xf2_i387"
16829 [(set (match_operand:XF 0 "register_operand" "=f")
16832 (match_operand:MODEF 1 "register_operand" "0"))))]
16833 "TARGET_USE_FANCY_MATH_387"
16835 [(set_attr "type" "fpspc")
16836 (set_attr "mode" "XF")
16837 (set_attr "athlon_decode" "direct")
16838 (set_attr "amdfam10_decode" "direct")])
16840 (define_insn "*rsqrtsf2_sse"
16841 [(set (match_operand:SF 0 "register_operand" "=x")
16842 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16845 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16846 [(set_attr "type" "sse")
16847 (set_attr "atom_sse_attr" "rcp")
16848 (set_attr "prefix" "maybe_vex")
16849 (set_attr "mode" "SF")])
16851 (define_expand "rsqrtsf2"
16852 [(set (match_operand:SF 0 "register_operand" "")
16853 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16857 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16861 (define_insn "*sqrt<mode>2_sse"
16862 [(set (match_operand:MODEF 0 "register_operand" "=x")
16864 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16865 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16866 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16867 [(set_attr "type" "sse")
16868 (set_attr "atom_sse_attr" "sqrt")
16869 (set_attr "prefix" "maybe_vex")
16870 (set_attr "mode" "<MODE>")
16871 (set_attr "athlon_decode" "*")
16872 (set_attr "amdfam10_decode" "*")])
16874 (define_expand "sqrt<mode>2"
16875 [(set (match_operand:MODEF 0 "register_operand" "")
16877 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16878 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16879 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16881 if (<MODE>mode == SFmode
16882 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16883 && flag_finite_math_only && !flag_trapping_math
16884 && flag_unsafe_math_optimizations)
16886 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16890 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16892 rtx op0 = gen_reg_rtx (XFmode);
16893 rtx op1 = force_reg (<MODE>mode, operands[1]);
16895 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16896 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16901 (define_insn "fpremxf4_i387"
16902 [(set (match_operand:XF 0 "register_operand" "=f")
16903 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16904 (match_operand:XF 3 "register_operand" "1")]
16906 (set (match_operand:XF 1 "register_operand" "=u")
16907 (unspec:XF [(match_dup 2) (match_dup 3)]
16909 (set (reg:CCFP FPSR_REG)
16910 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16912 "TARGET_USE_FANCY_MATH_387"
16914 [(set_attr "type" "fpspc")
16915 (set_attr "mode" "XF")])
16917 (define_expand "fmodxf3"
16918 [(use (match_operand:XF 0 "register_operand" ""))
16919 (use (match_operand:XF 1 "general_operand" ""))
16920 (use (match_operand:XF 2 "general_operand" ""))]
16921 "TARGET_USE_FANCY_MATH_387"
16923 rtx label = gen_label_rtx ();
16925 rtx op1 = gen_reg_rtx (XFmode);
16926 rtx op2 = gen_reg_rtx (XFmode);
16928 emit_move_insn (op2, operands[2]);
16929 emit_move_insn (op1, operands[1]);
16931 emit_label (label);
16932 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16933 ix86_emit_fp_unordered_jump (label);
16934 LABEL_NUSES (label) = 1;
16936 emit_move_insn (operands[0], op1);
16940 (define_expand "fmod<mode>3"
16941 [(use (match_operand:MODEF 0 "register_operand" ""))
16942 (use (match_operand:MODEF 1 "general_operand" ""))
16943 (use (match_operand:MODEF 2 "general_operand" ""))]
16944 "TARGET_USE_FANCY_MATH_387"
16946 rtx label = gen_label_rtx ();
16948 rtx op1 = gen_reg_rtx (XFmode);
16949 rtx op2 = gen_reg_rtx (XFmode);
16951 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16954 emit_label (label);
16955 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16956 ix86_emit_fp_unordered_jump (label);
16957 LABEL_NUSES (label) = 1;
16959 /* Truncate the result properly for strict SSE math. */
16960 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16961 && !TARGET_MIX_SSE_I387)
16962 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16964 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16969 (define_insn "fprem1xf4_i387"
16970 [(set (match_operand:XF 0 "register_operand" "=f")
16971 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16972 (match_operand:XF 3 "register_operand" "1")]
16974 (set (match_operand:XF 1 "register_operand" "=u")
16975 (unspec:XF [(match_dup 2) (match_dup 3)]
16977 (set (reg:CCFP FPSR_REG)
16978 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16980 "TARGET_USE_FANCY_MATH_387"
16982 [(set_attr "type" "fpspc")
16983 (set_attr "mode" "XF")])
16985 (define_expand "remainderxf3"
16986 [(use (match_operand:XF 0 "register_operand" ""))
16987 (use (match_operand:XF 1 "general_operand" ""))
16988 (use (match_operand:XF 2 "general_operand" ""))]
16989 "TARGET_USE_FANCY_MATH_387"
16991 rtx label = gen_label_rtx ();
16993 rtx op1 = gen_reg_rtx (XFmode);
16994 rtx op2 = gen_reg_rtx (XFmode);
16996 emit_move_insn (op2, operands[2]);
16997 emit_move_insn (op1, operands[1]);
16999 emit_label (label);
17000 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17001 ix86_emit_fp_unordered_jump (label);
17002 LABEL_NUSES (label) = 1;
17004 emit_move_insn (operands[0], op1);
17008 (define_expand "remainder<mode>3"
17009 [(use (match_operand:MODEF 0 "register_operand" ""))
17010 (use (match_operand:MODEF 1 "general_operand" ""))
17011 (use (match_operand:MODEF 2 "general_operand" ""))]
17012 "TARGET_USE_FANCY_MATH_387"
17014 rtx label = gen_label_rtx ();
17016 rtx op1 = gen_reg_rtx (XFmode);
17017 rtx op2 = gen_reg_rtx (XFmode);
17019 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17020 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17022 emit_label (label);
17024 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17025 ix86_emit_fp_unordered_jump (label);
17026 LABEL_NUSES (label) = 1;
17028 /* Truncate the result properly for strict SSE math. */
17029 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17030 && !TARGET_MIX_SSE_I387)
17031 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17033 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17038 (define_insn "*sinxf2_i387"
17039 [(set (match_operand:XF 0 "register_operand" "=f")
17040 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17041 "TARGET_USE_FANCY_MATH_387
17042 && flag_unsafe_math_optimizations"
17044 [(set_attr "type" "fpspc")
17045 (set_attr "mode" "XF")])
17047 (define_insn "*sin_extend<mode>xf2_i387"
17048 [(set (match_operand:XF 0 "register_operand" "=f")
17049 (unspec:XF [(float_extend:XF
17050 (match_operand:MODEF 1 "register_operand" "0"))]
17052 "TARGET_USE_FANCY_MATH_387
17053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17054 || TARGET_MIX_SSE_I387)
17055 && flag_unsafe_math_optimizations"
17057 [(set_attr "type" "fpspc")
17058 (set_attr "mode" "XF")])
17060 (define_insn "*cosxf2_i387"
17061 [(set (match_operand:XF 0 "register_operand" "=f")
17062 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17066 [(set_attr "type" "fpspc")
17067 (set_attr "mode" "XF")])
17069 (define_insn "*cos_extend<mode>xf2_i387"
17070 [(set (match_operand:XF 0 "register_operand" "=f")
17071 (unspec:XF [(float_extend:XF
17072 (match_operand:MODEF 1 "register_operand" "0"))]
17074 "TARGET_USE_FANCY_MATH_387
17075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17076 || TARGET_MIX_SSE_I387)
17077 && flag_unsafe_math_optimizations"
17079 [(set_attr "type" "fpspc")
17080 (set_attr "mode" "XF")])
17082 ;; When sincos pattern is defined, sin and cos builtin functions will be
17083 ;; expanded to sincos pattern with one of its outputs left unused.
17084 ;; CSE pass will figure out if two sincos patterns can be combined,
17085 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17086 ;; depending on the unused output.
17088 (define_insn "sincosxf3"
17089 [(set (match_operand:XF 0 "register_operand" "=f")
17090 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17091 UNSPEC_SINCOS_COS))
17092 (set (match_operand:XF 1 "register_operand" "=u")
17093 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17094 "TARGET_USE_FANCY_MATH_387
17095 && flag_unsafe_math_optimizations"
17097 [(set_attr "type" "fpspc")
17098 (set_attr "mode" "XF")])
17101 [(set (match_operand:XF 0 "register_operand" "")
17102 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17103 UNSPEC_SINCOS_COS))
17104 (set (match_operand:XF 1 "register_operand" "")
17105 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17106 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17107 && !(reload_completed || reload_in_progress)"
17108 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17112 [(set (match_operand:XF 0 "register_operand" "")
17113 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17114 UNSPEC_SINCOS_COS))
17115 (set (match_operand:XF 1 "register_operand" "")
17116 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17117 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17118 && !(reload_completed || reload_in_progress)"
17119 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17122 (define_insn "sincos_extend<mode>xf3_i387"
17123 [(set (match_operand:XF 0 "register_operand" "=f")
17124 (unspec:XF [(float_extend:XF
17125 (match_operand:MODEF 2 "register_operand" "0"))]
17126 UNSPEC_SINCOS_COS))
17127 (set (match_operand:XF 1 "register_operand" "=u")
17128 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17129 "TARGET_USE_FANCY_MATH_387
17130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131 || TARGET_MIX_SSE_I387)
17132 && flag_unsafe_math_optimizations"
17134 [(set_attr "type" "fpspc")
17135 (set_attr "mode" "XF")])
17138 [(set (match_operand:XF 0 "register_operand" "")
17139 (unspec:XF [(float_extend:XF
17140 (match_operand:MODEF 2 "register_operand" ""))]
17141 UNSPEC_SINCOS_COS))
17142 (set (match_operand:XF 1 "register_operand" "")
17143 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17144 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17145 && !(reload_completed || reload_in_progress)"
17146 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17150 [(set (match_operand:XF 0 "register_operand" "")
17151 (unspec:XF [(float_extend:XF
17152 (match_operand:MODEF 2 "register_operand" ""))]
17153 UNSPEC_SINCOS_COS))
17154 (set (match_operand:XF 1 "register_operand" "")
17155 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17156 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17157 && !(reload_completed || reload_in_progress)"
17158 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17161 (define_expand "sincos<mode>3"
17162 [(use (match_operand:MODEF 0 "register_operand" ""))
17163 (use (match_operand:MODEF 1 "register_operand" ""))
17164 (use (match_operand:MODEF 2 "register_operand" ""))]
17165 "TARGET_USE_FANCY_MATH_387
17166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17167 || TARGET_MIX_SSE_I387)
17168 && flag_unsafe_math_optimizations"
17170 rtx op0 = gen_reg_rtx (XFmode);
17171 rtx op1 = gen_reg_rtx (XFmode);
17173 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17175 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17179 (define_insn "fptanxf4_i387"
17180 [(set (match_operand:XF 0 "register_operand" "=f")
17181 (match_operand:XF 3 "const_double_operand" "F"))
17182 (set (match_operand:XF 1 "register_operand" "=u")
17183 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17185 "TARGET_USE_FANCY_MATH_387
17186 && flag_unsafe_math_optimizations
17187 && standard_80387_constant_p (operands[3]) == 2"
17189 [(set_attr "type" "fpspc")
17190 (set_attr "mode" "XF")])
17192 (define_insn "fptan_extend<mode>xf4_i387"
17193 [(set (match_operand:MODEF 0 "register_operand" "=f")
17194 (match_operand:MODEF 3 "const_double_operand" "F"))
17195 (set (match_operand:XF 1 "register_operand" "=u")
17196 (unspec:XF [(float_extend:XF
17197 (match_operand:MODEF 2 "register_operand" "0"))]
17199 "TARGET_USE_FANCY_MATH_387
17200 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17201 || TARGET_MIX_SSE_I387)
17202 && flag_unsafe_math_optimizations
17203 && standard_80387_constant_p (operands[3]) == 2"
17205 [(set_attr "type" "fpspc")
17206 (set_attr "mode" "XF")])
17208 (define_expand "tanxf2"
17209 [(use (match_operand:XF 0 "register_operand" ""))
17210 (use (match_operand:XF 1 "register_operand" ""))]
17211 "TARGET_USE_FANCY_MATH_387
17212 && flag_unsafe_math_optimizations"
17214 rtx one = gen_reg_rtx (XFmode);
17215 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17217 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17221 (define_expand "tan<mode>2"
17222 [(use (match_operand:MODEF 0 "register_operand" ""))
17223 (use (match_operand:MODEF 1 "register_operand" ""))]
17224 "TARGET_USE_FANCY_MATH_387
17225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17226 || TARGET_MIX_SSE_I387)
17227 && flag_unsafe_math_optimizations"
17229 rtx op0 = gen_reg_rtx (XFmode);
17231 rtx one = gen_reg_rtx (<MODE>mode);
17232 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17234 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17235 operands[1], op2));
17236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17240 (define_insn "*fpatanxf3_i387"
17241 [(set (match_operand:XF 0 "register_operand" "=f")
17242 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17243 (match_operand:XF 2 "register_operand" "u")]
17245 (clobber (match_scratch:XF 3 "=2"))]
17246 "TARGET_USE_FANCY_MATH_387
17247 && flag_unsafe_math_optimizations"
17249 [(set_attr "type" "fpspc")
17250 (set_attr "mode" "XF")])
17252 (define_insn "fpatan_extend<mode>xf3_i387"
17253 [(set (match_operand:XF 0 "register_operand" "=f")
17254 (unspec:XF [(float_extend:XF
17255 (match_operand:MODEF 1 "register_operand" "0"))
17257 (match_operand:MODEF 2 "register_operand" "u"))]
17259 (clobber (match_scratch:XF 3 "=2"))]
17260 "TARGET_USE_FANCY_MATH_387
17261 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17262 || TARGET_MIX_SSE_I387)
17263 && flag_unsafe_math_optimizations"
17265 [(set_attr "type" "fpspc")
17266 (set_attr "mode" "XF")])
17268 (define_expand "atan2xf3"
17269 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17270 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17271 (match_operand:XF 1 "register_operand" "")]
17273 (clobber (match_scratch:XF 3 ""))])]
17274 "TARGET_USE_FANCY_MATH_387
17275 && flag_unsafe_math_optimizations"
17278 (define_expand "atan2<mode>3"
17279 [(use (match_operand:MODEF 0 "register_operand" ""))
17280 (use (match_operand:MODEF 1 "register_operand" ""))
17281 (use (match_operand:MODEF 2 "register_operand" ""))]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284 || TARGET_MIX_SSE_I387)
17285 && flag_unsafe_math_optimizations"
17287 rtx op0 = gen_reg_rtx (XFmode);
17289 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17290 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17294 (define_expand "atanxf2"
17295 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17296 (unspec:XF [(match_dup 2)
17297 (match_operand:XF 1 "register_operand" "")]
17299 (clobber (match_scratch:XF 3 ""))])]
17300 "TARGET_USE_FANCY_MATH_387
17301 && flag_unsafe_math_optimizations"
17303 operands[2] = gen_reg_rtx (XFmode);
17304 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17307 (define_expand "atan<mode>2"
17308 [(use (match_operand:MODEF 0 "register_operand" ""))
17309 (use (match_operand:MODEF 1 "register_operand" ""))]
17310 "TARGET_USE_FANCY_MATH_387
17311 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17312 || TARGET_MIX_SSE_I387)
17313 && flag_unsafe_math_optimizations"
17315 rtx op0 = gen_reg_rtx (XFmode);
17317 rtx op2 = gen_reg_rtx (<MODE>mode);
17318 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17320 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17321 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17325 (define_expand "asinxf2"
17326 [(set (match_dup 2)
17327 (mult:XF (match_operand:XF 1 "register_operand" "")
17329 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17330 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17331 (parallel [(set (match_operand:XF 0 "register_operand" "")
17332 (unspec:XF [(match_dup 5) (match_dup 1)]
17334 (clobber (match_scratch:XF 6 ""))])]
17335 "TARGET_USE_FANCY_MATH_387
17336 && flag_unsafe_math_optimizations"
17340 if (optimize_insn_for_size_p ())
17343 for (i = 2; i < 6; i++)
17344 operands[i] = gen_reg_rtx (XFmode);
17346 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17349 (define_expand "asin<mode>2"
17350 [(use (match_operand:MODEF 0 "register_operand" ""))
17351 (use (match_operand:MODEF 1 "general_operand" ""))]
17352 "TARGET_USE_FANCY_MATH_387
17353 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17354 || TARGET_MIX_SSE_I387)
17355 && flag_unsafe_math_optimizations"
17357 rtx op0 = gen_reg_rtx (XFmode);
17358 rtx op1 = gen_reg_rtx (XFmode);
17360 if (optimize_insn_for_size_p ())
17363 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17364 emit_insn (gen_asinxf2 (op0, op1));
17365 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17369 (define_expand "acosxf2"
17370 [(set (match_dup 2)
17371 (mult:XF (match_operand:XF 1 "register_operand" "")
17373 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17374 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17375 (parallel [(set (match_operand:XF 0 "register_operand" "")
17376 (unspec:XF [(match_dup 1) (match_dup 5)]
17378 (clobber (match_scratch:XF 6 ""))])]
17379 "TARGET_USE_FANCY_MATH_387
17380 && flag_unsafe_math_optimizations"
17384 if (optimize_insn_for_size_p ())
17387 for (i = 2; i < 6; i++)
17388 operands[i] = gen_reg_rtx (XFmode);
17390 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17393 (define_expand "acos<mode>2"
17394 [(use (match_operand:MODEF 0 "register_operand" ""))
17395 (use (match_operand:MODEF 1 "general_operand" ""))]
17396 "TARGET_USE_FANCY_MATH_387
17397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17398 || TARGET_MIX_SSE_I387)
17399 && flag_unsafe_math_optimizations"
17401 rtx op0 = gen_reg_rtx (XFmode);
17402 rtx op1 = gen_reg_rtx (XFmode);
17404 if (optimize_insn_for_size_p ())
17407 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17408 emit_insn (gen_acosxf2 (op0, op1));
17409 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17413 (define_insn "fyl2xxf3_i387"
17414 [(set (match_operand:XF 0 "register_operand" "=f")
17415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17416 (match_operand:XF 2 "register_operand" "u")]
17418 (clobber (match_scratch:XF 3 "=2"))]
17419 "TARGET_USE_FANCY_MATH_387
17420 && flag_unsafe_math_optimizations"
17422 [(set_attr "type" "fpspc")
17423 (set_attr "mode" "XF")])
17425 (define_insn "fyl2x_extend<mode>xf3_i387"
17426 [(set (match_operand:XF 0 "register_operand" "=f")
17427 (unspec:XF [(float_extend:XF
17428 (match_operand:MODEF 1 "register_operand" "0"))
17429 (match_operand:XF 2 "register_operand" "u")]
17431 (clobber (match_scratch:XF 3 "=2"))]
17432 "TARGET_USE_FANCY_MATH_387
17433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434 || TARGET_MIX_SSE_I387)
17435 && flag_unsafe_math_optimizations"
17437 [(set_attr "type" "fpspc")
17438 (set_attr "mode" "XF")])
17440 (define_expand "logxf2"
17441 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17442 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17443 (match_dup 2)] UNSPEC_FYL2X))
17444 (clobber (match_scratch:XF 3 ""))])]
17445 "TARGET_USE_FANCY_MATH_387
17446 && flag_unsafe_math_optimizations"
17448 operands[2] = gen_reg_rtx (XFmode);
17449 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17452 (define_expand "log<mode>2"
17453 [(use (match_operand:MODEF 0 "register_operand" ""))
17454 (use (match_operand:MODEF 1 "register_operand" ""))]
17455 "TARGET_USE_FANCY_MATH_387
17456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17457 || TARGET_MIX_SSE_I387)
17458 && flag_unsafe_math_optimizations"
17460 rtx op0 = gen_reg_rtx (XFmode);
17462 rtx op2 = gen_reg_rtx (XFmode);
17463 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17465 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17470 (define_expand "log10xf2"
17471 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17472 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17473 (match_dup 2)] UNSPEC_FYL2X))
17474 (clobber (match_scratch:XF 3 ""))])]
17475 "TARGET_USE_FANCY_MATH_387
17476 && flag_unsafe_math_optimizations"
17478 operands[2] = gen_reg_rtx (XFmode);
17479 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17482 (define_expand "log10<mode>2"
17483 [(use (match_operand:MODEF 0 "register_operand" ""))
17484 (use (match_operand:MODEF 1 "register_operand" ""))]
17485 "TARGET_USE_FANCY_MATH_387
17486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17487 || TARGET_MIX_SSE_I387)
17488 && flag_unsafe_math_optimizations"
17490 rtx op0 = gen_reg_rtx (XFmode);
17492 rtx op2 = gen_reg_rtx (XFmode);
17493 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17495 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17496 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17500 (define_expand "log2xf2"
17501 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17502 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17503 (match_dup 2)] UNSPEC_FYL2X))
17504 (clobber (match_scratch:XF 3 ""))])]
17505 "TARGET_USE_FANCY_MATH_387
17506 && flag_unsafe_math_optimizations"
17508 operands[2] = gen_reg_rtx (XFmode);
17509 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17512 (define_expand "log2<mode>2"
17513 [(use (match_operand:MODEF 0 "register_operand" ""))
17514 (use (match_operand:MODEF 1 "register_operand" ""))]
17515 "TARGET_USE_FANCY_MATH_387
17516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17517 || TARGET_MIX_SSE_I387)
17518 && flag_unsafe_math_optimizations"
17520 rtx op0 = gen_reg_rtx (XFmode);
17522 rtx op2 = gen_reg_rtx (XFmode);
17523 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17525 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17530 (define_insn "fyl2xp1xf3_i387"
17531 [(set (match_operand:XF 0 "register_operand" "=f")
17532 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17533 (match_operand:XF 2 "register_operand" "u")]
17535 (clobber (match_scratch:XF 3 "=2"))]
17536 "TARGET_USE_FANCY_MATH_387
17537 && flag_unsafe_math_optimizations"
17539 [(set_attr "type" "fpspc")
17540 (set_attr "mode" "XF")])
17542 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17543 [(set (match_operand:XF 0 "register_operand" "=f")
17544 (unspec:XF [(float_extend:XF
17545 (match_operand:MODEF 1 "register_operand" "0"))
17546 (match_operand:XF 2 "register_operand" "u")]
17548 (clobber (match_scratch:XF 3 "=2"))]
17549 "TARGET_USE_FANCY_MATH_387
17550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17551 || TARGET_MIX_SSE_I387)
17552 && flag_unsafe_math_optimizations"
17554 [(set_attr "type" "fpspc")
17555 (set_attr "mode" "XF")])
17557 (define_expand "log1pxf2"
17558 [(use (match_operand:XF 0 "register_operand" ""))
17559 (use (match_operand:XF 1 "register_operand" ""))]
17560 "TARGET_USE_FANCY_MATH_387
17561 && flag_unsafe_math_optimizations"
17563 if (optimize_insn_for_size_p ())
17566 ix86_emit_i387_log1p (operands[0], operands[1]);
17570 (define_expand "log1p<mode>2"
17571 [(use (match_operand:MODEF 0 "register_operand" ""))
17572 (use (match_operand:MODEF 1 "register_operand" ""))]
17573 "TARGET_USE_FANCY_MATH_387
17574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17575 || TARGET_MIX_SSE_I387)
17576 && flag_unsafe_math_optimizations"
17580 if (optimize_insn_for_size_p ())
17583 op0 = gen_reg_rtx (XFmode);
17585 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17587 ix86_emit_i387_log1p (op0, operands[1]);
17588 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17592 (define_insn "fxtractxf3_i387"
17593 [(set (match_operand:XF 0 "register_operand" "=f")
17594 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17595 UNSPEC_XTRACT_FRACT))
17596 (set (match_operand:XF 1 "register_operand" "=u")
17597 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17598 "TARGET_USE_FANCY_MATH_387
17599 && flag_unsafe_math_optimizations"
17601 [(set_attr "type" "fpspc")
17602 (set_attr "mode" "XF")])
17604 (define_insn "fxtract_extend<mode>xf3_i387"
17605 [(set (match_operand:XF 0 "register_operand" "=f")
17606 (unspec:XF [(float_extend:XF
17607 (match_operand:MODEF 2 "register_operand" "0"))]
17608 UNSPEC_XTRACT_FRACT))
17609 (set (match_operand:XF 1 "register_operand" "=u")
17610 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17611 "TARGET_USE_FANCY_MATH_387
17612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17613 || TARGET_MIX_SSE_I387)
17614 && flag_unsafe_math_optimizations"
17616 [(set_attr "type" "fpspc")
17617 (set_attr "mode" "XF")])
17619 (define_expand "logbxf2"
17620 [(parallel [(set (match_dup 2)
17621 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17622 UNSPEC_XTRACT_FRACT))
17623 (set (match_operand:XF 0 "register_operand" "")
17624 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17625 "TARGET_USE_FANCY_MATH_387
17626 && flag_unsafe_math_optimizations"
17628 operands[2] = gen_reg_rtx (XFmode);
17631 (define_expand "logb<mode>2"
17632 [(use (match_operand:MODEF 0 "register_operand" ""))
17633 (use (match_operand:MODEF 1 "register_operand" ""))]
17634 "TARGET_USE_FANCY_MATH_387
17635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17636 || TARGET_MIX_SSE_I387)
17637 && flag_unsafe_math_optimizations"
17639 rtx op0 = gen_reg_rtx (XFmode);
17640 rtx op1 = gen_reg_rtx (XFmode);
17642 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17643 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17647 (define_expand "ilogbxf2"
17648 [(use (match_operand:SI 0 "register_operand" ""))
17649 (use (match_operand:XF 1 "register_operand" ""))]
17650 "TARGET_USE_FANCY_MATH_387
17651 && flag_unsafe_math_optimizations"
17655 if (optimize_insn_for_size_p ())
17658 op0 = gen_reg_rtx (XFmode);
17659 op1 = gen_reg_rtx (XFmode);
17661 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17662 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17666 (define_expand "ilogb<mode>2"
17667 [(use (match_operand:SI 0 "register_operand" ""))
17668 (use (match_operand:MODEF 1 "register_operand" ""))]
17669 "TARGET_USE_FANCY_MATH_387
17670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17671 || TARGET_MIX_SSE_I387)
17672 && flag_unsafe_math_optimizations"
17676 if (optimize_insn_for_size_p ())
17679 op0 = gen_reg_rtx (XFmode);
17680 op1 = gen_reg_rtx (XFmode);
17682 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17683 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17687 (define_insn "*f2xm1xf2_i387"
17688 [(set (match_operand:XF 0 "register_operand" "=f")
17689 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17691 "TARGET_USE_FANCY_MATH_387
17692 && flag_unsafe_math_optimizations"
17694 [(set_attr "type" "fpspc")
17695 (set_attr "mode" "XF")])
17697 (define_insn "*fscalexf4_i387"
17698 [(set (match_operand:XF 0 "register_operand" "=f")
17699 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17700 (match_operand:XF 3 "register_operand" "1")]
17701 UNSPEC_FSCALE_FRACT))
17702 (set (match_operand:XF 1 "register_operand" "=u")
17703 (unspec:XF [(match_dup 2) (match_dup 3)]
17704 UNSPEC_FSCALE_EXP))]
17705 "TARGET_USE_FANCY_MATH_387
17706 && flag_unsafe_math_optimizations"
17708 [(set_attr "type" "fpspc")
17709 (set_attr "mode" "XF")])
17711 (define_expand "expNcorexf3"
17712 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17713 (match_operand:XF 2 "register_operand" "")))
17714 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17715 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17716 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17717 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17718 (parallel [(set (match_operand:XF 0 "register_operand" "")
17719 (unspec:XF [(match_dup 8) (match_dup 4)]
17720 UNSPEC_FSCALE_FRACT))
17722 (unspec:XF [(match_dup 8) (match_dup 4)]
17723 UNSPEC_FSCALE_EXP))])]
17724 "TARGET_USE_FANCY_MATH_387
17725 && flag_unsafe_math_optimizations"
17729 if (optimize_insn_for_size_p ())
17732 for (i = 3; i < 10; i++)
17733 operands[i] = gen_reg_rtx (XFmode);
17735 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17738 (define_expand "expxf2"
17739 [(use (match_operand:XF 0 "register_operand" ""))
17740 (use (match_operand:XF 1 "register_operand" ""))]
17741 "TARGET_USE_FANCY_MATH_387
17742 && flag_unsafe_math_optimizations"
17746 if (optimize_insn_for_size_p ())
17749 op2 = gen_reg_rtx (XFmode);
17750 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17752 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17756 (define_expand "exp<mode>2"
17757 [(use (match_operand:MODEF 0 "register_operand" ""))
17758 (use (match_operand:MODEF 1 "general_operand" ""))]
17759 "TARGET_USE_FANCY_MATH_387
17760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17761 || TARGET_MIX_SSE_I387)
17762 && flag_unsafe_math_optimizations"
17766 if (optimize_insn_for_size_p ())
17769 op0 = gen_reg_rtx (XFmode);
17770 op1 = gen_reg_rtx (XFmode);
17772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17773 emit_insn (gen_expxf2 (op0, op1));
17774 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17778 (define_expand "exp10xf2"
17779 [(use (match_operand:XF 0 "register_operand" ""))
17780 (use (match_operand:XF 1 "register_operand" ""))]
17781 "TARGET_USE_FANCY_MATH_387
17782 && flag_unsafe_math_optimizations"
17786 if (optimize_insn_for_size_p ())
17789 op2 = gen_reg_rtx (XFmode);
17790 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17792 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17796 (define_expand "exp10<mode>2"
17797 [(use (match_operand:MODEF 0 "register_operand" ""))
17798 (use (match_operand:MODEF 1 "general_operand" ""))]
17799 "TARGET_USE_FANCY_MATH_387
17800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17801 || TARGET_MIX_SSE_I387)
17802 && flag_unsafe_math_optimizations"
17806 if (optimize_insn_for_size_p ())
17809 op0 = gen_reg_rtx (XFmode);
17810 op1 = gen_reg_rtx (XFmode);
17812 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17813 emit_insn (gen_exp10xf2 (op0, op1));
17814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17818 (define_expand "exp2xf2"
17819 [(use (match_operand:XF 0 "register_operand" ""))
17820 (use (match_operand:XF 1 "register_operand" ""))]
17821 "TARGET_USE_FANCY_MATH_387
17822 && flag_unsafe_math_optimizations"
17826 if (optimize_insn_for_size_p ())
17829 op2 = gen_reg_rtx (XFmode);
17830 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17832 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17836 (define_expand "exp2<mode>2"
17837 [(use (match_operand:MODEF 0 "register_operand" ""))
17838 (use (match_operand:MODEF 1 "general_operand" ""))]
17839 "TARGET_USE_FANCY_MATH_387
17840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17841 || TARGET_MIX_SSE_I387)
17842 && flag_unsafe_math_optimizations"
17846 if (optimize_insn_for_size_p ())
17849 op0 = gen_reg_rtx (XFmode);
17850 op1 = gen_reg_rtx (XFmode);
17852 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17853 emit_insn (gen_exp2xf2 (op0, op1));
17854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17858 (define_expand "expm1xf2"
17859 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17861 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17862 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17863 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17864 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17865 (parallel [(set (match_dup 7)
17866 (unspec:XF [(match_dup 6) (match_dup 4)]
17867 UNSPEC_FSCALE_FRACT))
17869 (unspec:XF [(match_dup 6) (match_dup 4)]
17870 UNSPEC_FSCALE_EXP))])
17871 (parallel [(set (match_dup 10)
17872 (unspec:XF [(match_dup 9) (match_dup 8)]
17873 UNSPEC_FSCALE_FRACT))
17874 (set (match_dup 11)
17875 (unspec:XF [(match_dup 9) (match_dup 8)]
17876 UNSPEC_FSCALE_EXP))])
17877 (set (match_dup 12) (minus:XF (match_dup 10)
17878 (float_extend:XF (match_dup 13))))
17879 (set (match_operand:XF 0 "register_operand" "")
17880 (plus:XF (match_dup 12) (match_dup 7)))]
17881 "TARGET_USE_FANCY_MATH_387
17882 && flag_unsafe_math_optimizations"
17886 if (optimize_insn_for_size_p ())
17889 for (i = 2; i < 13; i++)
17890 operands[i] = gen_reg_rtx (XFmode);
17893 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17895 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17898 (define_expand "expm1<mode>2"
17899 [(use (match_operand:MODEF 0 "register_operand" ""))
17900 (use (match_operand:MODEF 1 "general_operand" ""))]
17901 "TARGET_USE_FANCY_MATH_387
17902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17903 || TARGET_MIX_SSE_I387)
17904 && flag_unsafe_math_optimizations"
17908 if (optimize_insn_for_size_p ())
17911 op0 = gen_reg_rtx (XFmode);
17912 op1 = gen_reg_rtx (XFmode);
17914 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17915 emit_insn (gen_expm1xf2 (op0, op1));
17916 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17920 (define_expand "ldexpxf3"
17921 [(set (match_dup 3)
17922 (float:XF (match_operand:SI 2 "register_operand" "")))
17923 (parallel [(set (match_operand:XF 0 " register_operand" "")
17924 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17926 UNSPEC_FSCALE_FRACT))
17928 (unspec:XF [(match_dup 1) (match_dup 3)]
17929 UNSPEC_FSCALE_EXP))])]
17930 "TARGET_USE_FANCY_MATH_387
17931 && flag_unsafe_math_optimizations"
17933 if (optimize_insn_for_size_p ())
17936 operands[3] = gen_reg_rtx (XFmode);
17937 operands[4] = gen_reg_rtx (XFmode);
17940 (define_expand "ldexp<mode>3"
17941 [(use (match_operand:MODEF 0 "register_operand" ""))
17942 (use (match_operand:MODEF 1 "general_operand" ""))
17943 (use (match_operand:SI 2 "register_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"
17951 if (optimize_insn_for_size_p ())
17954 op0 = gen_reg_rtx (XFmode);
17955 op1 = gen_reg_rtx (XFmode);
17957 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17958 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17959 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17963 (define_expand "scalbxf3"
17964 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17965 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17966 (match_operand:XF 2 "register_operand" "")]
17967 UNSPEC_FSCALE_FRACT))
17969 (unspec:XF [(match_dup 1) (match_dup 2)]
17970 UNSPEC_FSCALE_EXP))])]
17971 "TARGET_USE_FANCY_MATH_387
17972 && flag_unsafe_math_optimizations"
17974 if (optimize_insn_for_size_p ())
17977 operands[3] = gen_reg_rtx (XFmode);
17980 (define_expand "scalb<mode>3"
17981 [(use (match_operand:MODEF 0 "register_operand" ""))
17982 (use (match_operand:MODEF 1 "general_operand" ""))
17983 (use (match_operand:MODEF 2 "register_operand" ""))]
17984 "TARGET_USE_FANCY_MATH_387
17985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17986 || TARGET_MIX_SSE_I387)
17987 && flag_unsafe_math_optimizations"
17991 if (optimize_insn_for_size_p ())
17994 op0 = gen_reg_rtx (XFmode);
17995 op1 = gen_reg_rtx (XFmode);
17996 op2 = gen_reg_rtx (XFmode);
17998 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17999 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18000 emit_insn (gen_scalbxf3 (op0, op1, op2));
18001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18006 (define_insn "sse4_1_round<mode>2"
18007 [(set (match_operand:MODEF 0 "register_operand" "=x")
18008 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18009 (match_operand:SI 2 "const_0_to_15_operand" "n")]
18012 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18013 [(set_attr "type" "ssecvt")
18014 (set_attr "prefix_extra" "1")
18015 (set_attr "prefix" "maybe_vex")
18016 (set_attr "mode" "<MODE>")])
18018 (define_insn "rintxf2"
18019 [(set (match_operand:XF 0 "register_operand" "=f")
18020 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18022 "TARGET_USE_FANCY_MATH_387
18023 && flag_unsafe_math_optimizations"
18025 [(set_attr "type" "fpspc")
18026 (set_attr "mode" "XF")])
18028 (define_expand "rint<mode>2"
18029 [(use (match_operand:MODEF 0 "register_operand" ""))
18030 (use (match_operand:MODEF 1 "register_operand" ""))]
18031 "(TARGET_USE_FANCY_MATH_387
18032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18033 || TARGET_MIX_SSE_I387)
18034 && flag_unsafe_math_optimizations)
18035 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18036 && !flag_trapping_math)"
18038 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18039 && !flag_trapping_math)
18041 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18044 emit_insn (gen_sse4_1_round<mode>2
18045 (operands[0], operands[1], GEN_INT (0x04)));
18047 ix86_expand_rint (operand0, operand1);
18051 rtx op0 = gen_reg_rtx (XFmode);
18052 rtx op1 = gen_reg_rtx (XFmode);
18054 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18055 emit_insn (gen_rintxf2 (op0, op1));
18057 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18062 (define_expand "round<mode>2"
18063 [(match_operand:MODEF 0 "register_operand" "")
18064 (match_operand:MODEF 1 "nonimmediate_operand" "")]
18065 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18066 && !flag_trapping_math && !flag_rounding_math"
18068 if (optimize_insn_for_size_p ())
18070 if (TARGET_64BIT || (<MODE>mode != DFmode))
18071 ix86_expand_round (operand0, operand1);
18073 ix86_expand_rounddf_32 (operand0, operand1);
18077 (define_insn_and_split "*fistdi2_1"
18078 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18079 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18081 "TARGET_USE_FANCY_MATH_387
18082 && !(reload_completed || reload_in_progress)"
18087 if (memory_operand (operands[0], VOIDmode))
18088 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18091 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18092 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18097 [(set_attr "type" "fpspc")
18098 (set_attr "mode" "DI")])
18100 (define_insn "fistdi2"
18101 [(set (match_operand:DI 0 "memory_operand" "=m")
18102 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18104 (clobber (match_scratch:XF 2 "=&1f"))]
18105 "TARGET_USE_FANCY_MATH_387"
18106 "* return output_fix_trunc (insn, operands, 0);"
18107 [(set_attr "type" "fpspc")
18108 (set_attr "mode" "DI")])
18110 (define_insn "fistdi2_with_temp"
18111 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18112 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18114 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18115 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18116 "TARGET_USE_FANCY_MATH_387"
18118 [(set_attr "type" "fpspc")
18119 (set_attr "mode" "DI")])
18122 [(set (match_operand:DI 0 "register_operand" "")
18123 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18125 (clobber (match_operand:DI 2 "memory_operand" ""))
18126 (clobber (match_scratch 3 ""))]
18128 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18129 (clobber (match_dup 3))])
18130 (set (match_dup 0) (match_dup 2))]
18134 [(set (match_operand:DI 0 "memory_operand" "")
18135 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18137 (clobber (match_operand:DI 2 "memory_operand" ""))
18138 (clobber (match_scratch 3 ""))]
18140 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18141 (clobber (match_dup 3))])]
18144 (define_insn_and_split "*fist<mode>2_1"
18145 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18146 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18148 "TARGET_USE_FANCY_MATH_387
18149 && !(reload_completed || reload_in_progress)"
18154 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18155 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18159 [(set_attr "type" "fpspc")
18160 (set_attr "mode" "<MODE>")])
18162 (define_insn "fist<mode>2"
18163 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18164 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18166 "TARGET_USE_FANCY_MATH_387"
18167 "* return output_fix_trunc (insn, operands, 0);"
18168 [(set_attr "type" "fpspc")
18169 (set_attr "mode" "<MODE>")])
18171 (define_insn "fist<mode>2_with_temp"
18172 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18173 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18175 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18176 "TARGET_USE_FANCY_MATH_387"
18178 [(set_attr "type" "fpspc")
18179 (set_attr "mode" "<MODE>")])
18182 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18183 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18185 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18187 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18188 (set (match_dup 0) (match_dup 2))]
18192 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18193 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18195 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18197 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18200 (define_expand "lrintxf<mode>2"
18201 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18202 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18204 "TARGET_USE_FANCY_MATH_387"
18207 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18208 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18209 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18210 UNSPEC_FIX_NOTRUNC))]
18211 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18212 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18215 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18216 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18217 (match_operand:MODEF 1 "register_operand" "")]
18218 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18219 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18220 && !flag_trapping_math && !flag_rounding_math"
18222 if (optimize_insn_for_size_p ())
18224 ix86_expand_lround (operand0, operand1);
18228 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18229 (define_insn_and_split "frndintxf2_floor"
18230 [(set (match_operand:XF 0 "register_operand" "")
18231 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18232 UNSPEC_FRNDINT_FLOOR))
18233 (clobber (reg:CC FLAGS_REG))]
18234 "TARGET_USE_FANCY_MATH_387
18235 && flag_unsafe_math_optimizations
18236 && !(reload_completed || reload_in_progress)"
18241 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18243 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18244 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18246 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18247 operands[2], operands[3]));
18250 [(set_attr "type" "frndint")
18251 (set_attr "i387_cw" "floor")
18252 (set_attr "mode" "XF")])
18254 (define_insn "frndintxf2_floor_i387"
18255 [(set (match_operand:XF 0 "register_operand" "=f")
18256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18257 UNSPEC_FRNDINT_FLOOR))
18258 (use (match_operand:HI 2 "memory_operand" "m"))
18259 (use (match_operand:HI 3 "memory_operand" "m"))]
18260 "TARGET_USE_FANCY_MATH_387
18261 && flag_unsafe_math_optimizations"
18262 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18263 [(set_attr "type" "frndint")
18264 (set_attr "i387_cw" "floor")
18265 (set_attr "mode" "XF")])
18267 (define_expand "floorxf2"
18268 [(use (match_operand:XF 0 "register_operand" ""))
18269 (use (match_operand:XF 1 "register_operand" ""))]
18270 "TARGET_USE_FANCY_MATH_387
18271 && flag_unsafe_math_optimizations"
18273 if (optimize_insn_for_size_p ())
18275 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18279 (define_expand "floor<mode>2"
18280 [(use (match_operand:MODEF 0 "register_operand" ""))
18281 (use (match_operand:MODEF 1 "register_operand" ""))]
18282 "(TARGET_USE_FANCY_MATH_387
18283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18284 || TARGET_MIX_SSE_I387)
18285 && flag_unsafe_math_optimizations)
18286 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18287 && !flag_trapping_math)"
18289 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18290 && !flag_trapping_math
18291 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18293 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18296 emit_insn (gen_sse4_1_round<mode>2
18297 (operands[0], operands[1], GEN_INT (0x01)));
18298 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18299 ix86_expand_floorceil (operand0, operand1, true);
18301 ix86_expand_floorceildf_32 (operand0, operand1, true);
18307 if (optimize_insn_for_size_p ())
18310 op0 = gen_reg_rtx (XFmode);
18311 op1 = gen_reg_rtx (XFmode);
18312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18313 emit_insn (gen_frndintxf2_floor (op0, op1));
18315 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18320 (define_insn_and_split "*fist<mode>2_floor_1"
18321 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18322 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18323 UNSPEC_FIST_FLOOR))
18324 (clobber (reg:CC FLAGS_REG))]
18325 "TARGET_USE_FANCY_MATH_387
18326 && flag_unsafe_math_optimizations
18327 && !(reload_completed || reload_in_progress)"
18332 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18334 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18335 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18336 if (memory_operand (operands[0], VOIDmode))
18337 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18338 operands[2], operands[3]));
18341 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18342 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18343 operands[2], operands[3],
18348 [(set_attr "type" "fistp")
18349 (set_attr "i387_cw" "floor")
18350 (set_attr "mode" "<MODE>")])
18352 (define_insn "fistdi2_floor"
18353 [(set (match_operand:DI 0 "memory_operand" "=m")
18354 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18355 UNSPEC_FIST_FLOOR))
18356 (use (match_operand:HI 2 "memory_operand" "m"))
18357 (use (match_operand:HI 3 "memory_operand" "m"))
18358 (clobber (match_scratch:XF 4 "=&1f"))]
18359 "TARGET_USE_FANCY_MATH_387
18360 && flag_unsafe_math_optimizations"
18361 "* return output_fix_trunc (insn, operands, 0);"
18362 [(set_attr "type" "fistp")
18363 (set_attr "i387_cw" "floor")
18364 (set_attr "mode" "DI")])
18366 (define_insn "fistdi2_floor_with_temp"
18367 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18368 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18369 UNSPEC_FIST_FLOOR))
18370 (use (match_operand:HI 2 "memory_operand" "m,m"))
18371 (use (match_operand:HI 3 "memory_operand" "m,m"))
18372 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18373 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18374 "TARGET_USE_FANCY_MATH_387
18375 && flag_unsafe_math_optimizations"
18377 [(set_attr "type" "fistp")
18378 (set_attr "i387_cw" "floor")
18379 (set_attr "mode" "DI")])
18382 [(set (match_operand:DI 0 "register_operand" "")
18383 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18384 UNSPEC_FIST_FLOOR))
18385 (use (match_operand:HI 2 "memory_operand" ""))
18386 (use (match_operand:HI 3 "memory_operand" ""))
18387 (clobber (match_operand:DI 4 "memory_operand" ""))
18388 (clobber (match_scratch 5 ""))]
18390 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18391 (use (match_dup 2))
18392 (use (match_dup 3))
18393 (clobber (match_dup 5))])
18394 (set (match_dup 0) (match_dup 4))]
18398 [(set (match_operand:DI 0 "memory_operand" "")
18399 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18400 UNSPEC_FIST_FLOOR))
18401 (use (match_operand:HI 2 "memory_operand" ""))
18402 (use (match_operand:HI 3 "memory_operand" ""))
18403 (clobber (match_operand:DI 4 "memory_operand" ""))
18404 (clobber (match_scratch 5 ""))]
18406 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18407 (use (match_dup 2))
18408 (use (match_dup 3))
18409 (clobber (match_dup 5))])]
18412 (define_insn "fist<mode>2_floor"
18413 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18414 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18415 UNSPEC_FIST_FLOOR))
18416 (use (match_operand:HI 2 "memory_operand" "m"))
18417 (use (match_operand:HI 3 "memory_operand" "m"))]
18418 "TARGET_USE_FANCY_MATH_387
18419 && flag_unsafe_math_optimizations"
18420 "* return output_fix_trunc (insn, operands, 0);"
18421 [(set_attr "type" "fistp")
18422 (set_attr "i387_cw" "floor")
18423 (set_attr "mode" "<MODE>")])
18425 (define_insn "fist<mode>2_floor_with_temp"
18426 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18427 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18428 UNSPEC_FIST_FLOOR))
18429 (use (match_operand:HI 2 "memory_operand" "m,m"))
18430 (use (match_operand:HI 3 "memory_operand" "m,m"))
18431 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18432 "TARGET_USE_FANCY_MATH_387
18433 && flag_unsafe_math_optimizations"
18435 [(set_attr "type" "fistp")
18436 (set_attr "i387_cw" "floor")
18437 (set_attr "mode" "<MODE>")])
18440 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18441 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18442 UNSPEC_FIST_FLOOR))
18443 (use (match_operand:HI 2 "memory_operand" ""))
18444 (use (match_operand:HI 3 "memory_operand" ""))
18445 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18447 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18448 UNSPEC_FIST_FLOOR))
18449 (use (match_dup 2))
18450 (use (match_dup 3))])
18451 (set (match_dup 0) (match_dup 4))]
18455 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18456 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18457 UNSPEC_FIST_FLOOR))
18458 (use (match_operand:HI 2 "memory_operand" ""))
18459 (use (match_operand:HI 3 "memory_operand" ""))
18460 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18462 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18463 UNSPEC_FIST_FLOOR))
18464 (use (match_dup 2))
18465 (use (match_dup 3))])]
18468 (define_expand "lfloorxf<mode>2"
18469 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18470 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18471 UNSPEC_FIST_FLOOR))
18472 (clobber (reg:CC FLAGS_REG))])]
18473 "TARGET_USE_FANCY_MATH_387
18474 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18475 && flag_unsafe_math_optimizations"
18478 (define_expand "lfloor<mode>di2"
18479 [(match_operand:DI 0 "nonimmediate_operand" "")
18480 (match_operand:MODEF 1 "register_operand" "")]
18481 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18482 && !flag_trapping_math"
18484 if (optimize_insn_for_size_p ())
18486 ix86_expand_lfloorceil (operand0, operand1, true);
18490 (define_expand "lfloor<mode>si2"
18491 [(match_operand:SI 0 "nonimmediate_operand" "")
18492 (match_operand:MODEF 1 "register_operand" "")]
18493 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18494 && !flag_trapping_math"
18496 if (optimize_insn_for_size_p () && TARGET_64BIT)
18498 ix86_expand_lfloorceil (operand0, operand1, true);
18502 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18503 (define_insn_and_split "frndintxf2_ceil"
18504 [(set (match_operand:XF 0 "register_operand" "")
18505 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18506 UNSPEC_FRNDINT_CEIL))
18507 (clobber (reg:CC FLAGS_REG))]
18508 "TARGET_USE_FANCY_MATH_387
18509 && flag_unsafe_math_optimizations
18510 && !(reload_completed || reload_in_progress)"
18515 ix86_optimize_mode_switching[I387_CEIL] = 1;
18517 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18518 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18520 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18521 operands[2], operands[3]));
18524 [(set_attr "type" "frndint")
18525 (set_attr "i387_cw" "ceil")
18526 (set_attr "mode" "XF")])
18528 (define_insn "frndintxf2_ceil_i387"
18529 [(set (match_operand:XF 0 "register_operand" "=f")
18530 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18531 UNSPEC_FRNDINT_CEIL))
18532 (use (match_operand:HI 2 "memory_operand" "m"))
18533 (use (match_operand:HI 3 "memory_operand" "m"))]
18534 "TARGET_USE_FANCY_MATH_387
18535 && flag_unsafe_math_optimizations"
18536 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18537 [(set_attr "type" "frndint")
18538 (set_attr "i387_cw" "ceil")
18539 (set_attr "mode" "XF")])
18541 (define_expand "ceilxf2"
18542 [(use (match_operand:XF 0 "register_operand" ""))
18543 (use (match_operand:XF 1 "register_operand" ""))]
18544 "TARGET_USE_FANCY_MATH_387
18545 && flag_unsafe_math_optimizations"
18547 if (optimize_insn_for_size_p ())
18549 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18553 (define_expand "ceil<mode>2"
18554 [(use (match_operand:MODEF 0 "register_operand" ""))
18555 (use (match_operand:MODEF 1 "register_operand" ""))]
18556 "(TARGET_USE_FANCY_MATH_387
18557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18558 || TARGET_MIX_SSE_I387)
18559 && flag_unsafe_math_optimizations)
18560 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18561 && !flag_trapping_math)"
18563 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18564 && !flag_trapping_math
18565 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18568 emit_insn (gen_sse4_1_round<mode>2
18569 (operands[0], operands[1], GEN_INT (0x02)));
18570 else if (optimize_insn_for_size_p ())
18572 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18573 ix86_expand_floorceil (operand0, operand1, false);
18575 ix86_expand_floorceildf_32 (operand0, operand1, false);
18581 if (optimize_insn_for_size_p ())
18584 op0 = gen_reg_rtx (XFmode);
18585 op1 = gen_reg_rtx (XFmode);
18586 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18587 emit_insn (gen_frndintxf2_ceil (op0, op1));
18589 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18594 (define_insn_and_split "*fist<mode>2_ceil_1"
18595 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18596 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18598 (clobber (reg:CC FLAGS_REG))]
18599 "TARGET_USE_FANCY_MATH_387
18600 && flag_unsafe_math_optimizations
18601 && !(reload_completed || reload_in_progress)"
18606 ix86_optimize_mode_switching[I387_CEIL] = 1;
18608 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18609 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18610 if (memory_operand (operands[0], VOIDmode))
18611 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18612 operands[2], operands[3]));
18615 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18616 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18617 operands[2], operands[3],
18622 [(set_attr "type" "fistp")
18623 (set_attr "i387_cw" "ceil")
18624 (set_attr "mode" "<MODE>")])
18626 (define_insn "fistdi2_ceil"
18627 [(set (match_operand:DI 0 "memory_operand" "=m")
18628 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18630 (use (match_operand:HI 2 "memory_operand" "m"))
18631 (use (match_operand:HI 3 "memory_operand" "m"))
18632 (clobber (match_scratch:XF 4 "=&1f"))]
18633 "TARGET_USE_FANCY_MATH_387
18634 && flag_unsafe_math_optimizations"
18635 "* return output_fix_trunc (insn, operands, 0);"
18636 [(set_attr "type" "fistp")
18637 (set_attr "i387_cw" "ceil")
18638 (set_attr "mode" "DI")])
18640 (define_insn "fistdi2_ceil_with_temp"
18641 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18642 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18644 (use (match_operand:HI 2 "memory_operand" "m,m"))
18645 (use (match_operand:HI 3 "memory_operand" "m,m"))
18646 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18647 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18648 "TARGET_USE_FANCY_MATH_387
18649 && flag_unsafe_math_optimizations"
18651 [(set_attr "type" "fistp")
18652 (set_attr "i387_cw" "ceil")
18653 (set_attr "mode" "DI")])
18656 [(set (match_operand:DI 0 "register_operand" "")
18657 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18659 (use (match_operand:HI 2 "memory_operand" ""))
18660 (use (match_operand:HI 3 "memory_operand" ""))
18661 (clobber (match_operand:DI 4 "memory_operand" ""))
18662 (clobber (match_scratch 5 ""))]
18664 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18665 (use (match_dup 2))
18666 (use (match_dup 3))
18667 (clobber (match_dup 5))])
18668 (set (match_dup 0) (match_dup 4))]
18672 [(set (match_operand:DI 0 "memory_operand" "")
18673 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18675 (use (match_operand:HI 2 "memory_operand" ""))
18676 (use (match_operand:HI 3 "memory_operand" ""))
18677 (clobber (match_operand:DI 4 "memory_operand" ""))
18678 (clobber (match_scratch 5 ""))]
18680 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18681 (use (match_dup 2))
18682 (use (match_dup 3))
18683 (clobber (match_dup 5))])]
18686 (define_insn "fist<mode>2_ceil"
18687 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18688 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18690 (use (match_operand:HI 2 "memory_operand" "m"))
18691 (use (match_operand:HI 3 "memory_operand" "m"))]
18692 "TARGET_USE_FANCY_MATH_387
18693 && flag_unsafe_math_optimizations"
18694 "* return output_fix_trunc (insn, operands, 0);"
18695 [(set_attr "type" "fistp")
18696 (set_attr "i387_cw" "ceil")
18697 (set_attr "mode" "<MODE>")])
18699 (define_insn "fist<mode>2_ceil_with_temp"
18700 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18701 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18703 (use (match_operand:HI 2 "memory_operand" "m,m"))
18704 (use (match_operand:HI 3 "memory_operand" "m,m"))
18705 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18706 "TARGET_USE_FANCY_MATH_387
18707 && flag_unsafe_math_optimizations"
18709 [(set_attr "type" "fistp")
18710 (set_attr "i387_cw" "ceil")
18711 (set_attr "mode" "<MODE>")])
18714 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18715 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18717 (use (match_operand:HI 2 "memory_operand" ""))
18718 (use (match_operand:HI 3 "memory_operand" ""))
18719 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18721 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18723 (use (match_dup 2))
18724 (use (match_dup 3))])
18725 (set (match_dup 0) (match_dup 4))]
18729 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18730 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18732 (use (match_operand:HI 2 "memory_operand" ""))
18733 (use (match_operand:HI 3 "memory_operand" ""))
18734 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18736 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18738 (use (match_dup 2))
18739 (use (match_dup 3))])]
18742 (define_expand "lceilxf<mode>2"
18743 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18744 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18746 (clobber (reg:CC FLAGS_REG))])]
18747 "TARGET_USE_FANCY_MATH_387
18748 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18749 && flag_unsafe_math_optimizations"
18752 (define_expand "lceil<mode>di2"
18753 [(match_operand:DI 0 "nonimmediate_operand" "")
18754 (match_operand:MODEF 1 "register_operand" "")]
18755 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18756 && !flag_trapping_math"
18758 ix86_expand_lfloorceil (operand0, operand1, false);
18762 (define_expand "lceil<mode>si2"
18763 [(match_operand:SI 0 "nonimmediate_operand" "")
18764 (match_operand:MODEF 1 "register_operand" "")]
18765 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18766 && !flag_trapping_math"
18768 ix86_expand_lfloorceil (operand0, operand1, false);
18772 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18773 (define_insn_and_split "frndintxf2_trunc"
18774 [(set (match_operand:XF 0 "register_operand" "")
18775 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18776 UNSPEC_FRNDINT_TRUNC))
18777 (clobber (reg:CC FLAGS_REG))]
18778 "TARGET_USE_FANCY_MATH_387
18779 && flag_unsafe_math_optimizations
18780 && !(reload_completed || reload_in_progress)"
18785 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18787 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18788 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18790 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18791 operands[2], operands[3]));
18794 [(set_attr "type" "frndint")
18795 (set_attr "i387_cw" "trunc")
18796 (set_attr "mode" "XF")])
18798 (define_insn "frndintxf2_trunc_i387"
18799 [(set (match_operand:XF 0 "register_operand" "=f")
18800 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18801 UNSPEC_FRNDINT_TRUNC))
18802 (use (match_operand:HI 2 "memory_operand" "m"))
18803 (use (match_operand:HI 3 "memory_operand" "m"))]
18804 "TARGET_USE_FANCY_MATH_387
18805 && flag_unsafe_math_optimizations"
18806 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18807 [(set_attr "type" "frndint")
18808 (set_attr "i387_cw" "trunc")
18809 (set_attr "mode" "XF")])
18811 (define_expand "btruncxf2"
18812 [(use (match_operand:XF 0 "register_operand" ""))
18813 (use (match_operand:XF 1 "register_operand" ""))]
18814 "TARGET_USE_FANCY_MATH_387
18815 && flag_unsafe_math_optimizations"
18817 if (optimize_insn_for_size_p ())
18819 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18823 (define_expand "btrunc<mode>2"
18824 [(use (match_operand:MODEF 0 "register_operand" ""))
18825 (use (match_operand:MODEF 1 "register_operand" ""))]
18826 "(TARGET_USE_FANCY_MATH_387
18827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18828 || TARGET_MIX_SSE_I387)
18829 && flag_unsafe_math_optimizations)
18830 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18831 && !flag_trapping_math)"
18833 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18834 && !flag_trapping_math
18835 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18838 emit_insn (gen_sse4_1_round<mode>2
18839 (operands[0], operands[1], GEN_INT (0x03)));
18840 else if (optimize_insn_for_size_p ())
18842 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18843 ix86_expand_trunc (operand0, operand1);
18845 ix86_expand_truncdf_32 (operand0, operand1);
18851 if (optimize_insn_for_size_p ())
18854 op0 = gen_reg_rtx (XFmode);
18855 op1 = gen_reg_rtx (XFmode);
18856 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18857 emit_insn (gen_frndintxf2_trunc (op0, op1));
18859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18864 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18865 (define_insn_and_split "frndintxf2_mask_pm"
18866 [(set (match_operand:XF 0 "register_operand" "")
18867 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18868 UNSPEC_FRNDINT_MASK_PM))
18869 (clobber (reg:CC FLAGS_REG))]
18870 "TARGET_USE_FANCY_MATH_387
18871 && flag_unsafe_math_optimizations
18872 && !(reload_completed || reload_in_progress)"
18877 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18879 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18880 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18882 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18883 operands[2], operands[3]));
18886 [(set_attr "type" "frndint")
18887 (set_attr "i387_cw" "mask_pm")
18888 (set_attr "mode" "XF")])
18890 (define_insn "frndintxf2_mask_pm_i387"
18891 [(set (match_operand:XF 0 "register_operand" "=f")
18892 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18893 UNSPEC_FRNDINT_MASK_PM))
18894 (use (match_operand:HI 2 "memory_operand" "m"))
18895 (use (match_operand:HI 3 "memory_operand" "m"))]
18896 "TARGET_USE_FANCY_MATH_387
18897 && flag_unsafe_math_optimizations"
18898 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18899 [(set_attr "type" "frndint")
18900 (set_attr "i387_cw" "mask_pm")
18901 (set_attr "mode" "XF")])
18903 (define_expand "nearbyintxf2"
18904 [(use (match_operand:XF 0 "register_operand" ""))
18905 (use (match_operand:XF 1 "register_operand" ""))]
18906 "TARGET_USE_FANCY_MATH_387
18907 && flag_unsafe_math_optimizations"
18909 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18914 (define_expand "nearbyint<mode>2"
18915 [(use (match_operand:MODEF 0 "register_operand" ""))
18916 (use (match_operand:MODEF 1 "register_operand" ""))]
18917 "TARGET_USE_FANCY_MATH_387
18918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18919 || TARGET_MIX_SSE_I387)
18920 && flag_unsafe_math_optimizations"
18922 rtx op0 = gen_reg_rtx (XFmode);
18923 rtx op1 = gen_reg_rtx (XFmode);
18925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18926 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18932 (define_insn "fxam<mode>2_i387"
18933 [(set (match_operand:HI 0 "register_operand" "=a")
18935 [(match_operand:X87MODEF 1 "register_operand" "f")]
18937 "TARGET_USE_FANCY_MATH_387"
18938 "fxam\n\tfnstsw\t%0"
18939 [(set_attr "type" "multi")
18940 (set_attr "unit" "i387")
18941 (set_attr "mode" "<MODE>")])
18943 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18944 [(set (match_operand:HI 0 "register_operand" "")
18946 [(match_operand:MODEF 1 "memory_operand" "")]
18948 "TARGET_USE_FANCY_MATH_387
18949 && !(reload_completed || reload_in_progress)"
18952 [(set (match_dup 2)(match_dup 1))
18954 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18956 operands[2] = gen_reg_rtx (<MODE>mode);
18958 MEM_VOLATILE_P (operands[1]) = 1;
18960 [(set_attr "type" "multi")
18961 (set_attr "unit" "i387")
18962 (set_attr "mode" "<MODE>")])
18964 (define_expand "isinfxf2"
18965 [(use (match_operand:SI 0 "register_operand" ""))
18966 (use (match_operand:XF 1 "register_operand" ""))]
18967 "TARGET_USE_FANCY_MATH_387
18968 && TARGET_C99_FUNCTIONS"
18970 rtx mask = GEN_INT (0x45);
18971 rtx val = GEN_INT (0x05);
18975 rtx scratch = gen_reg_rtx (HImode);
18976 rtx res = gen_reg_rtx (QImode);
18978 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18980 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18981 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18982 cond = gen_rtx_fmt_ee (EQ, QImode,
18983 gen_rtx_REG (CCmode, FLAGS_REG),
18985 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18986 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18990 (define_expand "isinf<mode>2"
18991 [(use (match_operand:SI 0 "register_operand" ""))
18992 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18993 "TARGET_USE_FANCY_MATH_387
18994 && TARGET_C99_FUNCTIONS
18995 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18997 rtx mask = GEN_INT (0x45);
18998 rtx val = GEN_INT (0x05);
19002 rtx scratch = gen_reg_rtx (HImode);
19003 rtx res = gen_reg_rtx (QImode);
19005 /* Remove excess precision by forcing value through memory. */
19006 if (memory_operand (operands[1], VOIDmode))
19007 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19010 enum ix86_stack_slot slot = (virtuals_instantiated
19013 rtx temp = assign_386_stack_local (<MODE>mode, slot);
19015 emit_move_insn (temp, operands[1]);
19016 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19019 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19020 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19021 cond = gen_rtx_fmt_ee (EQ, QImode,
19022 gen_rtx_REG (CCmode, FLAGS_REG),
19024 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19025 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19029 (define_expand "signbit<mode>2"
19030 [(use (match_operand:SI 0 "register_operand" ""))
19031 (use (match_operand:X87MODEF 1 "register_operand" ""))]
19032 "TARGET_USE_FANCY_MATH_387
19033 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19035 rtx mask = GEN_INT (0x0200);
19037 rtx scratch = gen_reg_rtx (HImode);
19039 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19040 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19044 ;; Block operation instructions
19047 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19050 [(set_attr "length" "1")
19051 (set_attr "length_immediate" "0")
19052 (set_attr "modrm" "0")])
19054 (define_expand "movmemsi"
19055 [(use (match_operand:BLK 0 "memory_operand" ""))
19056 (use (match_operand:BLK 1 "memory_operand" ""))
19057 (use (match_operand:SI 2 "nonmemory_operand" ""))
19058 (use (match_operand:SI 3 "const_int_operand" ""))
19059 (use (match_operand:SI 4 "const_int_operand" ""))
19060 (use (match_operand:SI 5 "const_int_operand" ""))]
19063 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19064 operands[4], operands[5]))
19070 (define_expand "movmemdi"
19071 [(use (match_operand:BLK 0 "memory_operand" ""))
19072 (use (match_operand:BLK 1 "memory_operand" ""))
19073 (use (match_operand:DI 2 "nonmemory_operand" ""))
19074 (use (match_operand:DI 3 "const_int_operand" ""))
19075 (use (match_operand:SI 4 "const_int_operand" ""))
19076 (use (match_operand:SI 5 "const_int_operand" ""))]
19079 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19080 operands[4], operands[5]))
19086 ;; Most CPUs don't like single string operations
19087 ;; Handle this case here to simplify previous expander.
19089 (define_expand "strmov"
19090 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19091 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19092 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19093 (clobber (reg:CC FLAGS_REG))])
19094 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19095 (clobber (reg:CC FLAGS_REG))])]
19098 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19100 /* If .md ever supports :P for Pmode, these can be directly
19101 in the pattern above. */
19102 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19103 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19105 /* Can't use this if the user has appropriated esi or edi. */
19106 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19107 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19109 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19110 operands[2], operands[3],
19111 operands[5], operands[6]));
19115 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19118 (define_expand "strmov_singleop"
19119 [(parallel [(set (match_operand 1 "memory_operand" "")
19120 (match_operand 3 "memory_operand" ""))
19121 (set (match_operand 0 "register_operand" "")
19122 (match_operand 4 "" ""))
19123 (set (match_operand 2 "register_operand" "")
19124 (match_operand 5 "" ""))])]
19126 "ix86_current_function_needs_cld = 1;")
19128 (define_insn "*strmovdi_rex_1"
19129 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19130 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19131 (set (match_operand:DI 0 "register_operand" "=D")
19132 (plus:DI (match_dup 2)
19134 (set (match_operand:DI 1 "register_operand" "=S")
19135 (plus:DI (match_dup 3)
19139 [(set_attr "type" "str")
19140 (set_attr "mode" "DI")
19141 (set_attr "memory" "both")])
19143 (define_insn "*strmovsi_1"
19144 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19145 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19146 (set (match_operand:SI 0 "register_operand" "=D")
19147 (plus:SI (match_dup 2)
19149 (set (match_operand:SI 1 "register_operand" "=S")
19150 (plus:SI (match_dup 3)
19154 [(set_attr "type" "str")
19155 (set_attr "mode" "SI")
19156 (set_attr "memory" "both")])
19158 (define_insn "*strmovsi_rex_1"
19159 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19160 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19161 (set (match_operand:DI 0 "register_operand" "=D")
19162 (plus:DI (match_dup 2)
19164 (set (match_operand:DI 1 "register_operand" "=S")
19165 (plus:DI (match_dup 3)
19169 [(set_attr "type" "str")
19170 (set_attr "mode" "SI")
19171 (set_attr "memory" "both")])
19173 (define_insn "*strmovhi_1"
19174 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19175 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19176 (set (match_operand:SI 0 "register_operand" "=D")
19177 (plus:SI (match_dup 2)
19179 (set (match_operand:SI 1 "register_operand" "=S")
19180 (plus:SI (match_dup 3)
19184 [(set_attr "type" "str")
19185 (set_attr "memory" "both")
19186 (set_attr "mode" "HI")])
19188 (define_insn "*strmovhi_rex_1"
19189 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19190 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19191 (set (match_operand:DI 0 "register_operand" "=D")
19192 (plus:DI (match_dup 2)
19194 (set (match_operand:DI 1 "register_operand" "=S")
19195 (plus:DI (match_dup 3)
19199 [(set_attr "type" "str")
19200 (set_attr "memory" "both")
19201 (set_attr "mode" "HI")])
19203 (define_insn "*strmovqi_1"
19204 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19205 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19206 (set (match_operand:SI 0 "register_operand" "=D")
19207 (plus:SI (match_dup 2)
19209 (set (match_operand:SI 1 "register_operand" "=S")
19210 (plus:SI (match_dup 3)
19214 [(set_attr "type" "str")
19215 (set_attr "memory" "both")
19216 (set_attr "mode" "QI")])
19218 (define_insn "*strmovqi_rex_1"
19219 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19220 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19221 (set (match_operand:DI 0 "register_operand" "=D")
19222 (plus:DI (match_dup 2)
19224 (set (match_operand:DI 1 "register_operand" "=S")
19225 (plus:DI (match_dup 3)
19229 [(set_attr "type" "str")
19230 (set_attr "memory" "both")
19231 (set_attr "mode" "QI")])
19233 (define_expand "rep_mov"
19234 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19235 (set (match_operand 0 "register_operand" "")
19236 (match_operand 5 "" ""))
19237 (set (match_operand 2 "register_operand" "")
19238 (match_operand 6 "" ""))
19239 (set (match_operand 1 "memory_operand" "")
19240 (match_operand 3 "memory_operand" ""))
19241 (use (match_dup 4))])]
19243 "ix86_current_function_needs_cld = 1;")
19245 (define_insn "*rep_movdi_rex64"
19246 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19247 (set (match_operand:DI 0 "register_operand" "=D")
19248 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19250 (match_operand:DI 3 "register_operand" "0")))
19251 (set (match_operand:DI 1 "register_operand" "=S")
19252 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19253 (match_operand:DI 4 "register_operand" "1")))
19254 (set (mem:BLK (match_dup 3))
19255 (mem:BLK (match_dup 4)))
19256 (use (match_dup 5))]
19259 [(set_attr "type" "str")
19260 (set_attr "prefix_rep" "1")
19261 (set_attr "memory" "both")
19262 (set_attr "mode" "DI")])
19264 (define_insn "*rep_movsi"
19265 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19266 (set (match_operand:SI 0 "register_operand" "=D")
19267 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19269 (match_operand:SI 3 "register_operand" "0")))
19270 (set (match_operand:SI 1 "register_operand" "=S")
19271 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19272 (match_operand:SI 4 "register_operand" "1")))
19273 (set (mem:BLK (match_dup 3))
19274 (mem:BLK (match_dup 4)))
19275 (use (match_dup 5))]
19278 [(set_attr "type" "str")
19279 (set_attr "prefix_rep" "1")
19280 (set_attr "memory" "both")
19281 (set_attr "mode" "SI")])
19283 (define_insn "*rep_movsi_rex64"
19284 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19285 (set (match_operand:DI 0 "register_operand" "=D")
19286 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19288 (match_operand:DI 3 "register_operand" "0")))
19289 (set (match_operand:DI 1 "register_operand" "=S")
19290 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19291 (match_operand:DI 4 "register_operand" "1")))
19292 (set (mem:BLK (match_dup 3))
19293 (mem:BLK (match_dup 4)))
19294 (use (match_dup 5))]
19297 [(set_attr "type" "str")
19298 (set_attr "prefix_rep" "1")
19299 (set_attr "memory" "both")
19300 (set_attr "mode" "SI")])
19302 (define_insn "*rep_movqi"
19303 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19304 (set (match_operand:SI 0 "register_operand" "=D")
19305 (plus:SI (match_operand:SI 3 "register_operand" "0")
19306 (match_operand:SI 5 "register_operand" "2")))
19307 (set (match_operand:SI 1 "register_operand" "=S")
19308 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19309 (set (mem:BLK (match_dup 3))
19310 (mem:BLK (match_dup 4)))
19311 (use (match_dup 5))]
19314 [(set_attr "type" "str")
19315 (set_attr "prefix_rep" "1")
19316 (set_attr "memory" "both")
19317 (set_attr "mode" "SI")])
19319 (define_insn "*rep_movqi_rex64"
19320 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19321 (set (match_operand:DI 0 "register_operand" "=D")
19322 (plus:DI (match_operand:DI 3 "register_operand" "0")
19323 (match_operand:DI 5 "register_operand" "2")))
19324 (set (match_operand:DI 1 "register_operand" "=S")
19325 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19326 (set (mem:BLK (match_dup 3))
19327 (mem:BLK (match_dup 4)))
19328 (use (match_dup 5))]
19331 [(set_attr "type" "str")
19332 (set_attr "prefix_rep" "1")
19333 (set_attr "memory" "both")
19334 (set_attr "mode" "SI")])
19336 (define_expand "setmemsi"
19337 [(use (match_operand:BLK 0 "memory_operand" ""))
19338 (use (match_operand:SI 1 "nonmemory_operand" ""))
19339 (use (match_operand 2 "const_int_operand" ""))
19340 (use (match_operand 3 "const_int_operand" ""))
19341 (use (match_operand:SI 4 "const_int_operand" ""))
19342 (use (match_operand:SI 5 "const_int_operand" ""))]
19345 if (ix86_expand_setmem (operands[0], operands[1],
19346 operands[2], operands[3],
19347 operands[4], operands[5]))
19353 (define_expand "setmemdi"
19354 [(use (match_operand:BLK 0 "memory_operand" ""))
19355 (use (match_operand:DI 1 "nonmemory_operand" ""))
19356 (use (match_operand 2 "const_int_operand" ""))
19357 (use (match_operand 3 "const_int_operand" ""))
19358 (use (match_operand 4 "const_int_operand" ""))
19359 (use (match_operand 5 "const_int_operand" ""))]
19362 if (ix86_expand_setmem (operands[0], operands[1],
19363 operands[2], operands[3],
19364 operands[4], operands[5]))
19370 ;; Most CPUs don't like single string operations
19371 ;; Handle this case here to simplify previous expander.
19373 (define_expand "strset"
19374 [(set (match_operand 1 "memory_operand" "")
19375 (match_operand 2 "register_operand" ""))
19376 (parallel [(set (match_operand 0 "register_operand" "")
19378 (clobber (reg:CC FLAGS_REG))])]
19381 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19382 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19384 /* If .md ever supports :P for Pmode, this can be directly
19385 in the pattern above. */
19386 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19387 GEN_INT (GET_MODE_SIZE (GET_MODE
19389 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19391 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19397 (define_expand "strset_singleop"
19398 [(parallel [(set (match_operand 1 "memory_operand" "")
19399 (match_operand 2 "register_operand" ""))
19400 (set (match_operand 0 "register_operand" "")
19401 (match_operand 3 "" ""))])]
19403 "ix86_current_function_needs_cld = 1;")
19405 (define_insn "*strsetdi_rex_1"
19406 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19407 (match_operand:DI 2 "register_operand" "a"))
19408 (set (match_operand:DI 0 "register_operand" "=D")
19409 (plus:DI (match_dup 1)
19413 [(set_attr "type" "str")
19414 (set_attr "memory" "store")
19415 (set_attr "mode" "DI")])
19417 (define_insn "*strsetsi_1"
19418 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19419 (match_operand:SI 2 "register_operand" "a"))
19420 (set (match_operand:SI 0 "register_operand" "=D")
19421 (plus:SI (match_dup 1)
19425 [(set_attr "type" "str")
19426 (set_attr "memory" "store")
19427 (set_attr "mode" "SI")])
19429 (define_insn "*strsetsi_rex_1"
19430 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19431 (match_operand:SI 2 "register_operand" "a"))
19432 (set (match_operand:DI 0 "register_operand" "=D")
19433 (plus:DI (match_dup 1)
19437 [(set_attr "type" "str")
19438 (set_attr "memory" "store")
19439 (set_attr "mode" "SI")])
19441 (define_insn "*strsethi_1"
19442 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19443 (match_operand:HI 2 "register_operand" "a"))
19444 (set (match_operand:SI 0 "register_operand" "=D")
19445 (plus:SI (match_dup 1)
19449 [(set_attr "type" "str")
19450 (set_attr "memory" "store")
19451 (set_attr "mode" "HI")])
19453 (define_insn "*strsethi_rex_1"
19454 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19455 (match_operand:HI 2 "register_operand" "a"))
19456 (set (match_operand:DI 0 "register_operand" "=D")
19457 (plus:DI (match_dup 1)
19461 [(set_attr "type" "str")
19462 (set_attr "memory" "store")
19463 (set_attr "mode" "HI")])
19465 (define_insn "*strsetqi_1"
19466 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19467 (match_operand:QI 2 "register_operand" "a"))
19468 (set (match_operand:SI 0 "register_operand" "=D")
19469 (plus:SI (match_dup 1)
19473 [(set_attr "type" "str")
19474 (set_attr "memory" "store")
19475 (set_attr "mode" "QI")])
19477 (define_insn "*strsetqi_rex_1"
19478 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19479 (match_operand:QI 2 "register_operand" "a"))
19480 (set (match_operand:DI 0 "register_operand" "=D")
19481 (plus:DI (match_dup 1)
19485 [(set_attr "type" "str")
19486 (set_attr "memory" "store")
19487 (set_attr "mode" "QI")])
19489 (define_expand "rep_stos"
19490 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19491 (set (match_operand 0 "register_operand" "")
19492 (match_operand 4 "" ""))
19493 (set (match_operand 2 "memory_operand" "") (const_int 0))
19494 (use (match_operand 3 "register_operand" ""))
19495 (use (match_dup 1))])]
19497 "ix86_current_function_needs_cld = 1;")
19499 (define_insn "*rep_stosdi_rex64"
19500 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19501 (set (match_operand:DI 0 "register_operand" "=D")
19502 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19504 (match_operand:DI 3 "register_operand" "0")))
19505 (set (mem:BLK (match_dup 3))
19507 (use (match_operand:DI 2 "register_operand" "a"))
19508 (use (match_dup 4))]
19511 [(set_attr "type" "str")
19512 (set_attr "prefix_rep" "1")
19513 (set_attr "memory" "store")
19514 (set_attr "mode" "DI")])
19516 (define_insn "*rep_stossi"
19517 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19518 (set (match_operand:SI 0 "register_operand" "=D")
19519 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19521 (match_operand:SI 3 "register_operand" "0")))
19522 (set (mem:BLK (match_dup 3))
19524 (use (match_operand:SI 2 "register_operand" "a"))
19525 (use (match_dup 4))]
19528 [(set_attr "type" "str")
19529 (set_attr "prefix_rep" "1")
19530 (set_attr "memory" "store")
19531 (set_attr "mode" "SI")])
19533 (define_insn "*rep_stossi_rex64"
19534 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19535 (set (match_operand:DI 0 "register_operand" "=D")
19536 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19538 (match_operand:DI 3 "register_operand" "0")))
19539 (set (mem:BLK (match_dup 3))
19541 (use (match_operand:SI 2 "register_operand" "a"))
19542 (use (match_dup 4))]
19545 [(set_attr "type" "str")
19546 (set_attr "prefix_rep" "1")
19547 (set_attr "memory" "store")
19548 (set_attr "mode" "SI")])
19550 (define_insn "*rep_stosqi"
19551 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19552 (set (match_operand:SI 0 "register_operand" "=D")
19553 (plus:SI (match_operand:SI 3 "register_operand" "0")
19554 (match_operand:SI 4 "register_operand" "1")))
19555 (set (mem:BLK (match_dup 3))
19557 (use (match_operand:QI 2 "register_operand" "a"))
19558 (use (match_dup 4))]
19561 [(set_attr "type" "str")
19562 (set_attr "prefix_rep" "1")
19563 (set_attr "memory" "store")
19564 (set_attr "mode" "QI")])
19566 (define_insn "*rep_stosqi_rex64"
19567 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19568 (set (match_operand:DI 0 "register_operand" "=D")
19569 (plus:DI (match_operand:DI 3 "register_operand" "0")
19570 (match_operand:DI 4 "register_operand" "1")))
19571 (set (mem:BLK (match_dup 3))
19573 (use (match_operand:QI 2 "register_operand" "a"))
19574 (use (match_dup 4))]
19577 [(set_attr "type" "str")
19578 (set_attr "prefix_rep" "1")
19579 (set_attr "memory" "store")
19580 (set_attr "mode" "QI")])
19582 (define_expand "cmpstrnsi"
19583 [(set (match_operand:SI 0 "register_operand" "")
19584 (compare:SI (match_operand:BLK 1 "general_operand" "")
19585 (match_operand:BLK 2 "general_operand" "")))
19586 (use (match_operand 3 "general_operand" ""))
19587 (use (match_operand 4 "immediate_operand" ""))]
19590 rtx addr1, addr2, out, outlow, count, countreg, align;
19592 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19595 /* Can't use this if the user has appropriated esi or edi. */
19596 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19601 out = gen_reg_rtx (SImode);
19603 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19604 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19605 if (addr1 != XEXP (operands[1], 0))
19606 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19607 if (addr2 != XEXP (operands[2], 0))
19608 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19610 count = operands[3];
19611 countreg = ix86_zero_extend_to_Pmode (count);
19613 /* %%% Iff we are testing strict equality, we can use known alignment
19614 to good advantage. This may be possible with combine, particularly
19615 once cc0 is dead. */
19616 align = operands[4];
19618 if (CONST_INT_P (count))
19620 if (INTVAL (count) == 0)
19622 emit_move_insn (operands[0], const0_rtx);
19625 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19626 operands[1], operands[2]));
19631 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19633 emit_insn (gen_cmpsi_1 (countreg, countreg));
19634 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19635 operands[1], operands[2]));
19638 outlow = gen_lowpart (QImode, out);
19639 emit_insn (gen_cmpintqi (outlow));
19640 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19642 if (operands[0] != out)
19643 emit_move_insn (operands[0], out);
19648 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19650 (define_expand "cmpintqi"
19651 [(set (match_dup 1)
19652 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19654 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19655 (parallel [(set (match_operand:QI 0 "register_operand" "")
19656 (minus:QI (match_dup 1)
19658 (clobber (reg:CC FLAGS_REG))])]
19660 "operands[1] = gen_reg_rtx (QImode);
19661 operands[2] = gen_reg_rtx (QImode);")
19663 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19664 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19666 (define_expand "cmpstrnqi_nz_1"
19667 [(parallel [(set (reg:CC FLAGS_REG)
19668 (compare:CC (match_operand 4 "memory_operand" "")
19669 (match_operand 5 "memory_operand" "")))
19670 (use (match_operand 2 "register_operand" ""))
19671 (use (match_operand:SI 3 "immediate_operand" ""))
19672 (clobber (match_operand 0 "register_operand" ""))
19673 (clobber (match_operand 1 "register_operand" ""))
19674 (clobber (match_dup 2))])]
19676 "ix86_current_function_needs_cld = 1;")
19678 (define_insn "*cmpstrnqi_nz_1"
19679 [(set (reg:CC FLAGS_REG)
19680 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19681 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19682 (use (match_operand:SI 6 "register_operand" "2"))
19683 (use (match_operand:SI 3 "immediate_operand" "i"))
19684 (clobber (match_operand:SI 0 "register_operand" "=S"))
19685 (clobber (match_operand:SI 1 "register_operand" "=D"))
19686 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19689 [(set_attr "type" "str")
19690 (set_attr "mode" "QI")
19691 (set_attr "prefix_rep" "1")])
19693 (define_insn "*cmpstrnqi_nz_rex_1"
19694 [(set (reg:CC FLAGS_REG)
19695 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19696 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19697 (use (match_operand:DI 6 "register_operand" "2"))
19698 (use (match_operand:SI 3 "immediate_operand" "i"))
19699 (clobber (match_operand:DI 0 "register_operand" "=S"))
19700 (clobber (match_operand:DI 1 "register_operand" "=D"))
19701 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19704 [(set_attr "type" "str")
19705 (set_attr "mode" "QI")
19706 (set_attr "prefix_rep" "1")])
19708 ;; The same, but the count is not known to not be zero.
19710 (define_expand "cmpstrnqi_1"
19711 [(parallel [(set (reg:CC FLAGS_REG)
19712 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19714 (compare:CC (match_operand 4 "memory_operand" "")
19715 (match_operand 5 "memory_operand" ""))
19717 (use (match_operand:SI 3 "immediate_operand" ""))
19718 (use (reg:CC FLAGS_REG))
19719 (clobber (match_operand 0 "register_operand" ""))
19720 (clobber (match_operand 1 "register_operand" ""))
19721 (clobber (match_dup 2))])]
19723 "ix86_current_function_needs_cld = 1;")
19725 (define_insn "*cmpstrnqi_1"
19726 [(set (reg:CC FLAGS_REG)
19727 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19729 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19730 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19732 (use (match_operand:SI 3 "immediate_operand" "i"))
19733 (use (reg:CC FLAGS_REG))
19734 (clobber (match_operand:SI 0 "register_operand" "=S"))
19735 (clobber (match_operand:SI 1 "register_operand" "=D"))
19736 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19739 [(set_attr "type" "str")
19740 (set_attr "mode" "QI")
19741 (set_attr "prefix_rep" "1")])
19743 (define_insn "*cmpstrnqi_rex_1"
19744 [(set (reg:CC FLAGS_REG)
19745 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19747 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19748 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19750 (use (match_operand:SI 3 "immediate_operand" "i"))
19751 (use (reg:CC FLAGS_REG))
19752 (clobber (match_operand:DI 0 "register_operand" "=S"))
19753 (clobber (match_operand:DI 1 "register_operand" "=D"))
19754 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19757 [(set_attr "type" "str")
19758 (set_attr "mode" "QI")
19759 (set_attr "prefix_rep" "1")])
19761 (define_expand "strlensi"
19762 [(set (match_operand:SI 0 "register_operand" "")
19763 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19764 (match_operand:QI 2 "immediate_operand" "")
19765 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19768 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19774 (define_expand "strlendi"
19775 [(set (match_operand:DI 0 "register_operand" "")
19776 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19777 (match_operand:QI 2 "immediate_operand" "")
19778 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19781 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19787 (define_expand "strlenqi_1"
19788 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19789 (clobber (match_operand 1 "register_operand" ""))
19790 (clobber (reg:CC FLAGS_REG))])]
19792 "ix86_current_function_needs_cld = 1;")
19794 (define_insn "*strlenqi_1"
19795 [(set (match_operand:SI 0 "register_operand" "=&c")
19796 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19797 (match_operand:QI 2 "register_operand" "a")
19798 (match_operand:SI 3 "immediate_operand" "i")
19799 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19800 (clobber (match_operand:SI 1 "register_operand" "=D"))
19801 (clobber (reg:CC FLAGS_REG))]
19804 [(set_attr "type" "str")
19805 (set_attr "mode" "QI")
19806 (set_attr "prefix_rep" "1")])
19808 (define_insn "*strlenqi_rex_1"
19809 [(set (match_operand:DI 0 "register_operand" "=&c")
19810 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19811 (match_operand:QI 2 "register_operand" "a")
19812 (match_operand:DI 3 "immediate_operand" "i")
19813 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19814 (clobber (match_operand:DI 1 "register_operand" "=D"))
19815 (clobber (reg:CC FLAGS_REG))]
19818 [(set_attr "type" "str")
19819 (set_attr "mode" "QI")
19820 (set_attr "prefix_rep" "1")])
19822 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19823 ;; handled in combine, but it is not currently up to the task.
19824 ;; When used for their truth value, the cmpstrn* expanders generate
19833 ;; The intermediate three instructions are unnecessary.
19835 ;; This one handles cmpstrn*_nz_1...
19838 (set (reg:CC FLAGS_REG)
19839 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19840 (mem:BLK (match_operand 5 "register_operand" ""))))
19841 (use (match_operand 6 "register_operand" ""))
19842 (use (match_operand:SI 3 "immediate_operand" ""))
19843 (clobber (match_operand 0 "register_operand" ""))
19844 (clobber (match_operand 1 "register_operand" ""))
19845 (clobber (match_operand 2 "register_operand" ""))])
19846 (set (match_operand:QI 7 "register_operand" "")
19847 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19848 (set (match_operand:QI 8 "register_operand" "")
19849 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19850 (set (reg FLAGS_REG)
19851 (compare (match_dup 7) (match_dup 8)))
19853 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19855 (set (reg:CC FLAGS_REG)
19856 (compare:CC (mem:BLK (match_dup 4))
19857 (mem:BLK (match_dup 5))))
19858 (use (match_dup 6))
19859 (use (match_dup 3))
19860 (clobber (match_dup 0))
19861 (clobber (match_dup 1))
19862 (clobber (match_dup 2))])]
19865 ;; ...and this one handles cmpstrn*_1.
19868 (set (reg:CC FLAGS_REG)
19869 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19871 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19872 (mem:BLK (match_operand 5 "register_operand" "")))
19874 (use (match_operand:SI 3 "immediate_operand" ""))
19875 (use (reg:CC FLAGS_REG))
19876 (clobber (match_operand 0 "register_operand" ""))
19877 (clobber (match_operand 1 "register_operand" ""))
19878 (clobber (match_operand 2 "register_operand" ""))])
19879 (set (match_operand:QI 7 "register_operand" "")
19880 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19881 (set (match_operand:QI 8 "register_operand" "")
19882 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19883 (set (reg FLAGS_REG)
19884 (compare (match_dup 7) (match_dup 8)))
19886 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19888 (set (reg:CC FLAGS_REG)
19889 (if_then_else:CC (ne (match_dup 6)
19891 (compare:CC (mem:BLK (match_dup 4))
19892 (mem:BLK (match_dup 5)))
19894 (use (match_dup 3))
19895 (use (reg:CC FLAGS_REG))
19896 (clobber (match_dup 0))
19897 (clobber (match_dup 1))
19898 (clobber (match_dup 2))])]
19903 ;; Conditional move instructions.
19905 (define_expand "movdicc"
19906 [(set (match_operand:DI 0 "register_operand" "")
19907 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19908 (match_operand:DI 2 "general_operand" "")
19909 (match_operand:DI 3 "general_operand" "")))]
19911 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19913 (define_insn "x86_movdicc_0_m1_rex64"
19914 [(set (match_operand:DI 0 "register_operand" "=r")
19915 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19918 (clobber (reg:CC FLAGS_REG))]
19921 ; Since we don't have the proper number of operands for an alu insn,
19922 ; fill in all the blanks.
19923 [(set_attr "type" "alu")
19924 (set_attr "use_carry" "1")
19925 (set_attr "pent_pair" "pu")
19926 (set_attr "memory" "none")
19927 (set_attr "imm_disp" "false")
19928 (set_attr "mode" "DI")
19929 (set_attr "length_immediate" "0")])
19931 (define_insn "*x86_movdicc_0_m1_se"
19932 [(set (match_operand:DI 0 "register_operand" "=r")
19933 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19936 (clobber (reg:CC FLAGS_REG))]
19939 [(set_attr "type" "alu")
19940 (set_attr "use_carry" "1")
19941 (set_attr "pent_pair" "pu")
19942 (set_attr "memory" "none")
19943 (set_attr "imm_disp" "false")
19944 (set_attr "mode" "DI")
19945 (set_attr "length_immediate" "0")])
19947 (define_insn "*movdicc_c_rex64"
19948 [(set (match_operand:DI 0 "register_operand" "=r,r")
19949 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19950 [(reg FLAGS_REG) (const_int 0)])
19951 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19952 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19953 "TARGET_64BIT && TARGET_CMOVE
19954 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19956 cmov%O2%C1\t{%2, %0|%0, %2}
19957 cmov%O2%c1\t{%3, %0|%0, %3}"
19958 [(set_attr "type" "icmov")
19959 (set_attr "mode" "DI")])
19961 (define_expand "movsicc"
19962 [(set (match_operand:SI 0 "register_operand" "")
19963 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19964 (match_operand:SI 2 "general_operand" "")
19965 (match_operand:SI 3 "general_operand" "")))]
19967 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19969 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19970 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19971 ;; So just document what we're doing explicitly.
19973 (define_insn "x86_movsicc_0_m1"
19974 [(set (match_operand:SI 0 "register_operand" "=r")
19975 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19978 (clobber (reg:CC FLAGS_REG))]
19981 ; Since we don't have the proper number of operands for an alu insn,
19982 ; fill in all the blanks.
19983 [(set_attr "type" "alu")
19984 (set_attr "use_carry" "1")
19985 (set_attr "pent_pair" "pu")
19986 (set_attr "memory" "none")
19987 (set_attr "imm_disp" "false")
19988 (set_attr "mode" "SI")
19989 (set_attr "length_immediate" "0")])
19991 (define_insn "*x86_movsicc_0_m1_se"
19992 [(set (match_operand:SI 0 "register_operand" "=r")
19993 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19996 (clobber (reg:CC FLAGS_REG))]
19999 [(set_attr "type" "alu")
20000 (set_attr "use_carry" "1")
20001 (set_attr "pent_pair" "pu")
20002 (set_attr "memory" "none")
20003 (set_attr "imm_disp" "false")
20004 (set_attr "mode" "SI")
20005 (set_attr "length_immediate" "0")])
20007 (define_insn "*movsicc_noc"
20008 [(set (match_operand:SI 0 "register_operand" "=r,r")
20009 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20010 [(reg FLAGS_REG) (const_int 0)])
20011 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20012 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20014 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20016 cmov%O2%C1\t{%2, %0|%0, %2}
20017 cmov%O2%c1\t{%3, %0|%0, %3}"
20018 [(set_attr "type" "icmov")
20019 (set_attr "mode" "SI")])
20021 (define_expand "movhicc"
20022 [(set (match_operand:HI 0 "register_operand" "")
20023 (if_then_else:HI (match_operand 1 "comparison_operator" "")
20024 (match_operand:HI 2 "general_operand" "")
20025 (match_operand:HI 3 "general_operand" "")))]
20026 "TARGET_HIMODE_MATH"
20027 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20029 (define_insn "*movhicc_noc"
20030 [(set (match_operand:HI 0 "register_operand" "=r,r")
20031 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20032 [(reg FLAGS_REG) (const_int 0)])
20033 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20034 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20036 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20038 cmov%O2%C1\t{%2, %0|%0, %2}
20039 cmov%O2%c1\t{%3, %0|%0, %3}"
20040 [(set_attr "type" "icmov")
20041 (set_attr "mode" "HI")])
20043 (define_expand "movqicc"
20044 [(set (match_operand:QI 0 "register_operand" "")
20045 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20046 (match_operand:QI 2 "general_operand" "")
20047 (match_operand:QI 3 "general_operand" "")))]
20048 "TARGET_QIMODE_MATH"
20049 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20051 (define_insn_and_split "*movqicc_noc"
20052 [(set (match_operand:QI 0 "register_operand" "=r,r")
20053 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20054 [(match_operand 4 "flags_reg_operand" "")
20056 (match_operand:QI 2 "register_operand" "r,0")
20057 (match_operand:QI 3 "register_operand" "0,r")))]
20058 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20060 "&& reload_completed"
20061 [(set (match_dup 0)
20062 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20065 "operands[0] = gen_lowpart (SImode, operands[0]);
20066 operands[2] = gen_lowpart (SImode, operands[2]);
20067 operands[3] = gen_lowpart (SImode, operands[3]);"
20068 [(set_attr "type" "icmov")
20069 (set_attr "mode" "SI")])
20071 (define_expand "mov<mode>cc"
20072 [(set (match_operand:X87MODEF 0 "register_operand" "")
20073 (if_then_else:X87MODEF
20074 (match_operand 1 "comparison_operator" "")
20075 (match_operand:X87MODEF 2 "register_operand" "")
20076 (match_operand:X87MODEF 3 "register_operand" "")))]
20077 "(TARGET_80387 && TARGET_CMOVE)
20078 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20079 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20081 (define_insn "*movsfcc_1_387"
20082 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20083 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20084 [(reg FLAGS_REG) (const_int 0)])
20085 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20086 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20087 "TARGET_80387 && TARGET_CMOVE
20088 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20090 fcmov%F1\t{%2, %0|%0, %2}
20091 fcmov%f1\t{%3, %0|%0, %3}
20092 cmov%O2%C1\t{%2, %0|%0, %2}
20093 cmov%O2%c1\t{%3, %0|%0, %3}"
20094 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20095 (set_attr "mode" "SF,SF,SI,SI")])
20097 (define_insn "*movdfcc_1"
20098 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20099 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20100 [(reg FLAGS_REG) (const_int 0)])
20101 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20102 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20103 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20104 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20106 fcmov%F1\t{%2, %0|%0, %2}
20107 fcmov%f1\t{%3, %0|%0, %3}
20110 [(set_attr "type" "fcmov,fcmov,multi,multi")
20111 (set_attr "mode" "DF")])
20113 (define_insn "*movdfcc_1_rex64"
20114 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20115 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20116 [(reg FLAGS_REG) (const_int 0)])
20117 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20118 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20119 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20120 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20122 fcmov%F1\t{%2, %0|%0, %2}
20123 fcmov%f1\t{%3, %0|%0, %3}
20124 cmov%O2%C1\t{%2, %0|%0, %2}
20125 cmov%O2%c1\t{%3, %0|%0, %3}"
20126 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20127 (set_attr "mode" "DF")])
20130 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20131 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20132 [(match_operand 4 "flags_reg_operand" "")
20134 (match_operand:DF 2 "nonimmediate_operand" "")
20135 (match_operand:DF 3 "nonimmediate_operand" "")))]
20136 "!TARGET_64BIT && reload_completed"
20137 [(set (match_dup 2)
20138 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20142 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20145 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20146 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20148 (define_insn "*movxfcc_1"
20149 [(set (match_operand:XF 0 "register_operand" "=f,f")
20150 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20151 [(reg FLAGS_REG) (const_int 0)])
20152 (match_operand:XF 2 "register_operand" "f,0")
20153 (match_operand:XF 3 "register_operand" "0,f")))]
20154 "TARGET_80387 && TARGET_CMOVE"
20156 fcmov%F1\t{%2, %0|%0, %2}
20157 fcmov%f1\t{%3, %0|%0, %3}"
20158 [(set_attr "type" "fcmov")
20159 (set_attr "mode" "XF")])
20161 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20162 ;; the scalar versions to have only XMM registers as operands.
20164 ;; SSE5 conditional move
20165 (define_insn "*sse5_pcmov_<mode>"
20166 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20167 (if_then_else:MODEF
20168 (match_operand:MODEF 1 "register_operand" "x,0")
20169 (match_operand:MODEF 2 "register_operand" "0,x")
20170 (match_operand:MODEF 3 "register_operand" "x,x")))]
20171 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20172 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20173 [(set_attr "type" "sse4arg")])
20175 ;; These versions of the min/max patterns are intentionally ignorant of
20176 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20177 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20178 ;; are undefined in this condition, we're certain this is correct.
20180 (define_insn "*avx_<code><mode>3"
20181 [(set (match_operand:MODEF 0 "register_operand" "=x")
20183 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20184 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20185 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20186 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20187 [(set_attr "type" "sseadd")
20188 (set_attr "prefix" "vex")
20189 (set_attr "mode" "<MODE>")])
20191 (define_insn "<code><mode>3"
20192 [(set (match_operand:MODEF 0 "register_operand" "=x")
20194 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20195 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20196 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20197 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20198 [(set_attr "type" "sseadd")
20199 (set_attr "mode" "<MODE>")])
20201 ;; These versions of the min/max patterns implement exactly the operations
20202 ;; min = (op1 < op2 ? op1 : op2)
20203 ;; max = (!(op1 < op2) ? op1 : op2)
20204 ;; Their operands are not commutative, and thus they may be used in the
20205 ;; presence of -0.0 and NaN.
20207 (define_insn "*avx_ieee_smin<mode>3"
20208 [(set (match_operand:MODEF 0 "register_operand" "=x")
20210 [(match_operand:MODEF 1 "register_operand" "x")
20211 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20213 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20214 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20215 [(set_attr "type" "sseadd")
20216 (set_attr "prefix" "vex")
20217 (set_attr "mode" "<MODE>")])
20219 (define_insn "*ieee_smin<mode>3"
20220 [(set (match_operand:MODEF 0 "register_operand" "=x")
20222 [(match_operand:MODEF 1 "register_operand" "0")
20223 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20225 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20226 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20227 [(set_attr "type" "sseadd")
20228 (set_attr "mode" "<MODE>")])
20230 (define_insn "*avx_ieee_smax<mode>3"
20231 [(set (match_operand:MODEF 0 "register_operand" "=x")
20233 [(match_operand:MODEF 1 "register_operand" "0")
20234 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20236 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20237 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20238 [(set_attr "type" "sseadd")
20239 (set_attr "prefix" "vex")
20240 (set_attr "mode" "<MODE>")])
20242 (define_insn "*ieee_smax<mode>3"
20243 [(set (match_operand:MODEF 0 "register_operand" "=x")
20245 [(match_operand:MODEF 1 "register_operand" "0")
20246 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20248 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20249 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20250 [(set_attr "type" "sseadd")
20251 (set_attr "mode" "<MODE>")])
20253 ;; Make two stack loads independent:
20255 ;; fld %st(0) -> fld bb
20256 ;; fmul bb fmul %st(1), %st
20258 ;; Actually we only match the last two instructions for simplicity.
20260 [(set (match_operand 0 "fp_register_operand" "")
20261 (match_operand 1 "fp_register_operand" ""))
20263 (match_operator 2 "binary_fp_operator"
20265 (match_operand 3 "memory_operand" "")]))]
20266 "REGNO (operands[0]) != REGNO (operands[1])"
20267 [(set (match_dup 0) (match_dup 3))
20268 (set (match_dup 0) (match_dup 4))]
20270 ;; The % modifier is not operational anymore in peephole2's, so we have to
20271 ;; swap the operands manually in the case of addition and multiplication.
20272 "if (COMMUTATIVE_ARITH_P (operands[2]))
20273 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20274 operands[0], operands[1]);
20276 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20277 operands[1], operands[0]);")
20279 ;; Conditional addition patterns
20280 (define_expand "add<mode>cc"
20281 [(match_operand:SWI 0 "register_operand" "")
20282 (match_operand 1 "comparison_operator" "")
20283 (match_operand:SWI 2 "register_operand" "")
20284 (match_operand:SWI 3 "const_int_operand" "")]
20286 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20289 ;; Misc patterns (?)
20291 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20292 ;; Otherwise there will be nothing to keep
20294 ;; [(set (reg ebp) (reg esp))]
20295 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20296 ;; (clobber (eflags)]
20297 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20299 ;; in proper program order.
20300 (define_insn "pro_epilogue_adjust_stack_1"
20301 [(set (match_operand:SI 0 "register_operand" "=r,r")
20302 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20303 (match_operand:SI 2 "immediate_operand" "i,i")))
20304 (clobber (reg:CC FLAGS_REG))
20305 (clobber (mem:BLK (scratch)))]
20308 switch (get_attr_type (insn))
20311 return "mov{l}\t{%1, %0|%0, %1}";
20314 if (CONST_INT_P (operands[2])
20315 && (INTVAL (operands[2]) == 128
20316 || (INTVAL (operands[2]) < 0
20317 && INTVAL (operands[2]) != -128)))
20319 operands[2] = GEN_INT (-INTVAL (operands[2]));
20320 return "sub{l}\t{%2, %0|%0, %2}";
20322 return "add{l}\t{%2, %0|%0, %2}";
20325 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20326 return "lea{l}\t{%a2, %0|%0, %a2}";
20329 gcc_unreachable ();
20332 [(set (attr "type")
20333 (cond [(and (eq_attr "alternative" "0")
20334 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20335 (const_string "alu")
20336 (match_operand:SI 2 "const0_operand" "")
20337 (const_string "imov")
20339 (const_string "lea")))
20340 (set_attr "mode" "SI")])
20342 (define_insn "pro_epilogue_adjust_stack_rex64"
20343 [(set (match_operand:DI 0 "register_operand" "=r,r")
20344 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20345 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20346 (clobber (reg:CC FLAGS_REG))
20347 (clobber (mem:BLK (scratch)))]
20350 switch (get_attr_type (insn))
20353 return "mov{q}\t{%1, %0|%0, %1}";
20356 if (CONST_INT_P (operands[2])
20357 /* Avoid overflows. */
20358 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20359 && (INTVAL (operands[2]) == 128
20360 || (INTVAL (operands[2]) < 0
20361 && INTVAL (operands[2]) != -128)))
20363 operands[2] = GEN_INT (-INTVAL (operands[2]));
20364 return "sub{q}\t{%2, %0|%0, %2}";
20366 return "add{q}\t{%2, %0|%0, %2}";
20369 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20370 return "lea{q}\t{%a2, %0|%0, %a2}";
20373 gcc_unreachable ();
20376 [(set (attr "type")
20377 (cond [(and (eq_attr "alternative" "0")
20378 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20379 (const_string "alu")
20380 (match_operand:DI 2 "const0_operand" "")
20381 (const_string "imov")
20383 (const_string "lea")))
20384 (set_attr "mode" "DI")])
20386 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20387 [(set (match_operand:DI 0 "register_operand" "=r,r")
20388 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20389 (match_operand:DI 3 "immediate_operand" "i,i")))
20390 (use (match_operand:DI 2 "register_operand" "r,r"))
20391 (clobber (reg:CC FLAGS_REG))
20392 (clobber (mem:BLK (scratch)))]
20395 switch (get_attr_type (insn))
20398 return "add{q}\t{%2, %0|%0, %2}";
20401 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20402 return "lea{q}\t{%a2, %0|%0, %a2}";
20405 gcc_unreachable ();
20408 [(set_attr "type" "alu,lea")
20409 (set_attr "mode" "DI")])
20411 (define_insn "allocate_stack_worker_32"
20412 [(set (match_operand:SI 0 "register_operand" "=a")
20413 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20414 UNSPECV_STACK_PROBE))
20415 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20416 (clobber (reg:CC FLAGS_REG))]
20417 "!TARGET_64BIT && TARGET_STACK_PROBE"
20419 [(set_attr "type" "multi")
20420 (set_attr "length" "5")])
20422 (define_insn "allocate_stack_worker_64"
20423 [(set (match_operand:DI 0 "register_operand" "=a")
20424 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20425 UNSPECV_STACK_PROBE))
20426 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20427 (clobber (reg:DI R10_REG))
20428 (clobber (reg:DI R11_REG))
20429 (clobber (reg:CC FLAGS_REG))]
20430 "TARGET_64BIT && TARGET_STACK_PROBE"
20432 [(set_attr "type" "multi")
20433 (set_attr "length" "5")])
20435 (define_expand "allocate_stack"
20436 [(match_operand 0 "register_operand" "")
20437 (match_operand 1 "general_operand" "")]
20438 "TARGET_STACK_PROBE"
20442 #ifndef CHECK_STACK_LIMIT
20443 #define CHECK_STACK_LIMIT 0
20446 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20447 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20449 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20450 stack_pointer_rtx, 0, OPTAB_DIRECT);
20451 if (x != stack_pointer_rtx)
20452 emit_move_insn (stack_pointer_rtx, x);
20456 x = copy_to_mode_reg (Pmode, operands[1]);
20458 x = gen_allocate_stack_worker_64 (x, x);
20460 x = gen_allocate_stack_worker_32 (x, x);
20464 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20468 (define_expand "builtin_setjmp_receiver"
20469 [(label_ref (match_operand 0 "" ""))]
20470 "!TARGET_64BIT && flag_pic"
20476 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20477 rtx label_rtx = gen_label_rtx ();
20478 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20479 xops[0] = xops[1] = picreg;
20480 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20481 ix86_expand_binary_operator (MINUS, SImode, xops);
20485 emit_insn (gen_set_got (pic_offset_table_rtx));
20489 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20492 [(set (match_operand 0 "register_operand" "")
20493 (match_operator 3 "promotable_binary_operator"
20494 [(match_operand 1 "register_operand" "")
20495 (match_operand 2 "aligned_operand" "")]))
20496 (clobber (reg:CC FLAGS_REG))]
20497 "! TARGET_PARTIAL_REG_STALL && reload_completed
20498 && ((GET_MODE (operands[0]) == HImode
20499 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20500 /* ??? next two lines just !satisfies_constraint_K (...) */
20501 || !CONST_INT_P (operands[2])
20502 || satisfies_constraint_K (operands[2])))
20503 || (GET_MODE (operands[0]) == QImode
20504 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20505 [(parallel [(set (match_dup 0)
20506 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20507 (clobber (reg:CC FLAGS_REG))])]
20508 "operands[0] = gen_lowpart (SImode, operands[0]);
20509 operands[1] = gen_lowpart (SImode, operands[1]);
20510 if (GET_CODE (operands[3]) != ASHIFT)
20511 operands[2] = gen_lowpart (SImode, operands[2]);
20512 PUT_MODE (operands[3], SImode);")
20514 ; Promote the QImode tests, as i386 has encoding of the AND
20515 ; instruction with 32-bit sign-extended immediate and thus the
20516 ; instruction size is unchanged, except in the %eax case for
20517 ; which it is increased by one byte, hence the ! optimize_size.
20519 [(set (match_operand 0 "flags_reg_operand" "")
20520 (match_operator 2 "compare_operator"
20521 [(and (match_operand 3 "aligned_operand" "")
20522 (match_operand 4 "const_int_operand" ""))
20524 (set (match_operand 1 "register_operand" "")
20525 (and (match_dup 3) (match_dup 4)))]
20526 "! TARGET_PARTIAL_REG_STALL && reload_completed
20527 && optimize_insn_for_speed_p ()
20528 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20529 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20530 /* Ensure that the operand will remain sign-extended immediate. */
20531 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20532 [(parallel [(set (match_dup 0)
20533 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20536 (and:SI (match_dup 3) (match_dup 4)))])]
20539 = gen_int_mode (INTVAL (operands[4])
20540 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20541 operands[1] = gen_lowpart (SImode, operands[1]);
20542 operands[3] = gen_lowpart (SImode, operands[3]);
20545 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20546 ; the TEST instruction with 32-bit sign-extended immediate and thus
20547 ; the instruction size would at least double, which is not what we
20548 ; want even with ! optimize_size.
20550 [(set (match_operand 0 "flags_reg_operand" "")
20551 (match_operator 1 "compare_operator"
20552 [(and (match_operand:HI 2 "aligned_operand" "")
20553 (match_operand:HI 3 "const_int_operand" ""))
20555 "! TARGET_PARTIAL_REG_STALL && reload_completed
20556 && ! TARGET_FAST_PREFIX
20557 && optimize_insn_for_speed_p ()
20558 /* Ensure that the operand will remain sign-extended immediate. */
20559 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20560 [(set (match_dup 0)
20561 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20565 = gen_int_mode (INTVAL (operands[3])
20566 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20567 operands[2] = gen_lowpart (SImode, operands[2]);
20571 [(set (match_operand 0 "register_operand" "")
20572 (neg (match_operand 1 "register_operand" "")))
20573 (clobber (reg:CC FLAGS_REG))]
20574 "! TARGET_PARTIAL_REG_STALL && reload_completed
20575 && (GET_MODE (operands[0]) == HImode
20576 || (GET_MODE (operands[0]) == QImode
20577 && (TARGET_PROMOTE_QImode
20578 || optimize_insn_for_size_p ())))"
20579 [(parallel [(set (match_dup 0)
20580 (neg:SI (match_dup 1)))
20581 (clobber (reg:CC FLAGS_REG))])]
20582 "operands[0] = gen_lowpart (SImode, operands[0]);
20583 operands[1] = gen_lowpart (SImode, operands[1]);")
20586 [(set (match_operand 0 "register_operand" "")
20587 (not (match_operand 1 "register_operand" "")))]
20588 "! TARGET_PARTIAL_REG_STALL && reload_completed
20589 && (GET_MODE (operands[0]) == HImode
20590 || (GET_MODE (operands[0]) == QImode
20591 && (TARGET_PROMOTE_QImode
20592 || optimize_insn_for_size_p ())))"
20593 [(set (match_dup 0)
20594 (not:SI (match_dup 1)))]
20595 "operands[0] = gen_lowpart (SImode, operands[0]);
20596 operands[1] = gen_lowpart (SImode, operands[1]);")
20599 [(set (match_operand 0 "register_operand" "")
20600 (if_then_else (match_operator 1 "comparison_operator"
20601 [(reg FLAGS_REG) (const_int 0)])
20602 (match_operand 2 "register_operand" "")
20603 (match_operand 3 "register_operand" "")))]
20604 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20605 && (GET_MODE (operands[0]) == HImode
20606 || (GET_MODE (operands[0]) == QImode
20607 && (TARGET_PROMOTE_QImode
20608 || optimize_insn_for_size_p ())))"
20609 [(set (match_dup 0)
20610 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20611 "operands[0] = gen_lowpart (SImode, operands[0]);
20612 operands[2] = gen_lowpart (SImode, operands[2]);
20613 operands[3] = gen_lowpart (SImode, operands[3]);")
20616 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20617 ;; transform a complex memory operation into two memory to register operations.
20619 ;; Don't push memory operands
20621 [(set (match_operand:SI 0 "push_operand" "")
20622 (match_operand:SI 1 "memory_operand" ""))
20623 (match_scratch:SI 2 "r")]
20624 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20625 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20626 [(set (match_dup 2) (match_dup 1))
20627 (set (match_dup 0) (match_dup 2))]
20631 [(set (match_operand:DI 0 "push_operand" "")
20632 (match_operand:DI 1 "memory_operand" ""))
20633 (match_scratch:DI 2 "r")]
20634 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20635 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20636 [(set (match_dup 2) (match_dup 1))
20637 (set (match_dup 0) (match_dup 2))]
20640 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20643 [(set (match_operand:SF 0 "push_operand" "")
20644 (match_operand:SF 1 "memory_operand" ""))
20645 (match_scratch:SF 2 "r")]
20646 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20647 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20648 [(set (match_dup 2) (match_dup 1))
20649 (set (match_dup 0) (match_dup 2))]
20653 [(set (match_operand:HI 0 "push_operand" "")
20654 (match_operand:HI 1 "memory_operand" ""))
20655 (match_scratch:HI 2 "r")]
20656 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20657 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20658 [(set (match_dup 2) (match_dup 1))
20659 (set (match_dup 0) (match_dup 2))]
20663 [(set (match_operand:QI 0 "push_operand" "")
20664 (match_operand:QI 1 "memory_operand" ""))
20665 (match_scratch:QI 2 "q")]
20666 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20667 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20668 [(set (match_dup 2) (match_dup 1))
20669 (set (match_dup 0) (match_dup 2))]
20672 ;; Don't move an immediate directly to memory when the instruction
20675 [(match_scratch:SI 1 "r")
20676 (set (match_operand:SI 0 "memory_operand" "")
20678 "optimize_insn_for_speed_p ()
20679 && ! TARGET_USE_MOV0
20680 && TARGET_SPLIT_LONG_MOVES
20681 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20682 && peep2_regno_dead_p (0, FLAGS_REG)"
20683 [(parallel [(set (match_dup 1) (const_int 0))
20684 (clobber (reg:CC FLAGS_REG))])
20685 (set (match_dup 0) (match_dup 1))]
20689 [(match_scratch:HI 1 "r")
20690 (set (match_operand:HI 0 "memory_operand" "")
20692 "optimize_insn_for_speed_p ()
20693 && ! TARGET_USE_MOV0
20694 && TARGET_SPLIT_LONG_MOVES
20695 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20696 && peep2_regno_dead_p (0, FLAGS_REG)"
20697 [(parallel [(set (match_dup 2) (const_int 0))
20698 (clobber (reg:CC FLAGS_REG))])
20699 (set (match_dup 0) (match_dup 1))]
20700 "operands[2] = gen_lowpart (SImode, operands[1]);")
20703 [(match_scratch:QI 1 "q")
20704 (set (match_operand:QI 0 "memory_operand" "")
20706 "optimize_insn_for_speed_p ()
20707 && ! TARGET_USE_MOV0
20708 && TARGET_SPLIT_LONG_MOVES
20709 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20710 && peep2_regno_dead_p (0, FLAGS_REG)"
20711 [(parallel [(set (match_dup 2) (const_int 0))
20712 (clobber (reg:CC FLAGS_REG))])
20713 (set (match_dup 0) (match_dup 1))]
20714 "operands[2] = gen_lowpart (SImode, operands[1]);")
20717 [(match_scratch:SI 2 "r")
20718 (set (match_operand:SI 0 "memory_operand" "")
20719 (match_operand:SI 1 "immediate_operand" ""))]
20720 "optimize_insn_for_speed_p ()
20721 && TARGET_SPLIT_LONG_MOVES
20722 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20723 [(set (match_dup 2) (match_dup 1))
20724 (set (match_dup 0) (match_dup 2))]
20728 [(match_scratch:HI 2 "r")
20729 (set (match_operand:HI 0 "memory_operand" "")
20730 (match_operand:HI 1 "immediate_operand" ""))]
20731 "optimize_insn_for_speed_p ()
20732 && TARGET_SPLIT_LONG_MOVES
20733 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20734 [(set (match_dup 2) (match_dup 1))
20735 (set (match_dup 0) (match_dup 2))]
20739 [(match_scratch:QI 2 "q")
20740 (set (match_operand:QI 0 "memory_operand" "")
20741 (match_operand:QI 1 "immediate_operand" ""))]
20742 "optimize_insn_for_speed_p ()
20743 && TARGET_SPLIT_LONG_MOVES
20744 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20745 [(set (match_dup 2) (match_dup 1))
20746 (set (match_dup 0) (match_dup 2))]
20749 ;; Don't compare memory with zero, load and use a test instead.
20751 [(set (match_operand 0 "flags_reg_operand" "")
20752 (match_operator 1 "compare_operator"
20753 [(match_operand:SI 2 "memory_operand" "")
20755 (match_scratch:SI 3 "r")]
20756 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20757 [(set (match_dup 3) (match_dup 2))
20758 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20761 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20762 ;; Don't split NOTs with a displacement operand, because resulting XOR
20763 ;; will not be pairable anyway.
20765 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20766 ;; represented using a modRM byte. The XOR replacement is long decoded,
20767 ;; so this split helps here as well.
20769 ;; Note: Can't do this as a regular split because we can't get proper
20770 ;; lifetime information then.
20773 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20774 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20775 "optimize_insn_for_speed_p ()
20776 && ((TARGET_NOT_UNPAIRABLE
20777 && (!MEM_P (operands[0])
20778 || !memory_displacement_operand (operands[0], SImode)))
20779 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20780 && peep2_regno_dead_p (0, FLAGS_REG)"
20781 [(parallel [(set (match_dup 0)
20782 (xor:SI (match_dup 1) (const_int -1)))
20783 (clobber (reg:CC FLAGS_REG))])]
20787 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20788 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20789 "optimize_insn_for_speed_p ()
20790 && ((TARGET_NOT_UNPAIRABLE
20791 && (!MEM_P (operands[0])
20792 || !memory_displacement_operand (operands[0], HImode)))
20793 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20794 && peep2_regno_dead_p (0, FLAGS_REG)"
20795 [(parallel [(set (match_dup 0)
20796 (xor:HI (match_dup 1) (const_int -1)))
20797 (clobber (reg:CC FLAGS_REG))])]
20801 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20802 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20803 "optimize_insn_for_speed_p ()
20804 && ((TARGET_NOT_UNPAIRABLE
20805 && (!MEM_P (operands[0])
20806 || !memory_displacement_operand (operands[0], QImode)))
20807 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20808 && peep2_regno_dead_p (0, FLAGS_REG)"
20809 [(parallel [(set (match_dup 0)
20810 (xor:QI (match_dup 1) (const_int -1)))
20811 (clobber (reg:CC FLAGS_REG))])]
20814 ;; Non pairable "test imm, reg" instructions can be translated to
20815 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20816 ;; byte opcode instead of two, have a short form for byte operands),
20817 ;; so do it for other CPUs as well. Given that the value was dead,
20818 ;; this should not create any new dependencies. Pass on the sub-word
20819 ;; versions if we're concerned about partial register stalls.
20822 [(set (match_operand 0 "flags_reg_operand" "")
20823 (match_operator 1 "compare_operator"
20824 [(and:SI (match_operand:SI 2 "register_operand" "")
20825 (match_operand:SI 3 "immediate_operand" ""))
20827 "ix86_match_ccmode (insn, CCNOmode)
20828 && (true_regnum (operands[2]) != AX_REG
20829 || satisfies_constraint_K (operands[3]))
20830 && peep2_reg_dead_p (1, operands[2])"
20832 [(set (match_dup 0)
20833 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20836 (and:SI (match_dup 2) (match_dup 3)))])]
20839 ;; We don't need to handle HImode case, because it will be promoted to SImode
20840 ;; on ! TARGET_PARTIAL_REG_STALL
20843 [(set (match_operand 0 "flags_reg_operand" "")
20844 (match_operator 1 "compare_operator"
20845 [(and:QI (match_operand:QI 2 "register_operand" "")
20846 (match_operand:QI 3 "immediate_operand" ""))
20848 "! TARGET_PARTIAL_REG_STALL
20849 && ix86_match_ccmode (insn, CCNOmode)
20850 && true_regnum (operands[2]) != AX_REG
20851 && peep2_reg_dead_p (1, operands[2])"
20853 [(set (match_dup 0)
20854 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20857 (and:QI (match_dup 2) (match_dup 3)))])]
20861 [(set (match_operand 0 "flags_reg_operand" "")
20862 (match_operator 1 "compare_operator"
20865 (match_operand 2 "ext_register_operand" "")
20868 (match_operand 3 "const_int_operand" ""))
20870 "! TARGET_PARTIAL_REG_STALL
20871 && ix86_match_ccmode (insn, CCNOmode)
20872 && true_regnum (operands[2]) != AX_REG
20873 && peep2_reg_dead_p (1, operands[2])"
20874 [(parallel [(set (match_dup 0)
20883 (set (zero_extract:SI (match_dup 2)
20894 ;; Don't do logical operations with memory inputs.
20896 [(match_scratch:SI 2 "r")
20897 (parallel [(set (match_operand:SI 0 "register_operand" "")
20898 (match_operator:SI 3 "arith_or_logical_operator"
20900 (match_operand:SI 1 "memory_operand" "")]))
20901 (clobber (reg:CC FLAGS_REG))])]
20902 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20903 [(set (match_dup 2) (match_dup 1))
20904 (parallel [(set (match_dup 0)
20905 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20906 (clobber (reg:CC FLAGS_REG))])]
20910 [(match_scratch:SI 2 "r")
20911 (parallel [(set (match_operand:SI 0 "register_operand" "")
20912 (match_operator:SI 3 "arith_or_logical_operator"
20913 [(match_operand:SI 1 "memory_operand" "")
20915 (clobber (reg:CC FLAGS_REG))])]
20916 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20917 [(set (match_dup 2) (match_dup 1))
20918 (parallel [(set (match_dup 0)
20919 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20920 (clobber (reg:CC FLAGS_REG))])]
20923 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20924 ;; refers to the destination of the load!
20927 [(set (match_operand:SI 0 "register_operand" "")
20928 (match_operand:SI 1 "register_operand" ""))
20929 (parallel [(set (match_dup 0)
20930 (match_operator:SI 3 "commutative_operator"
20932 (match_operand:SI 2 "memory_operand" "")]))
20933 (clobber (reg:CC FLAGS_REG))])]
20934 "REGNO (operands[0]) != REGNO (operands[1])
20935 && GENERAL_REGNO_P (REGNO (operands[0]))
20936 && GENERAL_REGNO_P (REGNO (operands[1]))"
20937 [(set (match_dup 0) (match_dup 4))
20938 (parallel [(set (match_dup 0)
20939 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20940 (clobber (reg:CC FLAGS_REG))])]
20941 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20944 [(set (match_operand 0 "register_operand" "")
20945 (match_operand 1 "register_operand" ""))
20947 (match_operator 3 "commutative_operator"
20949 (match_operand 2 "memory_operand" "")]))]
20950 "REGNO (operands[0]) != REGNO (operands[1])
20951 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20952 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20953 [(set (match_dup 0) (match_dup 2))
20955 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20958 ; Don't do logical operations with memory outputs
20960 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20961 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20962 ; the same decoder scheduling characteristics as the original.
20965 [(match_scratch:SI 2 "r")
20966 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20967 (match_operator:SI 3 "arith_or_logical_operator"
20969 (match_operand:SI 1 "nonmemory_operand" "")]))
20970 (clobber (reg:CC FLAGS_REG))])]
20971 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20972 [(set (match_dup 2) (match_dup 0))
20973 (parallel [(set (match_dup 2)
20974 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20975 (clobber (reg:CC FLAGS_REG))])
20976 (set (match_dup 0) (match_dup 2))]
20980 [(match_scratch:SI 2 "r")
20981 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20982 (match_operator:SI 3 "arith_or_logical_operator"
20983 [(match_operand:SI 1 "nonmemory_operand" "")
20985 (clobber (reg:CC FLAGS_REG))])]
20986 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20987 [(set (match_dup 2) (match_dup 0))
20988 (parallel [(set (match_dup 2)
20989 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20990 (clobber (reg:CC FLAGS_REG))])
20991 (set (match_dup 0) (match_dup 2))]
20994 ;; Attempt to always use XOR for zeroing registers.
20996 [(set (match_operand 0 "register_operand" "")
20997 (match_operand 1 "const0_operand" ""))]
20998 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20999 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21000 && GENERAL_REG_P (operands[0])
21001 && peep2_regno_dead_p (0, FLAGS_REG)"
21002 [(parallel [(set (match_dup 0) (const_int 0))
21003 (clobber (reg:CC FLAGS_REG))])]
21005 operands[0] = gen_lowpart (word_mode, operands[0]);
21009 [(set (strict_low_part (match_operand 0 "register_operand" ""))
21011 "(GET_MODE (operands[0]) == QImode
21012 || GET_MODE (operands[0]) == HImode)
21013 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21014 && peep2_regno_dead_p (0, FLAGS_REG)"
21015 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21016 (clobber (reg:CC FLAGS_REG))])])
21018 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21020 [(set (match_operand 0 "register_operand" "")
21022 "(GET_MODE (operands[0]) == HImode
21023 || GET_MODE (operands[0]) == SImode
21024 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21025 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21026 && peep2_regno_dead_p (0, FLAGS_REG)"
21027 [(parallel [(set (match_dup 0) (const_int -1))
21028 (clobber (reg:CC FLAGS_REG))])]
21029 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21032 ;; Attempt to convert simple leas to adds. These can be created by
21035 [(set (match_operand:SI 0 "register_operand" "")
21036 (plus:SI (match_dup 0)
21037 (match_operand:SI 1 "nonmemory_operand" "")))]
21038 "peep2_regno_dead_p (0, FLAGS_REG)"
21039 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21040 (clobber (reg:CC FLAGS_REG))])]
21044 [(set (match_operand:SI 0 "register_operand" "")
21045 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21046 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21047 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21048 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21049 (clobber (reg:CC FLAGS_REG))])]
21050 "operands[2] = gen_lowpart (SImode, operands[2]);")
21053 [(set (match_operand:DI 0 "register_operand" "")
21054 (plus:DI (match_dup 0)
21055 (match_operand:DI 1 "x86_64_general_operand" "")))]
21056 "peep2_regno_dead_p (0, FLAGS_REG)"
21057 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21058 (clobber (reg:CC FLAGS_REG))])]
21062 [(set (match_operand:SI 0 "register_operand" "")
21063 (mult:SI (match_dup 0)
21064 (match_operand:SI 1 "const_int_operand" "")))]
21065 "exact_log2 (INTVAL (operands[1])) >= 0
21066 && peep2_regno_dead_p (0, FLAGS_REG)"
21067 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21068 (clobber (reg:CC FLAGS_REG))])]
21069 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21072 [(set (match_operand:DI 0 "register_operand" "")
21073 (mult:DI (match_dup 0)
21074 (match_operand:DI 1 "const_int_operand" "")))]
21075 "exact_log2 (INTVAL (operands[1])) >= 0
21076 && peep2_regno_dead_p (0, FLAGS_REG)"
21077 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21078 (clobber (reg:CC FLAGS_REG))])]
21079 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21082 [(set (match_operand:SI 0 "register_operand" "")
21083 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21084 (match_operand:DI 2 "const_int_operand" "")) 0))]
21085 "exact_log2 (INTVAL (operands[2])) >= 0
21086 && REGNO (operands[0]) == REGNO (operands[1])
21087 && peep2_regno_dead_p (0, FLAGS_REG)"
21088 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21089 (clobber (reg:CC FLAGS_REG))])]
21090 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21092 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21093 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21094 ;; many CPUs it is also faster, since special hardware to avoid esp
21095 ;; dependencies is present.
21097 ;; While some of these conversions may be done using splitters, we use peepholes
21098 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21100 ;; Convert prologue esp subtractions to push.
21101 ;; We need register to push. In order to keep verify_flow_info happy we have
21103 ;; - use scratch and clobber it in order to avoid dependencies
21104 ;; - use already live register
21105 ;; We can't use the second way right now, since there is no reliable way how to
21106 ;; verify that given register is live. First choice will also most likely in
21107 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21108 ;; call clobbered registers are dead. We may want to use base pointer as an
21109 ;; alternative when no register is available later.
21112 [(match_scratch:SI 0 "r")
21113 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21114 (clobber (reg:CC FLAGS_REG))
21115 (clobber (mem:BLK (scratch)))])]
21116 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21117 [(clobber (match_dup 0))
21118 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21119 (clobber (mem:BLK (scratch)))])])
21122 [(match_scratch:SI 0 "r")
21123 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21124 (clobber (reg:CC FLAGS_REG))
21125 (clobber (mem:BLK (scratch)))])]
21126 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21127 [(clobber (match_dup 0))
21128 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21129 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21130 (clobber (mem:BLK (scratch)))])])
21132 ;; Convert esp subtractions to push.
21134 [(match_scratch:SI 0 "r")
21135 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21136 (clobber (reg:CC FLAGS_REG))])]
21137 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21138 [(clobber (match_dup 0))
21139 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21142 [(match_scratch:SI 0 "r")
21143 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21144 (clobber (reg:CC FLAGS_REG))])]
21145 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21146 [(clobber (match_dup 0))
21147 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21148 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21150 ;; Convert epilogue deallocator to pop.
21152 [(match_scratch:SI 0 "r")
21153 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21154 (clobber (reg:CC FLAGS_REG))
21155 (clobber (mem:BLK (scratch)))])]
21156 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21157 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21158 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21159 (clobber (mem:BLK (scratch)))])]
21162 ;; Two pops case is tricky, since pop causes dependency on destination register.
21163 ;; We use two registers if available.
21165 [(match_scratch:SI 0 "r")
21166 (match_scratch:SI 1 "r")
21167 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21168 (clobber (reg:CC FLAGS_REG))
21169 (clobber (mem:BLK (scratch)))])]
21170 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21171 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21172 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21173 (clobber (mem:BLK (scratch)))])
21174 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21175 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21179 [(match_scratch:SI 0 "r")
21180 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21181 (clobber (reg:CC FLAGS_REG))
21182 (clobber (mem:BLK (scratch)))])]
21183 "optimize_insn_for_size_p ()"
21184 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21185 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21186 (clobber (mem:BLK (scratch)))])
21187 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21191 ;; Convert esp additions to pop.
21193 [(match_scratch:SI 0 "r")
21194 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21195 (clobber (reg:CC FLAGS_REG))])]
21197 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21198 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21201 ;; Two pops case is tricky, since pop causes dependency on destination register.
21202 ;; We use two registers if available.
21204 [(match_scratch:SI 0 "r")
21205 (match_scratch:SI 1 "r")
21206 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21207 (clobber (reg:CC FLAGS_REG))])]
21209 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21210 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21211 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21212 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21216 [(match_scratch:SI 0 "r")
21217 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21218 (clobber (reg:CC FLAGS_REG))])]
21219 "optimize_insn_for_size_p ()"
21220 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21221 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21222 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21223 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21226 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21227 ;; required and register dies. Similarly for 128 to -128.
21229 [(set (match_operand 0 "flags_reg_operand" "")
21230 (match_operator 1 "compare_operator"
21231 [(match_operand 2 "register_operand" "")
21232 (match_operand 3 "const_int_operand" "")]))]
21233 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21234 && incdec_operand (operands[3], GET_MODE (operands[3])))
21235 || (!TARGET_FUSE_CMP_AND_BRANCH
21236 && INTVAL (operands[3]) == 128))
21237 && ix86_match_ccmode (insn, CCGCmode)
21238 && peep2_reg_dead_p (1, operands[2])"
21239 [(parallel [(set (match_dup 0)
21240 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21241 (clobber (match_dup 2))])]
21245 [(match_scratch:DI 0 "r")
21246 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21247 (clobber (reg:CC FLAGS_REG))
21248 (clobber (mem:BLK (scratch)))])]
21249 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21250 [(clobber (match_dup 0))
21251 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21252 (clobber (mem:BLK (scratch)))])])
21255 [(match_scratch:DI 0 "r")
21256 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21257 (clobber (reg:CC FLAGS_REG))
21258 (clobber (mem:BLK (scratch)))])]
21259 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21260 [(clobber (match_dup 0))
21261 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21262 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21263 (clobber (mem:BLK (scratch)))])])
21265 ;; Convert esp subtractions to push.
21267 [(match_scratch:DI 0 "r")
21268 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21269 (clobber (reg:CC FLAGS_REG))])]
21270 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21271 [(clobber (match_dup 0))
21272 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21275 [(match_scratch:DI 0 "r")
21276 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21277 (clobber (reg:CC FLAGS_REG))])]
21278 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21279 [(clobber (match_dup 0))
21280 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21281 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21283 ;; Convert epilogue deallocator to pop.
21285 [(match_scratch:DI 0 "r")
21286 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21287 (clobber (reg:CC FLAGS_REG))
21288 (clobber (mem:BLK (scratch)))])]
21289 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21290 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21291 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21292 (clobber (mem:BLK (scratch)))])]
21295 ;; Two pops case is tricky, since pop causes dependency on destination register.
21296 ;; We use two registers if available.
21298 [(match_scratch:DI 0 "r")
21299 (match_scratch:DI 1 "r")
21300 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21301 (clobber (reg:CC FLAGS_REG))
21302 (clobber (mem:BLK (scratch)))])]
21303 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21304 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21305 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21306 (clobber (mem:BLK (scratch)))])
21307 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21308 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21312 [(match_scratch:DI 0 "r")
21313 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21314 (clobber (reg:CC FLAGS_REG))
21315 (clobber (mem:BLK (scratch)))])]
21316 "optimize_insn_for_size_p ()"
21317 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21318 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21319 (clobber (mem:BLK (scratch)))])
21320 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21321 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21324 ;; Convert esp additions to pop.
21326 [(match_scratch:DI 0 "r")
21327 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21328 (clobber (reg:CC FLAGS_REG))])]
21330 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21331 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21334 ;; Two pops case is tricky, since pop causes dependency on destination register.
21335 ;; We use two registers if available.
21337 [(match_scratch:DI 0 "r")
21338 (match_scratch:DI 1 "r")
21339 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21340 (clobber (reg:CC FLAGS_REG))])]
21342 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21343 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21344 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21345 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21349 [(match_scratch:DI 0 "r")
21350 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21351 (clobber (reg:CC FLAGS_REG))])]
21352 "optimize_insn_for_size_p ()"
21353 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21354 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21355 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21356 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21359 ;; Convert imul by three, five and nine into lea
21362 [(set (match_operand:SI 0 "register_operand" "")
21363 (mult:SI (match_operand:SI 1 "register_operand" "")
21364 (match_operand:SI 2 "const_int_operand" "")))
21365 (clobber (reg:CC FLAGS_REG))])]
21366 "INTVAL (operands[2]) == 3
21367 || INTVAL (operands[2]) == 5
21368 || INTVAL (operands[2]) == 9"
21369 [(set (match_dup 0)
21370 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21372 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21376 [(set (match_operand:SI 0 "register_operand" "")
21377 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21378 (match_operand:SI 2 "const_int_operand" "")))
21379 (clobber (reg:CC FLAGS_REG))])]
21380 "optimize_insn_for_speed_p ()
21381 && (INTVAL (operands[2]) == 3
21382 || INTVAL (operands[2]) == 5
21383 || INTVAL (operands[2]) == 9)"
21384 [(set (match_dup 0) (match_dup 1))
21386 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21388 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21392 [(set (match_operand:DI 0 "register_operand" "")
21393 (mult:DI (match_operand:DI 1 "register_operand" "")
21394 (match_operand:DI 2 "const_int_operand" "")))
21395 (clobber (reg:CC FLAGS_REG))])]
21397 && (INTVAL (operands[2]) == 3
21398 || INTVAL (operands[2]) == 5
21399 || INTVAL (operands[2]) == 9)"
21400 [(set (match_dup 0)
21401 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21403 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21407 [(set (match_operand:DI 0 "register_operand" "")
21408 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21409 (match_operand:DI 2 "const_int_operand" "")))
21410 (clobber (reg:CC FLAGS_REG))])]
21412 && optimize_insn_for_speed_p ()
21413 && (INTVAL (operands[2]) == 3
21414 || INTVAL (operands[2]) == 5
21415 || INTVAL (operands[2]) == 9)"
21416 [(set (match_dup 0) (match_dup 1))
21418 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21420 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21422 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21423 ;; imul $32bit_imm, reg, reg is direct decoded.
21425 [(match_scratch:DI 3 "r")
21426 (parallel [(set (match_operand:DI 0 "register_operand" "")
21427 (mult:DI (match_operand:DI 1 "memory_operand" "")
21428 (match_operand:DI 2 "immediate_operand" "")))
21429 (clobber (reg:CC FLAGS_REG))])]
21430 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21431 && !satisfies_constraint_K (operands[2])"
21432 [(set (match_dup 3) (match_dup 1))
21433 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21434 (clobber (reg:CC FLAGS_REG))])]
21438 [(match_scratch:SI 3 "r")
21439 (parallel [(set (match_operand:SI 0 "register_operand" "")
21440 (mult:SI (match_operand:SI 1 "memory_operand" "")
21441 (match_operand:SI 2 "immediate_operand" "")))
21442 (clobber (reg:CC FLAGS_REG))])]
21443 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21444 && !satisfies_constraint_K (operands[2])"
21445 [(set (match_dup 3) (match_dup 1))
21446 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21447 (clobber (reg:CC FLAGS_REG))])]
21451 [(match_scratch:SI 3 "r")
21452 (parallel [(set (match_operand:DI 0 "register_operand" "")
21454 (mult:SI (match_operand:SI 1 "memory_operand" "")
21455 (match_operand:SI 2 "immediate_operand" ""))))
21456 (clobber (reg:CC FLAGS_REG))])]
21457 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21458 && !satisfies_constraint_K (operands[2])"
21459 [(set (match_dup 3) (match_dup 1))
21460 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21461 (clobber (reg:CC FLAGS_REG))])]
21464 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21465 ;; Convert it into imul reg, reg
21466 ;; It would be better to force assembler to encode instruction using long
21467 ;; immediate, but there is apparently no way to do so.
21469 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21470 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21471 (match_operand:DI 2 "const_int_operand" "")))
21472 (clobber (reg:CC FLAGS_REG))])
21473 (match_scratch:DI 3 "r")]
21474 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21475 && satisfies_constraint_K (operands[2])"
21476 [(set (match_dup 3) (match_dup 2))
21477 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21478 (clobber (reg:CC FLAGS_REG))])]
21480 if (!rtx_equal_p (operands[0], operands[1]))
21481 emit_move_insn (operands[0], operands[1]);
21485 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21486 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21487 (match_operand:SI 2 "const_int_operand" "")))
21488 (clobber (reg:CC FLAGS_REG))])
21489 (match_scratch:SI 3 "r")]
21490 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21491 && satisfies_constraint_K (operands[2])"
21492 [(set (match_dup 3) (match_dup 2))
21493 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21494 (clobber (reg:CC FLAGS_REG))])]
21496 if (!rtx_equal_p (operands[0], operands[1]))
21497 emit_move_insn (operands[0], operands[1]);
21501 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21502 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21503 (match_operand:HI 2 "immediate_operand" "")))
21504 (clobber (reg:CC FLAGS_REG))])
21505 (match_scratch:HI 3 "r")]
21506 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21507 [(set (match_dup 3) (match_dup 2))
21508 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21509 (clobber (reg:CC FLAGS_REG))])]
21511 if (!rtx_equal_p (operands[0], operands[1]))
21512 emit_move_insn (operands[0], operands[1]);
21515 ;; After splitting up read-modify operations, array accesses with memory
21516 ;; operands might end up in form:
21518 ;; movl 4(%esp), %edx
21520 ;; instead of pre-splitting:
21522 ;; addl 4(%esp), %eax
21524 ;; movl 4(%esp), %edx
21525 ;; leal (%edx,%eax,4), %eax
21528 [(parallel [(set (match_operand 0 "register_operand" "")
21529 (ashift (match_operand 1 "register_operand" "")
21530 (match_operand 2 "const_int_operand" "")))
21531 (clobber (reg:CC FLAGS_REG))])
21532 (set (match_operand 3 "register_operand")
21533 (match_operand 4 "x86_64_general_operand" ""))
21534 (parallel [(set (match_operand 5 "register_operand" "")
21535 (plus (match_operand 6 "register_operand" "")
21536 (match_operand 7 "register_operand" "")))
21537 (clobber (reg:CC FLAGS_REG))])]
21538 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21539 /* Validate MODE for lea. */
21540 && ((!TARGET_PARTIAL_REG_STALL
21541 && (GET_MODE (operands[0]) == QImode
21542 || GET_MODE (operands[0]) == HImode))
21543 || GET_MODE (operands[0]) == SImode
21544 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21545 /* We reorder load and the shift. */
21546 && !rtx_equal_p (operands[1], operands[3])
21547 && !reg_overlap_mentioned_p (operands[0], operands[4])
21548 /* Last PLUS must consist of operand 0 and 3. */
21549 && !rtx_equal_p (operands[0], operands[3])
21550 && (rtx_equal_p (operands[3], operands[6])
21551 || rtx_equal_p (operands[3], operands[7]))
21552 && (rtx_equal_p (operands[0], operands[6])
21553 || rtx_equal_p (operands[0], operands[7]))
21554 /* The intermediate operand 0 must die or be same as output. */
21555 && (rtx_equal_p (operands[0], operands[5])
21556 || peep2_reg_dead_p (3, operands[0]))"
21557 [(set (match_dup 3) (match_dup 4))
21558 (set (match_dup 0) (match_dup 1))]
21560 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21561 int scale = 1 << INTVAL (operands[2]);
21562 rtx index = gen_lowpart (Pmode, operands[1]);
21563 rtx base = gen_lowpart (Pmode, operands[3]);
21564 rtx dest = gen_lowpart (mode, operands[5]);
21566 operands[1] = gen_rtx_PLUS (Pmode, base,
21567 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21569 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21570 operands[0] = dest;
21573 ;; Call-value patterns last so that the wildcard operand does not
21574 ;; disrupt insn-recog's switch tables.
21576 (define_insn "*call_value_pop_0"
21577 [(set (match_operand 0 "" "")
21578 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21579 (match_operand:SI 2 "" "")))
21580 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21581 (match_operand:SI 3 "immediate_operand" "")))]
21584 if (SIBLING_CALL_P (insn))
21587 return "call\t%P1";
21589 [(set_attr "type" "callv")])
21591 (define_insn "*call_value_pop_1"
21592 [(set (match_operand 0 "" "")
21593 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21594 (match_operand:SI 2 "" "")))
21595 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21596 (match_operand:SI 3 "immediate_operand" "i")))]
21599 if (constant_call_address_operand (operands[1], Pmode))
21601 if (SIBLING_CALL_P (insn))
21604 return "call\t%P1";
21606 if (SIBLING_CALL_P (insn))
21609 return "call\t%A1";
21611 [(set_attr "type" "callv")])
21613 (define_insn "*call_value_0"
21614 [(set (match_operand 0 "" "")
21615 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21616 (match_operand:SI 2 "" "")))]
21619 if (SIBLING_CALL_P (insn))
21622 return "call\t%P1";
21624 [(set_attr "type" "callv")])
21626 (define_insn "*call_value_0_rex64"
21627 [(set (match_operand 0 "" "")
21628 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21629 (match_operand:DI 2 "const_int_operand" "")))]
21632 if (SIBLING_CALL_P (insn))
21635 return "call\t%P1";
21637 [(set_attr "type" "callv")])
21639 (define_insn "*call_value_0_rex64_ms_sysv"
21640 [(set (match_operand 0 "" "")
21641 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21642 (match_operand:DI 2 "const_int_operand" "")))
21643 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21644 (clobber (reg:TI XMM6_REG))
21645 (clobber (reg:TI XMM7_REG))
21646 (clobber (reg:TI XMM8_REG))
21647 (clobber (reg:TI XMM9_REG))
21648 (clobber (reg:TI XMM10_REG))
21649 (clobber (reg:TI XMM11_REG))
21650 (clobber (reg:TI XMM12_REG))
21651 (clobber (reg:TI XMM13_REG))
21652 (clobber (reg:TI XMM14_REG))
21653 (clobber (reg:TI XMM15_REG))
21654 (clobber (reg:DI SI_REG))
21655 (clobber (reg:DI DI_REG))]
21656 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21658 if (SIBLING_CALL_P (insn))
21661 return "call\t%P1";
21663 [(set_attr "type" "callv")])
21665 (define_insn "*call_value_1"
21666 [(set (match_operand 0 "" "")
21667 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21668 (match_operand:SI 2 "" "")))]
21669 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21671 if (constant_call_address_operand (operands[1], Pmode))
21672 return "call\t%P1";
21673 return "call\t%A1";
21675 [(set_attr "type" "callv")])
21677 (define_insn "*sibcall_value_1"
21678 [(set (match_operand 0 "" "")
21679 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21680 (match_operand:SI 2 "" "")))]
21681 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21683 if (constant_call_address_operand (operands[1], Pmode))
21687 [(set_attr "type" "callv")])
21689 (define_insn "*call_value_1_rex64"
21690 [(set (match_operand 0 "" "")
21691 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21692 (match_operand:DI 2 "" "")))]
21693 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21694 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21696 if (constant_call_address_operand (operands[1], Pmode))
21697 return "call\t%P1";
21698 return "call\t%A1";
21700 [(set_attr "type" "callv")])
21702 (define_insn "*call_value_1_rex64_ms_sysv"
21703 [(set (match_operand 0 "" "")
21704 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21705 (match_operand:DI 2 "" "")))
21706 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21707 (clobber (reg:TI 27))
21708 (clobber (reg:TI 28))
21709 (clobber (reg:TI 45))
21710 (clobber (reg:TI 46))
21711 (clobber (reg:TI 47))
21712 (clobber (reg:TI 48))
21713 (clobber (reg:TI 49))
21714 (clobber (reg:TI 50))
21715 (clobber (reg:TI 51))
21716 (clobber (reg:TI 52))
21717 (clobber (reg:DI SI_REG))
21718 (clobber (reg:DI DI_REG))]
21719 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21721 if (constant_call_address_operand (operands[1], Pmode))
21722 return "call\t%P1";
21723 return "call\t%A1";
21725 [(set_attr "type" "callv")])
21727 (define_insn "*call_value_1_rex64_large"
21728 [(set (match_operand 0 "" "")
21729 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21730 (match_operand:DI 2 "" "")))]
21731 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21733 [(set_attr "type" "callv")])
21735 (define_insn "*sibcall_value_1_rex64"
21736 [(set (match_operand 0 "" "")
21737 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21738 (match_operand:DI 2 "" "")))]
21739 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21741 [(set_attr "type" "callv")])
21743 (define_insn "*sibcall_value_1_rex64_v"
21744 [(set (match_operand 0 "" "")
21745 (call (mem:QI (reg:DI R11_REG))
21746 (match_operand:DI 1 "" "")))]
21747 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21749 [(set_attr "type" "callv")])
21751 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21752 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21753 ;; caught for use by garbage collectors and the like. Using an insn that
21754 ;; maps to SIGILL makes it more likely the program will rightfully die.
21755 ;; Keeping with tradition, "6" is in honor of #UD.
21756 (define_insn "trap"
21757 [(trap_if (const_int 1) (const_int 6))]
21759 { return ASM_SHORT "0x0b0f"; }
21760 [(set_attr "length" "2")])
21762 (define_expand "sse_prologue_save"
21763 [(parallel [(set (match_operand:BLK 0 "" "")
21764 (unspec:BLK [(reg:DI 21)
21771 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21772 (use (match_operand:DI 1 "register_operand" ""))
21773 (use (match_operand:DI 2 "immediate_operand" ""))
21774 (use (label_ref:DI (match_operand 3 "" "")))])]
21778 (define_insn "*sse_prologue_save_insn"
21779 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21780 (match_operand:DI 4 "const_int_operand" "n")))
21781 (unspec:BLK [(reg:DI 21)
21788 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21789 (use (match_operand:DI 1 "register_operand" "r"))
21790 (use (match_operand:DI 2 "const_int_operand" "i"))
21791 (use (label_ref:DI (match_operand 3 "" "X")))]
21793 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21794 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21797 operands[0] = gen_rtx_MEM (Pmode,
21798 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21799 /* VEX instruction with a REX prefix will #UD. */
21800 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21801 gcc_unreachable ();
21803 output_asm_insn ("jmp\t%A1", operands);
21804 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21806 operands[4] = adjust_address (operands[0], DImode, i*16);
21807 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21808 PUT_MODE (operands[4], TImode);
21809 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21810 output_asm_insn ("rex", operands);
21811 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21813 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21814 CODE_LABEL_NUMBER (operands[3]));
21817 [(set_attr "type" "other")
21818 (set_attr "length_immediate" "0")
21819 (set_attr "length_address" "0")
21820 (set (attr "length")
21822 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21823 (const_string "34")
21824 (const_string "42")))
21825 (set_attr "memory" "store")
21826 (set_attr "modrm" "0")
21827 (set_attr "prefix" "maybe_vex")
21828 (set_attr "mode" "DI")])
21830 (define_expand "prefetch"
21831 [(prefetch (match_operand 0 "address_operand" "")
21832 (match_operand:SI 1 "const_int_operand" "")
21833 (match_operand:SI 2 "const_int_operand" ""))]
21834 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21836 int rw = INTVAL (operands[1]);
21837 int locality = INTVAL (operands[2]);
21839 gcc_assert (rw == 0 || rw == 1);
21840 gcc_assert (locality >= 0 && locality <= 3);
21841 gcc_assert (GET_MODE (operands[0]) == Pmode
21842 || GET_MODE (operands[0]) == VOIDmode);
21844 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21845 supported by SSE counterpart or the SSE prefetch is not available
21846 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21848 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21849 operands[2] = GEN_INT (3);
21851 operands[1] = const0_rtx;
21854 (define_insn "*prefetch_sse"
21855 [(prefetch (match_operand:SI 0 "address_operand" "p")
21857 (match_operand:SI 1 "const_int_operand" ""))]
21858 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21860 static const char * const patterns[4] = {
21861 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21864 int locality = INTVAL (operands[1]);
21865 gcc_assert (locality >= 0 && locality <= 3);
21867 return patterns[locality];
21869 [(set_attr "type" "sse")
21870 (set_attr "atom_sse_attr" "prefetch")
21871 (set_attr "memory" "none")])
21873 (define_insn "*prefetch_sse_rex"
21874 [(prefetch (match_operand:DI 0 "address_operand" "p")
21876 (match_operand:SI 1 "const_int_operand" ""))]
21877 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21879 static const char * const patterns[4] = {
21880 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21883 int locality = INTVAL (operands[1]);
21884 gcc_assert (locality >= 0 && locality <= 3);
21886 return patterns[locality];
21888 [(set_attr "type" "sse")
21889 (set_attr "atom_sse_attr" "prefetch")
21890 (set_attr "memory" "none")])
21892 (define_insn "*prefetch_3dnow"
21893 [(prefetch (match_operand:SI 0 "address_operand" "p")
21894 (match_operand:SI 1 "const_int_operand" "n")
21896 "TARGET_3DNOW && !TARGET_64BIT"
21898 if (INTVAL (operands[1]) == 0)
21899 return "prefetch\t%a0";
21901 return "prefetchw\t%a0";
21903 [(set_attr "type" "mmx")
21904 (set_attr "memory" "none")])
21906 (define_insn "*prefetch_3dnow_rex"
21907 [(prefetch (match_operand:DI 0 "address_operand" "p")
21908 (match_operand:SI 1 "const_int_operand" "n")
21910 "TARGET_3DNOW && TARGET_64BIT"
21912 if (INTVAL (operands[1]) == 0)
21913 return "prefetch\t%a0";
21915 return "prefetchw\t%a0";
21917 [(set_attr "type" "mmx")
21918 (set_attr "memory" "none")])
21920 (define_expand "stack_protect_set"
21921 [(match_operand 0 "memory_operand" "")
21922 (match_operand 1 "memory_operand" "")]
21925 #ifdef TARGET_THREAD_SSP_OFFSET
21927 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21928 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21930 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21931 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21934 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21936 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21941 (define_insn "stack_protect_set_si"
21942 [(set (match_operand:SI 0 "memory_operand" "=m")
21943 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21944 (set (match_scratch:SI 2 "=&r") (const_int 0))
21945 (clobber (reg:CC FLAGS_REG))]
21947 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21948 [(set_attr "type" "multi")])
21950 (define_insn "stack_protect_set_di"
21951 [(set (match_operand:DI 0 "memory_operand" "=m")
21952 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21953 (set (match_scratch:DI 2 "=&r") (const_int 0))
21954 (clobber (reg:CC FLAGS_REG))]
21956 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21957 [(set_attr "type" "multi")])
21959 (define_insn "stack_tls_protect_set_si"
21960 [(set (match_operand:SI 0 "memory_operand" "=m")
21961 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21962 (set (match_scratch:SI 2 "=&r") (const_int 0))
21963 (clobber (reg:CC FLAGS_REG))]
21965 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21966 [(set_attr "type" "multi")])
21968 (define_insn "stack_tls_protect_set_di"
21969 [(set (match_operand:DI 0 "memory_operand" "=m")
21970 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21971 (set (match_scratch:DI 2 "=&r") (const_int 0))
21972 (clobber (reg:CC FLAGS_REG))]
21975 /* The kernel uses a different segment register for performance reasons; a
21976 system call would not have to trash the userspace segment register,
21977 which would be expensive */
21978 if (ix86_cmodel != CM_KERNEL)
21979 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21981 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21983 [(set_attr "type" "multi")])
21985 (define_expand "stack_protect_test"
21986 [(match_operand 0 "memory_operand" "")
21987 (match_operand 1 "memory_operand" "")
21988 (match_operand 2 "" "")]
21991 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21993 #ifdef TARGET_THREAD_SSP_OFFSET
21995 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21996 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21998 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21999 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22002 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22004 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22007 ix86_compare_op0 = flags;
22008 ix86_compare_op1 = const0_rtx;
22009 emit_jump_insn (gen_beq (operands[2]));
22013 (define_insn "stack_protect_test_si"
22014 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22015 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22016 (match_operand:SI 2 "memory_operand" "m")]
22018 (clobber (match_scratch:SI 3 "=&r"))]
22020 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22021 [(set_attr "type" "multi")])
22023 (define_insn "stack_protect_test_di"
22024 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22025 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22026 (match_operand:DI 2 "memory_operand" "m")]
22028 (clobber (match_scratch:DI 3 "=&r"))]
22030 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22031 [(set_attr "type" "multi")])
22033 (define_insn "stack_tls_protect_test_si"
22034 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22035 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22036 (match_operand:SI 2 "const_int_operand" "i")]
22037 UNSPEC_SP_TLS_TEST))
22038 (clobber (match_scratch:SI 3 "=r"))]
22040 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22041 [(set_attr "type" "multi")])
22043 (define_insn "stack_tls_protect_test_di"
22044 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22045 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22046 (match_operand:DI 2 "const_int_operand" "i")]
22047 UNSPEC_SP_TLS_TEST))
22048 (clobber (match_scratch:DI 3 "=r"))]
22051 /* The kernel uses a different segment register for performance reasons; a
22052 system call would not have to trash the userspace segment register,
22053 which would be expensive */
22054 if (ix86_cmodel != CM_KERNEL)
22055 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22057 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22059 [(set_attr "type" "multi")])
22061 (define_mode_iterator CRC32MODE [QI HI SI])
22062 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22063 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22065 (define_insn "sse4_2_crc32<mode>"
22066 [(set (match_operand:SI 0 "register_operand" "=r")
22068 [(match_operand:SI 1 "register_operand" "0")
22069 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22072 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22073 [(set_attr "type" "sselog1")
22074 (set_attr "prefix_rep" "1")
22075 (set_attr "prefix_extra" "1")
22076 (set_attr "mode" "SI")])
22078 (define_insn "sse4_2_crc32di"
22079 [(set (match_operand:DI 0 "register_operand" "=r")
22081 [(match_operand:DI 1 "register_operand" "0")
22082 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22084 "TARGET_SSE4_2 && TARGET_64BIT"
22085 "crc32q\t{%2, %0|%0, %2}"
22086 [(set_attr "type" "sselog1")
22087 (set_attr "prefix_rep" "1")
22088 (set_attr "prefix_extra" "1")
22089 (set_attr "mode" "DI")])
22093 (include "sync.md")