1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for SSE5 com* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_SSE5_INTRINSIC 150)
201 (UNSPEC_SSE5_UNSIGNED_CMP 151)
202 (UNSPEC_SSE5_TRUEFALSE 152)
203 (UNSPEC_SSE5_PERMUTE 153)
205 (UNSPEC_CVTPH2PS 155)
206 (UNSPEC_CVTPS2PH 156)
210 (UNSPEC_AESENCLAST 160)
212 (UNSPEC_AESDECLAST 162)
214 (UNSPEC_AESKEYGENASSIST 164)
222 (UNSPEC_VPERMIL2F128 168)
223 (UNSPEC_MASKLOAD 169)
224 (UNSPEC_MASKSTORE 170)
230 [(UNSPECV_BLOCKAGE 0)
231 (UNSPECV_STACK_PROBE 1)
243 (UNSPECV_PROLOGUE_USE 14)
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
252 ;; Constants to represent pcomtrue/pcomfalse variants
262 ;; Constants used in the SSE5 pperm instruction
264 [(PPERM_SRC 0x00) /* copy source */
265 (PPERM_INVERT 0x20) /* invert source */
266 (PPERM_REVERSE 0x40) /* bit reverse source */
267 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
268 (PPERM_ZERO 0x80) /* all 0's */
269 (PPERM_ONES 0xa0) /* all 1's */
270 (PPERM_SIGN 0xc0) /* propagate sign bit */
271 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
272 (PPERM_SRC1 0x00) /* use first source byte */
273 (PPERM_SRC2 0x10) /* use second source byte */
276 ;; Registers by name.
329 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
332 ;; In C guard expressions, put expressions which may be compile-time
333 ;; constants first. This allows for better optimization. For
334 ;; example, write "TARGET_64BIT && reload_completed", not
335 ;; "reload_completed && TARGET_64BIT".
339 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
341 (const (symbol_ref "ix86_schedule")))
343 ;; A basic instruction type. Refinements due to arguments to be
344 ;; provided in other attributes.
347 alu,alu1,negnot,imov,imovx,lea,
348 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
349 icmp,test,ibr,setcc,icmov,
350 push,pop,call,callv,leave,
352 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
353 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
354 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
356 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
357 (const_string "other"))
359 ;; Main data type used by the insn
361 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
362 (const_string "unknown"))
364 ;; The CPU unit operations uses.
365 (define_attr "unit" "integer,i387,sse,mmx,unknown"
366 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
367 (const_string "i387")
368 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
369 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
370 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
372 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
374 (eq_attr "type" "other")
375 (const_string "unknown")]
376 (const_string "integer")))
378 ;; The (bounding maximum) length of an instruction immediate.
379 (define_attr "length_immediate" ""
380 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
383 (eq_attr "unit" "i387,sse,mmx")
385 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
387 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
388 (eq_attr "type" "imov,test")
389 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
390 (eq_attr "type" "call")
391 (if_then_else (match_operand 0 "constant_call_address_operand" "")
394 (eq_attr "type" "callv")
395 (if_then_else (match_operand 1 "constant_call_address_operand" "")
398 ;; We don't know the size before shorten_branches. Expect
399 ;; the instruction to fit for better scheduling.
400 (eq_attr "type" "ibr")
403 (symbol_ref "/* Update immediate_length and other attributes! */
404 gcc_unreachable (),1")))
406 ;; The (bounding maximum) length of an instruction address.
407 (define_attr "length_address" ""
408 (cond [(eq_attr "type" "str,other,multi,fxch")
410 (and (eq_attr "type" "call")
411 (match_operand 0 "constant_call_address_operand" ""))
413 (and (eq_attr "type" "callv")
414 (match_operand 1 "constant_call_address_operand" ""))
417 (symbol_ref "ix86_attr_length_address_default (insn)")))
419 ;; Set when length prefix is used.
420 (define_attr "prefix_data16" ""
421 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
423 (eq_attr "mode" "HI")
425 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
430 ;; Set when string REP prefix is used.
431 (define_attr "prefix_rep" ""
432 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
434 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
439 ;; Set when 0f opcode prefix is used.
440 (define_attr "prefix_0f" ""
442 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
443 (eq_attr "unit" "sse,mmx"))
447 ;; Set when REX opcode prefix is used.
448 (define_attr "prefix_rex" ""
449 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
451 (and (eq_attr "mode" "DI")
452 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
453 (eq_attr "unit" "!mmx")))
455 (and (eq_attr "mode" "QI")
456 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
459 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
462 (and (eq_attr "type" "imovx")
463 (match_operand:QI 1 "ext_QIreg_operand" ""))
468 ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
469 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
470 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
471 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
472 (define_attr "prefix_extra" ""
473 (cond [(eq_attr "type" "ssemuladd,sse4arg")
475 (eq_attr "type" "sseiadd1,ssecvt1")
480 ;; Prefix used: original, VEX or maybe VEX.
481 (define_attr "prefix" "orig,vex,maybe_vex"
482 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
484 (const_string "orig")))
486 ;; VEX W bit is used.
487 (define_attr "prefix_vex_w" "" (const_int 0))
489 ;; The length of VEX prefix
490 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
491 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
492 ;; still prefix_0f 1, with prefix_extra 1.
493 (define_attr "length_vex" ""
494 (if_then_else (and (eq_attr "prefix_0f" "1")
495 (eq_attr "prefix_extra" "0"))
496 (if_then_else (eq_attr "prefix_vex_w" "1")
497 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
498 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
499 (if_then_else (eq_attr "prefix_vex_w" "1")
500 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
501 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
503 ;; Set when modrm byte is used.
504 (define_attr "modrm" ""
505 (cond [(eq_attr "type" "str,leave")
507 (eq_attr "unit" "i387")
509 (and (eq_attr "type" "incdec")
510 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
511 (ior (match_operand:SI 1 "register_operand" "")
512 (match_operand:HI 1 "register_operand" ""))))
514 (and (eq_attr "type" "push")
515 (not (match_operand 1 "memory_operand" "")))
517 (and (eq_attr "type" "pop")
518 (not (match_operand 0 "memory_operand" "")))
520 (and (eq_attr "type" "imov")
521 (and (not (eq_attr "mode" "DI"))
522 (ior (and (match_operand 0 "register_operand" "")
523 (match_operand 1 "immediate_operand" ""))
524 (ior (and (match_operand 0 "ax_reg_operand" "")
525 (match_operand 1 "memory_displacement_only_operand" ""))
526 (and (match_operand 0 "memory_displacement_only_operand" "")
527 (match_operand 1 "ax_reg_operand" ""))))))
529 (and (eq_attr "type" "call")
530 (match_operand 0 "constant_call_address_operand" ""))
532 (and (eq_attr "type" "callv")
533 (match_operand 1 "constant_call_address_operand" ""))
535 (and (eq_attr "type" "alu,alu1,icmp,test")
536 (match_operand 0 "ax_reg_operand" ""))
537 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
541 ;; The (bounding maximum) length of an instruction in bytes.
542 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
543 ;; Later we may want to split them and compute proper length as for
545 (define_attr "length" ""
546 (cond [(eq_attr "type" "other,multi,fistp,frndint")
548 (eq_attr "type" "fcmp")
550 (eq_attr "unit" "i387")
552 (plus (attr "prefix_data16")
553 (attr "length_address")))
554 (ior (eq_attr "prefix" "vex")
555 (and (eq_attr "prefix" "maybe_vex")
556 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
557 (plus (attr "length_vex")
558 (plus (attr "length_immediate")
560 (attr "length_address"))))]
561 (plus (plus (attr "modrm")
562 (plus (attr "prefix_0f")
563 (plus (attr "prefix_rex")
564 (plus (attr "prefix_extra")
566 (plus (attr "prefix_rep")
567 (plus (attr "prefix_data16")
568 (plus (attr "length_immediate")
569 (attr "length_address")))))))
571 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
572 ;; `store' if there is a simple memory reference therein, or `unknown'
573 ;; if the instruction is complex.
575 (define_attr "memory" "none,load,store,both,unknown"
576 (cond [(eq_attr "type" "other,multi,str")
577 (const_string "unknown")
578 (eq_attr "type" "lea,fcmov,fpspc")
579 (const_string "none")
580 (eq_attr "type" "fistp,leave")
581 (const_string "both")
582 (eq_attr "type" "frndint")
583 (const_string "load")
584 (eq_attr "type" "push")
585 (if_then_else (match_operand 1 "memory_operand" "")
586 (const_string "both")
587 (const_string "store"))
588 (eq_attr "type" "pop")
589 (if_then_else (match_operand 0 "memory_operand" "")
590 (const_string "both")
591 (const_string "load"))
592 (eq_attr "type" "setcc")
593 (if_then_else (match_operand 0 "memory_operand" "")
594 (const_string "store")
595 (const_string "none"))
596 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
597 (if_then_else (ior (match_operand 0 "memory_operand" "")
598 (match_operand 1 "memory_operand" ""))
599 (const_string "load")
600 (const_string "none"))
601 (eq_attr "type" "ibr")
602 (if_then_else (match_operand 0 "memory_operand" "")
603 (const_string "load")
604 (const_string "none"))
605 (eq_attr "type" "call")
606 (if_then_else (match_operand 0 "constant_call_address_operand" "")
607 (const_string "none")
608 (const_string "load"))
609 (eq_attr "type" "callv")
610 (if_then_else (match_operand 1 "constant_call_address_operand" "")
611 (const_string "none")
612 (const_string "load"))
613 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "both")
616 (and (match_operand 0 "memory_operand" "")
617 (match_operand 1 "memory_operand" ""))
618 (const_string "both")
619 (match_operand 0 "memory_operand" "")
620 (const_string "store")
621 (match_operand 1 "memory_operand" "")
622 (const_string "load")
624 "!alu1,negnot,ishift1,
625 imov,imovx,icmp,test,bitmanip,
627 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
628 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
629 (match_operand 2 "memory_operand" ""))
630 (const_string "load")
631 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
632 (match_operand 3 "memory_operand" ""))
633 (const_string "load")
635 (const_string "none")))
637 ;; Indicates if an instruction has both an immediate and a displacement.
639 (define_attr "imm_disp" "false,true,unknown"
640 (cond [(eq_attr "type" "other,multi")
641 (const_string "unknown")
642 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
643 (and (match_operand 0 "memory_displacement_operand" "")
644 (match_operand 1 "immediate_operand" "")))
645 (const_string "true")
646 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
647 (and (match_operand 0 "memory_displacement_operand" "")
648 (match_operand 2 "immediate_operand" "")))
649 (const_string "true")
651 (const_string "false")))
653 ;; Indicates if an FP operation has an integer source.
655 (define_attr "fp_int_src" "false,true"
656 (const_string "false"))
658 ;; Defines rounding mode of an FP operation.
660 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
661 (const_string "any"))
663 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
664 (define_attr "use_carry" "0,1" (const_string "0"))
666 ;; Define attribute to indicate unaligned ssemov insns
667 (define_attr "movu" "0,1" (const_string "0"))
669 ;; Describe a user's asm statement.
670 (define_asm_attributes
671 [(set_attr "length" "128")
672 (set_attr "type" "multi")])
674 ;; All integer comparison codes.
675 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
677 ;; All floating-point comparison codes.
678 (define_code_iterator fp_cond [unordered ordered
679 uneq unge ungt unle unlt ltgt ])
681 (define_code_iterator plusminus [plus minus])
683 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
685 ;; Base name for define_insn
686 (define_code_attr plusminus_insn
687 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
688 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
690 ;; Base name for insn mnemonic.
691 (define_code_attr plusminus_mnemonic
692 [(plus "add") (ss_plus "adds") (us_plus "addus")
693 (minus "sub") (ss_minus "subs") (us_minus "subus")])
695 ;; Mark commutative operators as such in constraints.
696 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
697 (minus "") (ss_minus "") (us_minus "")])
699 ;; Mapping of signed max and min
700 (define_code_iterator smaxmin [smax smin])
702 ;; Mapping of unsigned max and min
703 (define_code_iterator umaxmin [umax umin])
705 ;; Mapping of signed/unsigned max and min
706 (define_code_iterator maxmin [smax smin umax umin])
708 ;; Base name for integer and FP insn mnemonic
709 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
710 (umax "maxu") (umin "minu")])
711 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
713 ;; Mapping of parallel logic operators
714 (define_code_iterator plogic [and ior xor])
716 ;; Base name for insn mnemonic.
717 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
725 ;; All single word integer modes.
726 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
728 ;; Single word integer modes without QImode.
729 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
731 ;; Instruction suffix for integer modes.
732 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
734 ;; Register class for integer modes.
735 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
737 ;; Immediate operand constraint for integer modes.
738 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
740 ;; General operand predicate for integer modes.
741 (define_mode_attr general_operand
742 [(QI "general_operand")
743 (HI "general_operand")
744 (SI "general_operand")
745 (DI "x86_64_general_operand")])
747 ;; SSE and x87 SFmode and DFmode floating point modes
748 (define_mode_iterator MODEF [SF DF])
750 ;; All x87 floating point modes
751 (define_mode_iterator X87MODEF [SF DF XF])
753 ;; All integer modes handled by x87 fisttp operator.
754 (define_mode_iterator X87MODEI [HI SI DI])
756 ;; All integer modes handled by integer x87 operators.
757 (define_mode_iterator X87MODEI12 [HI SI])
759 ;; All integer modes handled by SSE cvtts?2si* operators.
760 (define_mode_iterator SSEMODEI24 [SI DI])
762 ;; SSE asm suffix for floating point modes
763 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
765 ;; SSE vector mode corresponding to a scalar mode
766 (define_mode_attr ssevecmode
767 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
769 ;; Instruction suffix for REX 64bit operators.
770 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
772 ;; This mode iterator allows :P to be used for patterns that operate on
773 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
774 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
777 ;; Scheduling descriptions
779 (include "pentium.md")
782 (include "athlon.md")
787 ;; Operand and operator predicates and constraints
789 (include "predicates.md")
790 (include "constraints.md")
793 ;; Compare and branch/compare and store instructions.
795 (define_expand "cbranchti4"
796 [(set (reg:CC FLAGS_REG)
797 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
798 (match_operand:TI 2 "x86_64_general_operand" "")))
799 (set (pc) (if_then_else
800 (match_operator 0 "comparison_operator"
803 (label_ref (match_operand 3 "" ""))
807 if (MEM_P (operands[1]) && MEM_P (operands[2]))
808 operands[1] = force_reg (TImode, operands[1]);
809 ix86_compare_op0 = operands[1];
810 ix86_compare_op1 = operands[2];
811 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
815 (define_expand "cbranchdi4"
816 [(set (reg:CC FLAGS_REG)
817 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
818 (match_operand:DI 2 "x86_64_general_operand" "")))
819 (set (pc) (if_then_else
820 (match_operator 0 "comparison_operator"
823 (label_ref (match_operand 3 "" ""))
827 if (MEM_P (operands[1]) && MEM_P (operands[2]))
828 operands[1] = force_reg (DImode, operands[1]);
829 ix86_compare_op0 = operands[1];
830 ix86_compare_op1 = operands[2];
831 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
835 (define_expand "cstoredi4"
836 [(set (reg:CC FLAGS_REG)
837 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
838 (match_operand:DI 3 "x86_64_general_operand" "")))
839 (set (match_operand:QI 0 "register_operand" "")
840 (match_operator 1 "comparison_operator"
845 if (MEM_P (operands[2]) && MEM_P (operands[3]))
846 operands[2] = force_reg (DImode, operands[2]);
847 ix86_compare_op0 = operands[2];
848 ix86_compare_op1 = operands[3];
849 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
853 (define_expand "cbranchsi4"
854 [(set (reg:CC FLAGS_REG)
855 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
856 (match_operand:SI 2 "general_operand" "")))
857 (set (pc) (if_then_else
858 (match_operator 0 "comparison_operator"
861 (label_ref (match_operand 3 "" ""))
865 if (MEM_P (operands[1]) && MEM_P (operands[2]))
866 operands[1] = force_reg (SImode, operands[1]);
867 ix86_compare_op0 = operands[1];
868 ix86_compare_op1 = operands[2];
869 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
873 (define_expand "cstoresi4"
874 [(set (reg:CC FLAGS_REG)
875 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
876 (match_operand:SI 3 "general_operand" "")))
877 (set (match_operand:QI 0 "register_operand" "")
878 (match_operator 1 "comparison_operator"
883 if (MEM_P (operands[2]) && MEM_P (operands[3]))
884 operands[2] = force_reg (SImode, operands[2]);
885 ix86_compare_op0 = operands[2];
886 ix86_compare_op1 = operands[3];
887 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
891 (define_expand "cbranchhi4"
892 [(set (reg:CC FLAGS_REG)
893 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
894 (match_operand:HI 2 "general_operand" "")))
895 (set (pc) (if_then_else
896 (match_operator 0 "comparison_operator"
899 (label_ref (match_operand 3 "" ""))
903 if (MEM_P (operands[1]) && MEM_P (operands[2]))
904 operands[1] = force_reg (HImode, operands[1]);
905 ix86_compare_op0 = operands[1];
906 ix86_compare_op1 = operands[2];
907 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
911 (define_expand "cstorehi4"
912 [(set (reg:CC FLAGS_REG)
913 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
914 (match_operand:HI 3 "general_operand" "")))
915 (set (match_operand:QI 0 "register_operand" "")
916 (match_operator 1 "comparison_operator"
921 if (MEM_P (operands[2]) && MEM_P (operands[3]))
922 operands[2] = force_reg (HImode, operands[2]);
923 ix86_compare_op0 = operands[2];
924 ix86_compare_op1 = operands[3];
925 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
930 (define_expand "cbranchqi4"
931 [(set (reg:CC FLAGS_REG)
932 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
933 (match_operand:QI 2 "general_operand" "")))
934 (set (pc) (if_then_else
935 (match_operator 0 "comparison_operator"
938 (label_ref (match_operand 3 "" ""))
942 if (MEM_P (operands[1]) && MEM_P (operands[2]))
943 operands[1] = force_reg (QImode, operands[1]);
944 ix86_compare_op0 = operands[1];
945 ix86_compare_op1 = operands[2];
946 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
951 (define_expand "cstoreqi4"
952 [(set (reg:CC FLAGS_REG)
953 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
954 (match_operand:QI 3 "general_operand" "")))
955 (set (match_operand:QI 0 "register_operand" "")
956 (match_operator 1 "comparison_operator"
961 if (MEM_P (operands[2]) && MEM_P (operands[3]))
962 operands[2] = force_reg (QImode, operands[2]);
963 ix86_compare_op0 = operands[2];
964 ix86_compare_op1 = operands[3];
965 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
970 (define_insn "cmpdi_ccno_1_rex64"
971 [(set (reg FLAGS_REG)
972 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
973 (match_operand:DI 1 "const0_operand" "")))]
974 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
977 cmp{q}\t{%1, %0|%0, %1}"
978 [(set_attr "type" "test,icmp")
979 (set_attr "length_immediate" "0,1")
980 (set_attr "mode" "DI")])
982 (define_insn "*cmpdi_minus_1_rex64"
983 [(set (reg FLAGS_REG)
984 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
985 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
987 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
988 "cmp{q}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "icmp")
990 (set_attr "mode" "DI")])
992 (define_expand "cmpdi_1_rex64"
993 [(set (reg:CC FLAGS_REG)
994 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
995 (match_operand:DI 1 "general_operand" "")))]
999 (define_insn "cmpdi_1_insn_rex64"
1000 [(set (reg FLAGS_REG)
1001 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1002 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1003 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004 "cmp{q}\t{%1, %0|%0, %1}"
1005 [(set_attr "type" "icmp")
1006 (set_attr "mode" "DI")])
1009 (define_insn "*cmpsi_ccno_1"
1010 [(set (reg FLAGS_REG)
1011 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1012 (match_operand:SI 1 "const0_operand" "")))]
1013 "ix86_match_ccmode (insn, CCNOmode)"
1016 cmp{l}\t{%1, %0|%0, %1}"
1017 [(set_attr "type" "test,icmp")
1018 (set_attr "length_immediate" "0,1")
1019 (set_attr "mode" "SI")])
1021 (define_insn "*cmpsi_minus_1"
1022 [(set (reg FLAGS_REG)
1023 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1024 (match_operand:SI 1 "general_operand" "ri,mr"))
1026 "ix86_match_ccmode (insn, CCGOCmode)"
1027 "cmp{l}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "icmp")
1029 (set_attr "mode" "SI")])
1031 (define_expand "cmpsi_1"
1032 [(set (reg:CC FLAGS_REG)
1033 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1034 (match_operand:SI 1 "general_operand" "")))]
1038 (define_insn "*cmpsi_1_insn"
1039 [(set (reg FLAGS_REG)
1040 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1041 (match_operand:SI 1 "general_operand" "ri,mr")))]
1042 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1043 && ix86_match_ccmode (insn, CCmode)"
1044 "cmp{l}\t{%1, %0|%0, %1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "mode" "SI")])
1048 (define_insn "*cmphi_ccno_1"
1049 [(set (reg FLAGS_REG)
1050 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1051 (match_operand:HI 1 "const0_operand" "")))]
1052 "ix86_match_ccmode (insn, CCNOmode)"
1055 cmp{w}\t{%1, %0|%0, %1}"
1056 [(set_attr "type" "test,icmp")
1057 (set_attr "length_immediate" "0,1")
1058 (set_attr "mode" "HI")])
1060 (define_insn "*cmphi_minus_1"
1061 [(set (reg FLAGS_REG)
1062 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1063 (match_operand:HI 1 "general_operand" "rn,mr"))
1065 "ix86_match_ccmode (insn, CCGOCmode)"
1066 "cmp{w}\t{%1, %0|%0, %1}"
1067 [(set_attr "type" "icmp")
1068 (set_attr "mode" "HI")])
1070 (define_insn "*cmphi_1"
1071 [(set (reg FLAGS_REG)
1072 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1073 (match_operand:HI 1 "general_operand" "rn,mr")))]
1074 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1075 && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{w}\t{%1, %0|%0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "mode" "HI")])
1080 (define_insn "*cmpqi_ccno_1"
1081 [(set (reg FLAGS_REG)
1082 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1083 (match_operand:QI 1 "const0_operand" "")))]
1084 "ix86_match_ccmode (insn, CCNOmode)"
1087 cmp{b}\t{$0, %0|%0, 0}"
1088 [(set_attr "type" "test,icmp")
1089 (set_attr "length_immediate" "0,1")
1090 (set_attr "mode" "QI")])
1092 (define_insn "*cmpqi_1"
1093 [(set (reg FLAGS_REG)
1094 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1095 (match_operand:QI 1 "general_operand" "qn,mq")))]
1096 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1097 && ix86_match_ccmode (insn, CCmode)"
1098 "cmp{b}\t{%1, %0|%0, %1}"
1099 [(set_attr "type" "icmp")
1100 (set_attr "mode" "QI")])
1102 (define_insn "*cmpqi_minus_1"
1103 [(set (reg FLAGS_REG)
1104 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1105 (match_operand:QI 1 "general_operand" "qn,mq"))
1107 "ix86_match_ccmode (insn, CCGOCmode)"
1108 "cmp{b}\t{%1, %0|%0, %1}"
1109 [(set_attr "type" "icmp")
1110 (set_attr "mode" "QI")])
1112 (define_insn "*cmpqi_ext_1"
1113 [(set (reg FLAGS_REG)
1115 (match_operand:QI 0 "general_operand" "Qm")
1118 (match_operand 1 "ext_register_operand" "Q")
1120 (const_int 8)) 0)))]
1121 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1122 "cmp{b}\t{%h1, %0|%0, %h1}"
1123 [(set_attr "type" "icmp")
1124 (set_attr "mode" "QI")])
1126 (define_insn "*cmpqi_ext_1_rex64"
1127 [(set (reg FLAGS_REG)
1129 (match_operand:QI 0 "register_operand" "Q")
1132 (match_operand 1 "ext_register_operand" "Q")
1134 (const_int 8)) 0)))]
1135 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1136 "cmp{b}\t{%h1, %0|%0, %h1}"
1137 [(set_attr "type" "icmp")
1138 (set_attr "mode" "QI")])
1140 (define_insn "*cmpqi_ext_2"
1141 [(set (reg FLAGS_REG)
1145 (match_operand 0 "ext_register_operand" "Q")
1148 (match_operand:QI 1 "const0_operand" "")))]
1149 "ix86_match_ccmode (insn, CCNOmode)"
1151 [(set_attr "type" "test")
1152 (set_attr "length_immediate" "0")
1153 (set_attr "mode" "QI")])
1155 (define_expand "cmpqi_ext_3"
1156 [(set (reg:CC FLAGS_REG)
1160 (match_operand 0 "ext_register_operand" "")
1163 (match_operand:QI 1 "general_operand" "")))]
1167 (define_insn "cmpqi_ext_3_insn"
1168 [(set (reg FLAGS_REG)
1172 (match_operand 0 "ext_register_operand" "Q")
1175 (match_operand:QI 1 "general_operand" "Qmn")))]
1176 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1177 "cmp{b}\t{%1, %h0|%h0, %1}"
1178 [(set_attr "type" "icmp")
1179 (set_attr "modrm" "1")
1180 (set_attr "mode" "QI")])
1182 (define_insn "cmpqi_ext_3_insn_rex64"
1183 [(set (reg FLAGS_REG)
1187 (match_operand 0 "ext_register_operand" "Q")
1190 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1191 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1192 "cmp{b}\t{%1, %h0|%h0, %1}"
1193 [(set_attr "type" "icmp")
1194 (set_attr "modrm" "1")
1195 (set_attr "mode" "QI")])
1197 (define_insn "*cmpqi_ext_4"
1198 [(set (reg FLAGS_REG)
1202 (match_operand 0 "ext_register_operand" "Q")
1207 (match_operand 1 "ext_register_operand" "Q")
1209 (const_int 8)) 0)))]
1210 "ix86_match_ccmode (insn, CCmode)"
1211 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1212 [(set_attr "type" "icmp")
1213 (set_attr "mode" "QI")])
1215 ;; These implement float point compares.
1216 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1217 ;; which would allow mix and match FP modes on the compares. Which is what
1218 ;; the old patterns did, but with many more of them.
1220 (define_expand "cbranchxf4"
1221 [(set (reg:CC FLAGS_REG)
1222 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1223 (match_operand:XF 2 "nonmemory_operand" "")))
1224 (set (pc) (if_then_else
1225 (match_operator 0 "ix86_fp_comparison_operator"
1228 (label_ref (match_operand 3 "" ""))
1232 ix86_compare_op0 = operands[1];
1233 ix86_compare_op1 = operands[2];
1234 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1238 (define_expand "cstorexf4"
1239 [(set (reg:CC FLAGS_REG)
1240 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1241 (match_operand:XF 3 "nonmemory_operand" "")))
1242 (set (match_operand:QI 0 "register_operand" "")
1243 (match_operator 1 "ix86_fp_comparison_operator"
1248 ix86_compare_op0 = operands[2];
1249 ix86_compare_op1 = operands[3];
1250 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1254 (define_expand "cbranch<mode>4"
1255 [(set (reg:CC FLAGS_REG)
1256 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1257 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1258 (set (pc) (if_then_else
1259 (match_operator 0 "ix86_fp_comparison_operator"
1262 (label_ref (match_operand 3 "" ""))
1264 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1266 ix86_compare_op0 = operands[1];
1267 ix86_compare_op1 = operands[2];
1268 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1272 (define_expand "cstore<mode>4"
1273 [(set (reg:CC FLAGS_REG)
1274 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1275 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1276 (set (match_operand:QI 0 "register_operand" "")
1277 (match_operator 1 "ix86_fp_comparison_operator"
1280 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1282 ix86_compare_op0 = operands[2];
1283 ix86_compare_op1 = operands[3];
1284 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1288 (define_expand "cbranchcc4"
1289 [(set (pc) (if_then_else
1290 (match_operator 0 "comparison_operator"
1291 [(match_operand 1 "flags_reg_operand" "")
1292 (match_operand 2 "const0_operand" "")])
1293 (label_ref (match_operand 3 "" ""))
1297 ix86_compare_op0 = operands[1];
1298 ix86_compare_op1 = operands[2];
1299 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1303 (define_expand "cstorecc4"
1304 [(set (match_operand:QI 0 "register_operand" "")
1305 (match_operator 1 "comparison_operator"
1306 [(match_operand 2 "flags_reg_operand" "")
1307 (match_operand 3 "const0_operand" "")]))]
1310 ix86_compare_op0 = operands[2];
1311 ix86_compare_op1 = operands[3];
1312 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1317 ;; FP compares, step 1:
1318 ;; Set the FP condition codes.
1320 ;; CCFPmode compare with exceptions
1321 ;; CCFPUmode compare with no exceptions
1323 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1324 ;; used to manage the reg stack popping would not be preserved.
1326 (define_insn "*cmpfp_0"
1327 [(set (match_operand:HI 0 "register_operand" "=a")
1330 (match_operand 1 "register_operand" "f")
1331 (match_operand 2 "const0_operand" ""))]
1333 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1334 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1335 "* return output_fp_compare (insn, operands, 0, 0);"
1336 [(set_attr "type" "multi")
1337 (set_attr "unit" "i387")
1339 (cond [(match_operand:SF 1 "" "")
1341 (match_operand:DF 1 "" "")
1344 (const_string "XF")))])
1346 (define_insn_and_split "*cmpfp_0_cc"
1347 [(set (reg:CCFP FLAGS_REG)
1349 (match_operand 1 "register_operand" "f")
1350 (match_operand 2 "const0_operand" "")))
1351 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1353 && TARGET_SAHF && !TARGET_CMOVE
1354 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1356 "&& reload_completed"
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1367 (cond [(match_operand:SF 1 "" "")
1369 (match_operand:DF 1 "" "")
1372 (const_string "XF")))])
1374 (define_insn "*cmpfp_xf"
1375 [(set (match_operand:HI 0 "register_operand" "=a")
1378 (match_operand:XF 1 "register_operand" "f")
1379 (match_operand:XF 2 "register_operand" "f"))]
1382 "* return output_fp_compare (insn, operands, 0, 0);"
1383 [(set_attr "type" "multi")
1384 (set_attr "unit" "i387")
1385 (set_attr "mode" "XF")])
1387 (define_insn_and_split "*cmpfp_xf_cc"
1388 [(set (reg:CCFP FLAGS_REG)
1390 (match_operand:XF 1 "register_operand" "f")
1391 (match_operand:XF 2 "register_operand" "f")))
1392 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 && TARGET_SAHF && !TARGET_CMOVE"
1396 "&& reload_completed"
1399 [(compare:CCFP (match_dup 1)(match_dup 2))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "mode" "XF")])
1408 (define_insn "*cmpfp_<mode>"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1412 (match_operand:MODEF 1 "register_operand" "f")
1413 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1416 "* return output_fp_compare (insn, operands, 0, 0);"
1417 [(set_attr "type" "multi")
1418 (set_attr "unit" "i387")
1419 (set_attr "mode" "<MODE>")])
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422 [(set (reg:CCFP FLAGS_REG)
1424 (match_operand:MODEF 1 "register_operand" "f")
1425 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1426 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1428 && TARGET_SAHF && !TARGET_CMOVE"
1430 "&& reload_completed"
1433 [(compare:CCFP (match_dup 1)(match_dup 2))]
1435 (set (reg:CC FLAGS_REG)
1436 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1438 [(set_attr "type" "multi")
1439 (set_attr "unit" "i387")
1440 (set_attr "mode" "<MODE>")])
1442 (define_insn "*cmpfp_u"
1443 [(set (match_operand:HI 0 "register_operand" "=a")
1446 (match_operand 1 "register_operand" "f")
1447 (match_operand 2 "register_operand" "f"))]
1449 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1450 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1451 "* return output_fp_compare (insn, operands, 0, 1);"
1452 [(set_attr "type" "multi")
1453 (set_attr "unit" "i387")
1455 (cond [(match_operand:SF 1 "" "")
1457 (match_operand:DF 1 "" "")
1460 (const_string "XF")))])
1462 (define_insn_and_split "*cmpfp_u_cc"
1463 [(set (reg:CCFPU FLAGS_REG)
1465 (match_operand 1 "register_operand" "f")
1466 (match_operand 2 "register_operand" "f")))
1467 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1469 && TARGET_SAHF && !TARGET_CMOVE
1470 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1472 "&& reload_completed"
1475 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1477 (set (reg:CC FLAGS_REG)
1478 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1480 [(set_attr "type" "multi")
1481 (set_attr "unit" "i387")
1483 (cond [(match_operand:SF 1 "" "")
1485 (match_operand:DF 1 "" "")
1488 (const_string "XF")))])
1490 (define_insn "*cmpfp_<mode>"
1491 [(set (match_operand:HI 0 "register_operand" "=a")
1494 (match_operand 1 "register_operand" "f")
1495 (match_operator 3 "float_operator"
1496 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1498 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1499 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1500 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1501 "* return output_fp_compare (insn, operands, 0, 0);"
1502 [(set_attr "type" "multi")
1503 (set_attr "unit" "i387")
1504 (set_attr "fp_int_src" "true")
1505 (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmpfp_<mode>_cc"
1508 [(set (reg:CCFP FLAGS_REG)
1510 (match_operand 1 "register_operand" "f")
1511 (match_operator 3 "float_operator"
1512 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1513 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1515 && TARGET_SAHF && !TARGET_CMOVE
1516 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1517 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1519 "&& reload_completed"
1524 (match_op_dup 3 [(match_dup 2)]))]
1526 (set (reg:CC FLAGS_REG)
1527 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1529 [(set_attr "type" "multi")
1530 (set_attr "unit" "i387")
1531 (set_attr "fp_int_src" "true")
1532 (set_attr "mode" "<MODE>")])
1534 ;; FP compares, step 2
1535 ;; Move the fpsw to ax.
1537 (define_insn "x86_fnstsw_1"
1538 [(set (match_operand:HI 0 "register_operand" "=a")
1539 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1542 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1543 (set_attr "mode" "SI")
1544 (set_attr "unit" "i387")])
1546 ;; FP compares, step 3
1547 ;; Get ax into flags, general case.
1549 (define_insn "x86_sahf_1"
1550 [(set (reg:CC FLAGS_REG)
1551 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1555 #ifdef HAVE_AS_IX86_SAHF
1558 return ".byte\t0x9e";
1561 [(set_attr "length" "1")
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "mode" "SI")])
1566 ;; Pentium Pro can do steps 1 through 3 in one go.
1567 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1568 (define_insn "*cmpfp_i_mixed"
1569 [(set (reg:CCFP FLAGS_REG)
1570 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1571 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1572 "TARGET_MIX_SSE_I387
1573 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1575 "* return output_fp_compare (insn, operands, 1, 0);"
1576 [(set_attr "type" "fcmp,ssecomi")
1577 (set_attr "prefix" "orig,maybe_vex")
1579 (if_then_else (match_operand:SF 1 "" "")
1581 (const_string "DF")))
1582 (set (attr "prefix_rep")
1583 (if_then_else (eq_attr "type" "ssecomi")
1585 (const_string "*")))
1586 (set (attr "prefix_data16")
1587 (cond [(eq_attr "type" "fcmp")
1589 (eq_attr "mode" "DF")
1592 (const_string "0")))
1593 (set_attr "athlon_decode" "vector")
1594 (set_attr "amdfam10_decode" "direct")])
1596 (define_insn "*cmpfp_i_sse"
1597 [(set (reg:CCFP FLAGS_REG)
1598 (compare:CCFP (match_operand 0 "register_operand" "x")
1599 (match_operand 1 "nonimmediate_operand" "xm")))]
1601 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1602 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1603 "* return output_fp_compare (insn, operands, 1, 0);"
1604 [(set_attr "type" "ssecomi")
1605 (set_attr "prefix" "maybe_vex")
1607 (if_then_else (match_operand:SF 1 "" "")
1609 (const_string "DF")))
1610 (set_attr "prefix_rep" "0")
1611 (set (attr "prefix_data16")
1612 (if_then_else (eq_attr "mode" "DF")
1614 (const_string "0")))
1615 (set_attr "athlon_decode" "vector")
1616 (set_attr "amdfam10_decode" "direct")])
1618 (define_insn "*cmpfp_i_i387"
1619 [(set (reg:CCFP FLAGS_REG)
1620 (compare:CCFP (match_operand 0 "register_operand" "f")
1621 (match_operand 1 "register_operand" "f")))]
1622 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1624 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1625 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1626 "* return output_fp_compare (insn, operands, 1, 0);"
1627 [(set_attr "type" "fcmp")
1629 (cond [(match_operand:SF 1 "" "")
1631 (match_operand:DF 1 "" "")
1634 (const_string "XF")))
1635 (set_attr "athlon_decode" "vector")
1636 (set_attr "amdfam10_decode" "direct")])
1638 (define_insn "*cmpfp_iu_mixed"
1639 [(set (reg:CCFPU FLAGS_REG)
1640 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1641 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1642 "TARGET_MIX_SSE_I387
1643 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1644 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1645 "* return output_fp_compare (insn, operands, 1, 1);"
1646 [(set_attr "type" "fcmp,ssecomi")
1647 (set_attr "prefix" "orig,maybe_vex")
1649 (if_then_else (match_operand:SF 1 "" "")
1651 (const_string "DF")))
1652 (set (attr "prefix_rep")
1653 (if_then_else (eq_attr "type" "ssecomi")
1655 (const_string "*")))
1656 (set (attr "prefix_data16")
1657 (cond [(eq_attr "type" "fcmp")
1659 (eq_attr "mode" "DF")
1662 (const_string "0")))
1663 (set_attr "athlon_decode" "vector")
1664 (set_attr "amdfam10_decode" "direct")])
1666 (define_insn "*cmpfp_iu_sse"
1667 [(set (reg:CCFPU FLAGS_REG)
1668 (compare:CCFPU (match_operand 0 "register_operand" "x")
1669 (match_operand 1 "nonimmediate_operand" "xm")))]
1671 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1672 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1673 "* return output_fp_compare (insn, operands, 1, 1);"
1674 [(set_attr "type" "ssecomi")
1675 (set_attr "prefix" "maybe_vex")
1677 (if_then_else (match_operand:SF 1 "" "")
1679 (const_string "DF")))
1680 (set_attr "prefix_rep" "0")
1681 (set (attr "prefix_data16")
1682 (if_then_else (eq_attr "mode" "DF")
1684 (const_string "0")))
1685 (set_attr "athlon_decode" "vector")
1686 (set_attr "amdfam10_decode" "direct")])
1688 (define_insn "*cmpfp_iu_387"
1689 [(set (reg:CCFPU FLAGS_REG)
1690 (compare:CCFPU (match_operand 0 "register_operand" "f")
1691 (match_operand 1 "register_operand" "f")))]
1692 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1694 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1695 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1696 "* return output_fp_compare (insn, operands, 1, 1);"
1697 [(set_attr "type" "fcmp")
1699 (cond [(match_operand:SF 1 "" "")
1701 (match_operand:DF 1 "" "")
1704 (const_string "XF")))
1705 (set_attr "athlon_decode" "vector")
1706 (set_attr "amdfam10_decode" "direct")])
1708 ;; Move instructions.
1710 ;; General case of fullword move.
1712 (define_expand "movsi"
1713 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1714 (match_operand:SI 1 "general_operand" ""))]
1716 "ix86_expand_move (SImode, operands); DONE;")
1718 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1721 ;; %%% We don't use a post-inc memory reference because x86 is not a
1722 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1723 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1724 ;; targets without our curiosities, and it is just as easy to represent
1725 ;; this differently.
1727 (define_insn "*pushsi2"
1728 [(set (match_operand:SI 0 "push_operand" "=<")
1729 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1732 [(set_attr "type" "push")
1733 (set_attr "mode" "SI")])
1735 ;; For 64BIT abi we always round up to 8 bytes.
1736 (define_insn "*pushsi2_rex64"
1737 [(set (match_operand:SI 0 "push_operand" "=X")
1738 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1741 [(set_attr "type" "push")
1742 (set_attr "mode" "SI")])
1744 (define_insn "*pushsi2_prologue"
1745 [(set (match_operand:SI 0 "push_operand" "=<")
1746 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1747 (clobber (mem:BLK (scratch)))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*popsi1_epilogue"
1754 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1755 (mem:SI (reg:SI SP_REG)))
1756 (set (reg:SI SP_REG)
1757 (plus:SI (reg:SI SP_REG) (const_int 4)))
1758 (clobber (mem:BLK (scratch)))]
1761 [(set_attr "type" "pop")
1762 (set_attr "mode" "SI")])
1764 (define_insn "popsi1"
1765 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1766 (mem:SI (reg:SI SP_REG)))
1767 (set (reg:SI SP_REG)
1768 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "SI")])
1774 (define_insn "*movsi_xor"
1775 [(set (match_operand:SI 0 "register_operand" "=r")
1776 (match_operand:SI 1 "const0_operand" ""))
1777 (clobber (reg:CC FLAGS_REG))]
1780 [(set_attr "type" "alu1")
1781 (set_attr "mode" "SI")
1782 (set_attr "length_immediate" "0")])
1784 (define_insn "*movsi_or"
1785 [(set (match_operand:SI 0 "register_operand" "=r")
1786 (match_operand:SI 1 "immediate_operand" "i"))
1787 (clobber (reg:CC FLAGS_REG))]
1789 && operands[1] == constm1_rtx"
1791 operands[1] = constm1_rtx;
1792 return "or{l}\t{%1, %0|%0, %1}";
1794 [(set_attr "type" "alu1")
1795 (set_attr "mode" "SI")
1796 (set_attr "length_immediate" "1")])
1798 (define_insn "*movsi_1"
1799 [(set (match_operand:SI 0 "nonimmediate_operand"
1800 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1801 (match_operand:SI 1 "general_operand"
1802 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1803 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1805 switch (get_attr_type (insn))
1808 if (get_attr_mode (insn) == MODE_TI)
1809 return "%vpxor\t%0, %d0";
1810 return "%vxorps\t%0, %d0";
1813 switch (get_attr_mode (insn))
1816 return "%vmovdqa\t{%1, %0|%0, %1}";
1818 return "%vmovaps\t{%1, %0|%0, %1}";
1820 return "%vmovd\t{%1, %0|%0, %1}";
1822 return "%vmovss\t{%1, %0|%0, %1}";
1828 return "pxor\t%0, %0";
1831 if (get_attr_mode (insn) == MODE_DI)
1832 return "movq\t{%1, %0|%0, %1}";
1833 return "movd\t{%1, %0|%0, %1}";
1836 return "lea{l}\t{%1, %0|%0, %1}";
1839 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1840 return "mov{l}\t{%1, %0|%0, %1}";
1844 (cond [(eq_attr "alternative" "2")
1845 (const_string "mmx")
1846 (eq_attr "alternative" "3,4,5")
1847 (const_string "mmxmov")
1848 (eq_attr "alternative" "6")
1849 (const_string "sselog1")
1850 (eq_attr "alternative" "7,8,9,10,11")
1851 (const_string "ssemov")
1852 (match_operand:DI 1 "pic_32bit_operand" "")
1853 (const_string "lea")
1855 (const_string "imov")))
1856 (set (attr "prefix")
1857 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1858 (const_string "orig")
1859 (const_string "maybe_vex")))
1860 (set (attr "prefix_data16")
1861 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1863 (const_string "*")))
1865 (cond [(eq_attr "alternative" "2,3")
1867 (eq_attr "alternative" "6,7")
1869 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1870 (const_string "V4SF")
1871 (const_string "TI"))
1872 (and (eq_attr "alternative" "8,9,10,11")
1873 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1876 (const_string "SI")))])
1878 ;; Stores and loads of ax to arbitrary constant address.
1879 ;; We fake an second form of instruction to force reload to load address
1880 ;; into register when rax is not available
1881 (define_insn "*movabssi_1_rex64"
1882 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1883 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1884 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1886 movabs{l}\t{%1, %P0|%P0, %1}
1887 mov{l}\t{%1, %a0|%a0, %1}"
1888 [(set_attr "type" "imov")
1889 (set_attr "modrm" "0,*")
1890 (set_attr "length_address" "8,0")
1891 (set_attr "length_immediate" "0,*")
1892 (set_attr "memory" "store")
1893 (set_attr "mode" "SI")])
1895 (define_insn "*movabssi_2_rex64"
1896 [(set (match_operand:SI 0 "register_operand" "=a,r")
1897 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1898 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1900 movabs{l}\t{%P1, %0|%0, %P1}
1901 mov{l}\t{%a1, %0|%0, %a1}"
1902 [(set_attr "type" "imov")
1903 (set_attr "modrm" "0,*")
1904 (set_attr "length_address" "8,0")
1905 (set_attr "length_immediate" "0")
1906 (set_attr "memory" "load")
1907 (set_attr "mode" "SI")])
1909 (define_insn "*swapsi"
1910 [(set (match_operand:SI 0 "register_operand" "+r")
1911 (match_operand:SI 1 "register_operand" "+r"))
1916 [(set_attr "type" "imov")
1917 (set_attr "mode" "SI")
1918 (set_attr "pent_pair" "np")
1919 (set_attr "athlon_decode" "vector")
1920 (set_attr "amdfam10_decode" "double")])
1922 (define_expand "movhi"
1923 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1924 (match_operand:HI 1 "general_operand" ""))]
1926 "ix86_expand_move (HImode, operands); DONE;")
1928 (define_insn "*pushhi2"
1929 [(set (match_operand:HI 0 "push_operand" "=X")
1930 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1933 [(set_attr "type" "push")
1934 (set_attr "mode" "SI")])
1936 ;; For 64BIT abi we always round up to 8 bytes.
1937 (define_insn "*pushhi2_rex64"
1938 [(set (match_operand:HI 0 "push_operand" "=X")
1939 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1942 [(set_attr "type" "push")
1943 (set_attr "mode" "DI")])
1945 (define_insn "*movhi_1"
1946 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1947 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1948 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1950 switch (get_attr_type (insn))
1953 /* movzwl is faster than movw on p2 due to partial word stalls,
1954 though not as fast as an aligned movl. */
1955 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1957 if (get_attr_mode (insn) == MODE_SI)
1958 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1960 return "mov{w}\t{%1, %0|%0, %1}";
1964 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965 (const_string "imov")
1966 (and (eq_attr "alternative" "0")
1967 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1969 (eq (symbol_ref "TARGET_HIMODE_MATH")
1971 (const_string "imov")
1972 (and (eq_attr "alternative" "1,2")
1973 (match_operand:HI 1 "aligned_operand" ""))
1974 (const_string "imov")
1975 (and (ne (symbol_ref "TARGET_MOVX")
1977 (eq_attr "alternative" "0,2"))
1978 (const_string "imovx")
1980 (const_string "imov")))
1982 (cond [(eq_attr "type" "imovx")
1984 (and (eq_attr "alternative" "1,2")
1985 (match_operand:HI 1 "aligned_operand" ""))
1987 (and (eq_attr "alternative" "0")
1988 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1990 (eq (symbol_ref "TARGET_HIMODE_MATH")
1994 (const_string "HI")))])
1996 ;; Stores and loads of ax to arbitrary constant address.
1997 ;; We fake an second form of instruction to force reload to load address
1998 ;; into register when rax is not available
1999 (define_insn "*movabshi_1_rex64"
2000 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2001 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2002 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2004 movabs{w}\t{%1, %P0|%P0, %1}
2005 mov{w}\t{%1, %a0|%a0, %1}"
2006 [(set_attr "type" "imov")
2007 (set_attr "modrm" "0,*")
2008 (set_attr "length_address" "8,0")
2009 (set_attr "length_immediate" "0,*")
2010 (set_attr "memory" "store")
2011 (set_attr "mode" "HI")])
2013 (define_insn "*movabshi_2_rex64"
2014 [(set (match_operand:HI 0 "register_operand" "=a,r")
2015 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2016 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2018 movabs{w}\t{%P1, %0|%0, %P1}
2019 mov{w}\t{%a1, %0|%0, %a1}"
2020 [(set_attr "type" "imov")
2021 (set_attr "modrm" "0,*")
2022 (set_attr "length_address" "8,0")
2023 (set_attr "length_immediate" "0")
2024 (set_attr "memory" "load")
2025 (set_attr "mode" "HI")])
2027 (define_insn "*swaphi_1"
2028 [(set (match_operand:HI 0 "register_operand" "+r")
2029 (match_operand:HI 1 "register_operand" "+r"))
2032 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2034 [(set_attr "type" "imov")
2035 (set_attr "mode" "SI")
2036 (set_attr "pent_pair" "np")
2037 (set_attr "athlon_decode" "vector")
2038 (set_attr "amdfam10_decode" "double")])
2040 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2041 (define_insn "*swaphi_2"
2042 [(set (match_operand:HI 0 "register_operand" "+r")
2043 (match_operand:HI 1 "register_operand" "+r"))
2046 "TARGET_PARTIAL_REG_STALL"
2048 [(set_attr "type" "imov")
2049 (set_attr "mode" "HI")
2050 (set_attr "pent_pair" "np")
2051 (set_attr "athlon_decode" "vector")])
2053 (define_expand "movstricthi"
2054 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2055 (match_operand:HI 1 "general_operand" ""))]
2058 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2060 /* Don't generate memory->memory moves, go through a register */
2061 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2062 operands[1] = force_reg (HImode, operands[1]);
2065 (define_insn "*movstricthi_1"
2066 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2067 (match_operand:HI 1 "general_operand" "rn,m"))]
2068 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2069 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2070 "mov{w}\t{%1, %0|%0, %1}"
2071 [(set_attr "type" "imov")
2072 (set_attr "mode" "HI")])
2074 (define_insn "*movstricthi_xor"
2075 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2076 (match_operand:HI 1 "const0_operand" ""))
2077 (clobber (reg:CC FLAGS_REG))]
2080 [(set_attr "type" "alu1")
2081 (set_attr "mode" "HI")
2082 (set_attr "length_immediate" "0")])
2084 (define_expand "movqi"
2085 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2086 (match_operand:QI 1 "general_operand" ""))]
2088 "ix86_expand_move (QImode, operands); DONE;")
2090 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2091 ;; "push a byte". But actually we use pushl, which has the effect
2092 ;; of rounding the amount pushed up to a word.
2094 (define_insn "*pushqi2"
2095 [(set (match_operand:QI 0 "push_operand" "=X")
2096 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2099 [(set_attr "type" "push")
2100 (set_attr "mode" "SI")])
2102 ;; For 64BIT abi we always round up to 8 bytes.
2103 (define_insn "*pushqi2_rex64"
2104 [(set (match_operand:QI 0 "push_operand" "=X")
2105 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2108 [(set_attr "type" "push")
2109 (set_attr "mode" "DI")])
2111 ;; Situation is quite tricky about when to choose full sized (SImode) move
2112 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2113 ;; partial register dependency machines (such as AMD Athlon), where QImode
2114 ;; moves issue extra dependency and for partial register stalls machines
2115 ;; that don't use QImode patterns (and QImode move cause stall on the next
2118 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2119 ;; register stall machines with, where we use QImode instructions, since
2120 ;; partial register stall can be caused there. Then we use movzx.
2121 (define_insn "*movqi_1"
2122 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2123 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2124 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2126 switch (get_attr_type (insn))
2129 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2130 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2132 if (get_attr_mode (insn) == MODE_SI)
2133 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2135 return "mov{b}\t{%1, %0|%0, %1}";
2139 (cond [(and (eq_attr "alternative" "5")
2140 (not (match_operand:QI 1 "aligned_operand" "")))
2141 (const_string "imovx")
2142 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2143 (const_string "imov")
2144 (and (eq_attr "alternative" "3")
2145 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2147 (eq (symbol_ref "TARGET_QIMODE_MATH")
2149 (const_string "imov")
2150 (eq_attr "alternative" "3,5")
2151 (const_string "imovx")
2152 (and (ne (symbol_ref "TARGET_MOVX")
2154 (eq_attr "alternative" "2"))
2155 (const_string "imovx")
2157 (const_string "imov")))
2159 (cond [(eq_attr "alternative" "3,4,5")
2161 (eq_attr "alternative" "6")
2163 (eq_attr "type" "imovx")
2165 (and (eq_attr "type" "imov")
2166 (and (eq_attr "alternative" "0,1")
2167 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2169 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2171 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2174 ;; Avoid partial register stalls when not using QImode arithmetic
2175 (and (eq_attr "type" "imov")
2176 (and (eq_attr "alternative" "0,1")
2177 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2179 (eq (symbol_ref "TARGET_QIMODE_MATH")
2183 (const_string "QI")))])
2185 (define_insn "*swapqi_1"
2186 [(set (match_operand:QI 0 "register_operand" "+r")
2187 (match_operand:QI 1 "register_operand" "+r"))
2190 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2192 [(set_attr "type" "imov")
2193 (set_attr "mode" "SI")
2194 (set_attr "pent_pair" "np")
2195 (set_attr "athlon_decode" "vector")
2196 (set_attr "amdfam10_decode" "vector")])
2198 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2199 (define_insn "*swapqi_2"
2200 [(set (match_operand:QI 0 "register_operand" "+q")
2201 (match_operand:QI 1 "register_operand" "+q"))
2204 "TARGET_PARTIAL_REG_STALL"
2206 [(set_attr "type" "imov")
2207 (set_attr "mode" "QI")
2208 (set_attr "pent_pair" "np")
2209 (set_attr "athlon_decode" "vector")])
2211 (define_expand "movstrictqi"
2212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2213 (match_operand:QI 1 "general_operand" ""))]
2216 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2218 /* Don't generate memory->memory moves, go through a register. */
2219 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2220 operands[1] = force_reg (QImode, operands[1]);
2223 (define_insn "*movstrictqi_1"
2224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2225 (match_operand:QI 1 "general_operand" "*qn,m"))]
2226 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2228 "mov{b}\t{%1, %0|%0, %1}"
2229 [(set_attr "type" "imov")
2230 (set_attr "mode" "QI")])
2232 (define_insn "*movstrictqi_xor"
2233 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2234 (match_operand:QI 1 "const0_operand" ""))
2235 (clobber (reg:CC FLAGS_REG))]
2238 [(set_attr "type" "alu1")
2239 (set_attr "mode" "QI")
2240 (set_attr "length_immediate" "0")])
2242 (define_insn "*movsi_extv_1"
2243 [(set (match_operand:SI 0 "register_operand" "=R")
2244 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2248 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2249 [(set_attr "type" "imovx")
2250 (set_attr "mode" "SI")])
2252 (define_insn "*movhi_extv_1"
2253 [(set (match_operand:HI 0 "register_operand" "=R")
2254 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2258 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2259 [(set_attr "type" "imovx")
2260 (set_attr "mode" "SI")])
2262 (define_insn "*movqi_extv_1"
2263 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2264 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2269 switch (get_attr_type (insn))
2272 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2274 return "mov{b}\t{%h1, %0|%0, %h1}";
2278 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2279 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2280 (ne (symbol_ref "TARGET_MOVX")
2282 (const_string "imovx")
2283 (const_string "imov")))
2285 (if_then_else (eq_attr "type" "imovx")
2287 (const_string "QI")))])
2289 (define_insn "*movqi_extv_1_rex64"
2290 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2291 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2296 switch (get_attr_type (insn))
2299 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2301 return "mov{b}\t{%h1, %0|%0, %h1}";
2305 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2306 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2307 (ne (symbol_ref "TARGET_MOVX")
2309 (const_string "imovx")
2310 (const_string "imov")))
2312 (if_then_else (eq_attr "type" "imovx")
2314 (const_string "QI")))])
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsqi_1_rex64"
2320 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2322 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2324 movabs{b}\t{%1, %P0|%P0, %1}
2325 mov{b}\t{%1, %a0|%a0, %1}"
2326 [(set_attr "type" "imov")
2327 (set_attr "modrm" "0,*")
2328 (set_attr "length_address" "8,0")
2329 (set_attr "length_immediate" "0,*")
2330 (set_attr "memory" "store")
2331 (set_attr "mode" "QI")])
2333 (define_insn "*movabsqi_2_rex64"
2334 [(set (match_operand:QI 0 "register_operand" "=a,r")
2335 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2338 movabs{b}\t{%P1, %0|%0, %P1}
2339 mov{b}\t{%a1, %0|%0, %a1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "modrm" "0,*")
2342 (set_attr "length_address" "8,0")
2343 (set_attr "length_immediate" "0")
2344 (set_attr "memory" "load")
2345 (set_attr "mode" "QI")])
2347 (define_insn "*movdi_extzv_1"
2348 [(set (match_operand:DI 0 "register_operand" "=R")
2349 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2353 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2354 [(set_attr "type" "imovx")
2355 (set_attr "mode" "SI")])
2357 (define_insn "*movsi_extzv_1"
2358 [(set (match_operand:SI 0 "register_operand" "=R")
2359 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2363 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2364 [(set_attr "type" "imovx")
2365 (set_attr "mode" "SI")])
2367 (define_insn "*movqi_extzv_2"
2368 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2369 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2374 switch (get_attr_type (insn))
2377 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2379 return "mov{b}\t{%h1, %0|%0, %h1}";
2383 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2384 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2385 (ne (symbol_ref "TARGET_MOVX")
2387 (const_string "imovx")
2388 (const_string "imov")))
2390 (if_then_else (eq_attr "type" "imovx")
2392 (const_string "QI")))])
2394 (define_insn "*movqi_extzv_2_rex64"
2395 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2396 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2401 switch (get_attr_type (insn))
2404 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2406 return "mov{b}\t{%h1, %0|%0, %h1}";
2410 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2411 (ne (symbol_ref "TARGET_MOVX")
2413 (const_string "imovx")
2414 (const_string "imov")))
2416 (if_then_else (eq_attr "type" "imovx")
2418 (const_string "QI")))])
2420 (define_insn "movsi_insv_1"
2421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2424 (match_operand:SI 1 "general_operand" "Qmn"))]
2426 "mov{b}\t{%b1, %h0|%h0, %b1}"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "QI")])
2430 (define_insn "*movsi_insv_1_rex64"
2431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2434 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2436 "mov{b}\t{%b1, %h0|%h0, %b1}"
2437 [(set_attr "type" "imov")
2438 (set_attr "mode" "QI")])
2440 (define_insn "movdi_insv_1_rex64"
2441 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2444 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2446 "mov{b}\t{%b1, %h0|%h0, %b1}"
2447 [(set_attr "type" "imov")
2448 (set_attr "mode" "QI")])
2450 (define_insn "*movqi_insv_2"
2451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2454 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2457 "mov{b}\t{%h1, %h0|%h0, %h1}"
2458 [(set_attr "type" "imov")
2459 (set_attr "mode" "QI")])
2461 (define_expand "movdi"
2462 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2463 (match_operand:DI 1 "general_operand" ""))]
2465 "ix86_expand_move (DImode, operands); DONE;")
2467 (define_insn "*pushdi"
2468 [(set (match_operand:DI 0 "push_operand" "=<")
2469 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2473 (define_insn "*pushdi2_rex64"
2474 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2475 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2480 [(set_attr "type" "push,multi")
2481 (set_attr "mode" "DI")])
2483 ;; Convert impossible pushes of immediate to existing instructions.
2484 ;; First try to get scratch register and go through it. In case this
2485 ;; fails, push sign extended lower part first and then overwrite
2486 ;; upper part by 32bit move.
2488 [(match_scratch:DI 2 "r")
2489 (set (match_operand:DI 0 "push_operand" "")
2490 (match_operand:DI 1 "immediate_operand" ""))]
2491 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2492 && !x86_64_immediate_operand (operands[1], DImode)"
2493 [(set (match_dup 2) (match_dup 1))
2494 (set (match_dup 0) (match_dup 2))]
2497 ;; We need to define this as both peepholer and splitter for case
2498 ;; peephole2 pass is not run.
2499 ;; "&& 1" is needed to keep it from matching the previous pattern.
2501 [(set (match_operand:DI 0 "push_operand" "")
2502 (match_operand:DI 1 "immediate_operand" ""))]
2503 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2504 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2505 [(set (match_dup 0) (match_dup 1))
2506 (set (match_dup 2) (match_dup 3))]
2507 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2508 operands[1] = gen_lowpart (DImode, operands[2]);
2509 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2514 [(set (match_operand:DI 0 "push_operand" "")
2515 (match_operand:DI 1 "immediate_operand" ""))]
2516 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2517 ? epilogue_completed : reload_completed)
2518 && !symbolic_operand (operands[1], DImode)
2519 && !x86_64_immediate_operand (operands[1], DImode)"
2520 [(set (match_dup 0) (match_dup 1))
2521 (set (match_dup 2) (match_dup 3))]
2522 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2523 operands[1] = gen_lowpart (DImode, operands[2]);
2524 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2528 (define_insn "*pushdi2_prologue_rex64"
2529 [(set (match_operand:DI 0 "push_operand" "=<")
2530 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2531 (clobber (mem:BLK (scratch)))]
2534 [(set_attr "type" "push")
2535 (set_attr "mode" "DI")])
2537 (define_insn "*popdi1_epilogue_rex64"
2538 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2539 (mem:DI (reg:DI SP_REG)))
2540 (set (reg:DI SP_REG)
2541 (plus:DI (reg:DI SP_REG) (const_int 8)))
2542 (clobber (mem:BLK (scratch)))]
2545 [(set_attr "type" "pop")
2546 (set_attr "mode" "DI")])
2548 (define_insn "popdi1"
2549 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2550 (mem:DI (reg:DI SP_REG)))
2551 (set (reg:DI SP_REG)
2552 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2555 [(set_attr "type" "pop")
2556 (set_attr "mode" "DI")])
2558 (define_insn "*movdi_xor_rex64"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (match_operand:DI 1 "const0_operand" ""))
2561 (clobber (reg:CC FLAGS_REG))]
2563 && reload_completed"
2565 [(set_attr "type" "alu1")
2566 (set_attr "mode" "SI")
2567 (set_attr "length_immediate" "0")])
2569 (define_insn "*movdi_or_rex64"
2570 [(set (match_operand:DI 0 "register_operand" "=r")
2571 (match_operand:DI 1 "const_int_operand" "i"))
2572 (clobber (reg:CC FLAGS_REG))]
2575 && operands[1] == constm1_rtx"
2577 operands[1] = constm1_rtx;
2578 return "or{q}\t{%1, %0|%0, %1}";
2580 [(set_attr "type" "alu1")
2581 (set_attr "mode" "DI")
2582 (set_attr "length_immediate" "1")])
2584 (define_insn "*movdi_2"
2585 [(set (match_operand:DI 0 "nonimmediate_operand"
2586 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2587 (match_operand:DI 1 "general_operand"
2588 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2589 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2594 movq\t{%1, %0|%0, %1}
2595 movq\t{%1, %0|%0, %1}
2597 %vmovq\t{%1, %0|%0, %1}
2598 %vmovdqa\t{%1, %0|%0, %1}
2599 %vmovq\t{%1, %0|%0, %1}
2601 movlps\t{%1, %0|%0, %1}
2602 movaps\t{%1, %0|%0, %1}
2603 movlps\t{%1, %0|%0, %1}"
2604 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2605 (set (attr "prefix")
2606 (if_then_else (eq_attr "alternative" "5,6,7,8")
2607 (const_string "vex")
2608 (const_string "orig")))
2609 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2612 [(set (match_operand:DI 0 "push_operand" "")
2613 (match_operand:DI 1 "general_operand" ""))]
2614 "!TARGET_64BIT && reload_completed
2615 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2617 "ix86_split_long_move (operands); DONE;")
2619 ;; %%% This multiword shite has got to go.
2621 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2622 (match_operand:DI 1 "general_operand" ""))]
2623 "!TARGET_64BIT && reload_completed
2624 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2625 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2627 "ix86_split_long_move (operands); DONE;")
2629 (define_insn "*movdi_1_rex64"
2630 [(set (match_operand:DI 0 "nonimmediate_operand"
2631 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2632 (match_operand:DI 1 "general_operand"
2633 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2634 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2636 switch (get_attr_type (insn))
2639 if (SSE_REG_P (operands[0]))
2640 return "movq2dq\t{%1, %0|%0, %1}";
2642 return "movdq2q\t{%1, %0|%0, %1}";
2647 if (get_attr_mode (insn) == MODE_TI)
2648 return "vmovdqa\t{%1, %0|%0, %1}";
2650 return "vmovq\t{%1, %0|%0, %1}";
2653 if (get_attr_mode (insn) == MODE_TI)
2654 return "movdqa\t{%1, %0|%0, %1}";
2658 /* Moves from and into integer register is done using movd
2659 opcode with REX prefix. */
2660 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2661 return "movd\t{%1, %0|%0, %1}";
2662 return "movq\t{%1, %0|%0, %1}";
2665 return "%vpxor\t%0, %d0";
2668 return "pxor\t%0, %0";
2674 return "lea{q}\t{%a1, %0|%0, %a1}";
2677 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2678 if (get_attr_mode (insn) == MODE_SI)
2679 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2680 else if (which_alternative == 2)
2681 return "movabs{q}\t{%1, %0|%0, %1}";
2683 return "mov{q}\t{%1, %0|%0, %1}";
2687 (cond [(eq_attr "alternative" "5")
2688 (const_string "mmx")
2689 (eq_attr "alternative" "6,7,8,9,10")
2690 (const_string "mmxmov")
2691 (eq_attr "alternative" "11")
2692 (const_string "sselog1")
2693 (eq_attr "alternative" "12,13,14,15,16")
2694 (const_string "ssemov")
2695 (eq_attr "alternative" "17,18")
2696 (const_string "ssecvt")
2697 (eq_attr "alternative" "4")
2698 (const_string "multi")
2699 (match_operand:DI 1 "pic_32bit_operand" "")
2700 (const_string "lea")
2702 (const_string "imov")))
2705 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2707 (const_string "*")))
2708 (set (attr "length_immediate")
2710 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2712 (const_string "*")))
2713 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2714 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2715 (set (attr "prefix")
2716 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2717 (const_string "maybe_vex")
2718 (const_string "orig")))
2719 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2721 ;; Stores and loads of ax to arbitrary constant address.
2722 ;; We fake an second form of instruction to force reload to load address
2723 ;; into register when rax is not available
2724 (define_insn "*movabsdi_1_rex64"
2725 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2726 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2727 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2729 movabs{q}\t{%1, %P0|%P0, %1}
2730 mov{q}\t{%1, %a0|%a0, %1}"
2731 [(set_attr "type" "imov")
2732 (set_attr "modrm" "0,*")
2733 (set_attr "length_address" "8,0")
2734 (set_attr "length_immediate" "0,*")
2735 (set_attr "memory" "store")
2736 (set_attr "mode" "DI")])
2738 (define_insn "*movabsdi_2_rex64"
2739 [(set (match_operand:DI 0 "register_operand" "=a,r")
2740 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2741 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2743 movabs{q}\t{%P1, %0|%0, %P1}
2744 mov{q}\t{%a1, %0|%0, %a1}"
2745 [(set_attr "type" "imov")
2746 (set_attr "modrm" "0,*")
2747 (set_attr "length_address" "8,0")
2748 (set_attr "length_immediate" "0")
2749 (set_attr "memory" "load")
2750 (set_attr "mode" "DI")])
2752 ;; Convert impossible stores of immediate to existing instructions.
2753 ;; First try to get scratch register and go through it. In case this
2754 ;; fails, move by 32bit parts.
2756 [(match_scratch:DI 2 "r")
2757 (set (match_operand:DI 0 "memory_operand" "")
2758 (match_operand:DI 1 "immediate_operand" ""))]
2759 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2760 && !x86_64_immediate_operand (operands[1], DImode)"
2761 [(set (match_dup 2) (match_dup 1))
2762 (set (match_dup 0) (match_dup 2))]
2765 ;; We need to define this as both peepholer and splitter for case
2766 ;; peephole2 pass is not run.
2767 ;; "&& 1" is needed to keep it from matching the previous pattern.
2769 [(set (match_operand:DI 0 "memory_operand" "")
2770 (match_operand:DI 1 "immediate_operand" ""))]
2771 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2772 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2773 [(set (match_dup 2) (match_dup 3))
2774 (set (match_dup 4) (match_dup 5))]
2775 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2778 [(set (match_operand:DI 0 "memory_operand" "")
2779 (match_operand:DI 1 "immediate_operand" ""))]
2780 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2781 ? epilogue_completed : reload_completed)
2782 && !symbolic_operand (operands[1], DImode)
2783 && !x86_64_immediate_operand (operands[1], DImode)"
2784 [(set (match_dup 2) (match_dup 3))
2785 (set (match_dup 4) (match_dup 5))]
2786 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2788 (define_insn "*swapdi_rex64"
2789 [(set (match_operand:DI 0 "register_operand" "+r")
2790 (match_operand:DI 1 "register_operand" "+r"))
2795 [(set_attr "type" "imov")
2796 (set_attr "mode" "DI")
2797 (set_attr "pent_pair" "np")
2798 (set_attr "athlon_decode" "vector")
2799 (set_attr "amdfam10_decode" "double")])
2801 (define_expand "movoi"
2802 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2803 (match_operand:OI 1 "general_operand" ""))]
2805 "ix86_expand_move (OImode, operands); DONE;")
2807 (define_insn "*movoi_internal"
2808 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2809 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2813 switch (which_alternative)
2816 return "vxorps\t%0, %0, %0";
2819 if (misaligned_operand (operands[0], OImode)
2820 || misaligned_operand (operands[1], OImode))
2821 return "vmovdqu\t{%1, %0|%0, %1}";
2823 return "vmovdqa\t{%1, %0|%0, %1}";
2828 [(set_attr "type" "sselog1,ssemov,ssemov")
2829 (set_attr "prefix" "vex")
2830 (set_attr "mode" "OI")])
2832 (define_expand "movti"
2833 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2834 (match_operand:TI 1 "nonimmediate_operand" ""))]
2835 "TARGET_SSE || TARGET_64BIT"
2838 ix86_expand_move (TImode, operands);
2839 else if (push_operand (operands[0], TImode))
2840 ix86_expand_push (TImode, operands[1]);
2842 ix86_expand_vector_move (TImode, operands);
2846 (define_insn "*movti_internal"
2847 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2848 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2849 "TARGET_SSE && !TARGET_64BIT
2850 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2852 switch (which_alternative)
2855 if (get_attr_mode (insn) == MODE_V4SF)
2856 return "%vxorps\t%0, %d0";
2858 return "%vpxor\t%0, %d0";
2861 /* TDmode values are passed as TImode on the stack. Moving them
2862 to stack may result in unaligned memory access. */
2863 if (misaligned_operand (operands[0], TImode)
2864 || misaligned_operand (operands[1], TImode))
2866 if (get_attr_mode (insn) == MODE_V4SF)
2867 return "%vmovups\t{%1, %0|%0, %1}";
2869 return "%vmovdqu\t{%1, %0|%0, %1}";
2873 if (get_attr_mode (insn) == MODE_V4SF)
2874 return "%vmovaps\t{%1, %0|%0, %1}";
2876 return "%vmovdqa\t{%1, %0|%0, %1}";
2882 [(set_attr "type" "sselog1,ssemov,ssemov")
2883 (set_attr "prefix" "maybe_vex")
2885 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2886 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2887 (const_string "V4SF")
2888 (and (eq_attr "alternative" "2")
2889 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2891 (const_string "V4SF")]
2892 (const_string "TI")))])
2894 (define_insn "*movti_rex64"
2895 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2896 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2900 switch (which_alternative)
2906 if (get_attr_mode (insn) == MODE_V4SF)
2907 return "%vxorps\t%0, %d0";
2909 return "%vpxor\t%0, %d0";
2912 /* TDmode values are passed as TImode on the stack. Moving them
2913 to stack may result in unaligned memory access. */
2914 if (misaligned_operand (operands[0], TImode)
2915 || misaligned_operand (operands[1], TImode))
2917 if (get_attr_mode (insn) == MODE_V4SF)
2918 return "%vmovups\t{%1, %0|%0, %1}";
2920 return "%vmovdqu\t{%1, %0|%0, %1}";
2924 if (get_attr_mode (insn) == MODE_V4SF)
2925 return "%vmovaps\t{%1, %0|%0, %1}";
2927 return "%vmovdqa\t{%1, %0|%0, %1}";
2933 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2934 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2936 (cond [(eq_attr "alternative" "2,3")
2938 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2940 (const_string "V4SF")
2941 (const_string "TI"))
2942 (eq_attr "alternative" "4")
2944 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2946 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2948 (const_string "V4SF")
2949 (const_string "TI"))]
2950 (const_string "DI")))])
2953 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2954 (match_operand:TI 1 "general_operand" ""))]
2955 "reload_completed && !SSE_REG_P (operands[0])
2956 && !SSE_REG_P (operands[1])"
2958 "ix86_split_long_move (operands); DONE;")
2960 ;; This expands to what emit_move_complex would generate if we didn't
2961 ;; have a movti pattern. Having this avoids problems with reload on
2962 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2963 ;; to have around all the time.
2964 (define_expand "movcdi"
2965 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2966 (match_operand:CDI 1 "general_operand" ""))]
2969 if (push_operand (operands[0], CDImode))
2970 emit_move_complex_push (CDImode, operands[0], operands[1]);
2972 emit_move_complex_parts (operands[0], operands[1]);
2976 (define_expand "movsf"
2977 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2978 (match_operand:SF 1 "general_operand" ""))]
2980 "ix86_expand_move (SFmode, operands); DONE;")
2982 (define_insn "*pushsf"
2983 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2984 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2987 /* Anything else should be already split before reg-stack. */
2988 gcc_assert (which_alternative == 1);
2989 return "push{l}\t%1";
2991 [(set_attr "type" "multi,push,multi")
2992 (set_attr "unit" "i387,*,*")
2993 (set_attr "mode" "SF,SI,SF")])
2995 (define_insn "*pushsf_rex64"
2996 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2997 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3000 /* Anything else should be already split before reg-stack. */
3001 gcc_assert (which_alternative == 1);
3002 return "push{q}\t%q1";
3004 [(set_attr "type" "multi,push,multi")
3005 (set_attr "unit" "i387,*,*")
3006 (set_attr "mode" "SF,DI,SF")])
3009 [(set (match_operand:SF 0 "push_operand" "")
3010 (match_operand:SF 1 "memory_operand" ""))]
3012 && MEM_P (operands[1])
3013 && (operands[2] = find_constant_src (insn))"
3018 ;; %%% Kill this when call knows how to work this out.
3020 [(set (match_operand:SF 0 "push_operand" "")
3021 (match_operand:SF 1 "any_fp_register_operand" ""))]
3023 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3024 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3027 [(set (match_operand:SF 0 "push_operand" "")
3028 (match_operand:SF 1 "any_fp_register_operand" ""))]
3030 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3031 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3033 (define_insn "*movsf_1"
3034 [(set (match_operand:SF 0 "nonimmediate_operand"
3035 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3036 (match_operand:SF 1 "general_operand"
3037 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3038 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3039 && (reload_in_progress || reload_completed
3040 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3041 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3042 && standard_80387_constant_p (operands[1]))
3043 || GET_CODE (operands[1]) != CONST_DOUBLE
3044 || memory_operand (operands[0], SFmode))"
3046 switch (which_alternative)
3050 return output_387_reg_move (insn, operands);
3053 return standard_80387_constant_opcode (operands[1]);
3057 return "mov{l}\t{%1, %0|%0, %1}";
3059 if (get_attr_mode (insn) == MODE_TI)
3060 return "%vpxor\t%0, %d0";
3062 return "%vxorps\t%0, %d0";
3064 if (get_attr_mode (insn) == MODE_V4SF)
3065 return "%vmovaps\t{%1, %0|%0, %1}";
3067 return "%vmovss\t{%1, %d0|%d0, %1}";
3070 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3071 : "vmovss\t{%1, %0|%0, %1}";
3073 return "movss\t{%1, %0|%0, %1}";
3075 return "%vmovss\t{%1, %0|%0, %1}";
3077 case 9: case 10: case 14: case 15:
3078 return "movd\t{%1, %0|%0, %1}";
3080 return "%vmovd\t{%1, %0|%0, %1}";
3083 return "movq\t{%1, %0|%0, %1}";
3089 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3090 (set (attr "prefix")
3091 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3092 (const_string "maybe_vex")
3093 (const_string "orig")))
3095 (cond [(eq_attr "alternative" "3,4,9,10")
3097 (eq_attr "alternative" "5")
3099 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3101 (ne (symbol_ref "TARGET_SSE2")
3103 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3106 (const_string "V4SF"))
3107 /* For architectures resolving dependencies on
3108 whole SSE registers use APS move to break dependency
3109 chains, otherwise use short move to avoid extra work.
3111 Do the same for architectures resolving dependencies on
3112 the parts. While in DF mode it is better to always handle
3113 just register parts, the SF mode is different due to lack
3114 of instructions to load just part of the register. It is
3115 better to maintain the whole registers in single format
3116 to avoid problems on using packed logical operations. */
3117 (eq_attr "alternative" "6")
3119 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3121 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3123 (const_string "V4SF")
3124 (const_string "SF"))
3125 (eq_attr "alternative" "11")
3126 (const_string "DI")]
3127 (const_string "SF")))])
3129 (define_insn "*swapsf"
3130 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3131 (match_operand:SF 1 "fp_register_operand" "+f"))
3134 "reload_completed || TARGET_80387"
3136 if (STACK_TOP_P (operands[0]))
3141 [(set_attr "type" "fxch")
3142 (set_attr "mode" "SF")])
3144 (define_expand "movdf"
3145 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3146 (match_operand:DF 1 "general_operand" ""))]
3148 "ix86_expand_move (DFmode, operands); DONE;")
3150 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3151 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3152 ;; On the average, pushdf using integers can be still shorter. Allow this
3153 ;; pattern for optimize_size too.
3155 (define_insn "*pushdf_nointeger"
3156 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3157 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3158 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3160 /* This insn should be already split before reg-stack. */
3163 [(set_attr "type" "multi")
3164 (set_attr "unit" "i387,*,*,*")
3165 (set_attr "mode" "DF,SI,SI,DF")])
3167 (define_insn "*pushdf_integer"
3168 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3169 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3170 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3172 /* This insn should be already split before reg-stack. */
3175 [(set_attr "type" "multi")
3176 (set_attr "unit" "i387,*,*")
3177 (set_attr "mode" "DF,SI,DF")])
3179 ;; %%% Kill this when call knows how to work this out.
3181 [(set (match_operand:DF 0 "push_operand" "")
3182 (match_operand:DF 1 "any_fp_register_operand" ""))]
3184 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3185 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3189 [(set (match_operand:DF 0 "push_operand" "")
3190 (match_operand:DF 1 "general_operand" ""))]
3193 "ix86_split_long_move (operands); DONE;")
3195 ;; Moving is usually shorter when only FP registers are used. This separate
3196 ;; movdf pattern avoids the use of integer registers for FP operations
3197 ;; when optimizing for size.
3199 (define_insn "*movdf_nointeger"
3200 [(set (match_operand:DF 0 "nonimmediate_operand"
3201 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3202 (match_operand:DF 1 "general_operand"
3203 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3204 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3205 && ((optimize_function_for_size_p (cfun)
3206 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3207 && (reload_in_progress || reload_completed
3208 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3209 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3210 && optimize_function_for_size_p (cfun)
3211 && !memory_operand (operands[0], DFmode)
3212 && standard_80387_constant_p (operands[1]))
3213 || GET_CODE (operands[1]) != CONST_DOUBLE
3214 || ((optimize_function_for_size_p (cfun)
3215 || !TARGET_MEMORY_MISMATCH_STALL
3216 || reload_in_progress || reload_completed)
3217 && memory_operand (operands[0], DFmode)))"
3219 switch (which_alternative)
3223 return output_387_reg_move (insn, operands);
3226 return standard_80387_constant_opcode (operands[1]);
3232 switch (get_attr_mode (insn))
3235 return "%vxorps\t%0, %d0";
3237 return "%vxorpd\t%0, %d0";
3239 return "%vpxor\t%0, %d0";
3246 switch (get_attr_mode (insn))
3249 return "%vmovaps\t{%1, %0|%0, %1}";
3251 return "%vmovapd\t{%1, %0|%0, %1}";
3253 return "%vmovdqa\t{%1, %0|%0, %1}";
3255 return "%vmovq\t{%1, %0|%0, %1}";
3259 if (REG_P (operands[0]) && REG_P (operands[1]))
3260 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3262 return "vmovsd\t{%1, %0|%0, %1}";
3265 return "movsd\t{%1, %0|%0, %1}";
3269 if (REG_P (operands[0]))
3270 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3272 return "vmovlpd\t{%1, %0|%0, %1}";
3275 return "movlpd\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]))
3280 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovlps\t{%1, %0|%0, %1}";
3285 return "movlps\t{%1, %0|%0, %1}";
3294 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3295 (set (attr "prefix")
3296 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3297 (const_string "orig")
3298 (const_string "maybe_vex")))
3299 (set (attr "prefix_data16")
3300 (if_then_else (eq_attr "mode" "V1DF")
3302 (const_string "*")))
3304 (cond [(eq_attr "alternative" "0,1,2")
3306 (eq_attr "alternative" "3,4")
3309 /* For SSE1, we have many fewer alternatives. */
3310 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3311 (cond [(eq_attr "alternative" "5,6")
3312 (const_string "V4SF")
3314 (const_string "V2SF"))
3316 /* xorps is one byte shorter. */
3317 (eq_attr "alternative" "5")
3318 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320 (const_string "V4SF")
3321 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3325 (const_string "V2DF"))
3327 /* For architectures resolving dependencies on
3328 whole SSE registers use APD move to break dependency
3329 chains, otherwise use short move to avoid extra work.
3331 movaps encodes one byte shorter. */
3332 (eq_attr "alternative" "6")
3334 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3336 (const_string "V4SF")
3337 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3339 (const_string "V2DF")
3341 (const_string "DF"))
3342 /* For architectures resolving dependencies on register
3343 parts we may avoid extra work to zero out upper part
3345 (eq_attr "alternative" "7")
3347 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3349 (const_string "V1DF")
3350 (const_string "DF"))
3352 (const_string "DF")))])
3354 (define_insn "*movdf_integer_rex64"
3355 [(set (match_operand:DF 0 "nonimmediate_operand"
3356 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3357 (match_operand:DF 1 "general_operand"
3358 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3359 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360 && (reload_in_progress || reload_completed
3361 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3362 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3363 && optimize_function_for_size_p (cfun)
3364 && standard_80387_constant_p (operands[1]))
3365 || GET_CODE (operands[1]) != CONST_DOUBLE
3366 || memory_operand (operands[0], DFmode))"
3368 switch (which_alternative)
3372 return output_387_reg_move (insn, operands);
3375 return standard_80387_constant_opcode (operands[1]);
3382 switch (get_attr_mode (insn))
3385 return "%vxorps\t%0, %d0";
3387 return "%vxorpd\t%0, %d0";
3389 return "%vpxor\t%0, %d0";
3396 switch (get_attr_mode (insn))
3399 return "%vmovaps\t{%1, %0|%0, %1}";
3401 return "%vmovapd\t{%1, %0|%0, %1}";
3403 return "%vmovdqa\t{%1, %0|%0, %1}";
3405 return "%vmovq\t{%1, %0|%0, %1}";
3409 if (REG_P (operands[0]) && REG_P (operands[1]))
3410 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3412 return "vmovsd\t{%1, %0|%0, %1}";
3415 return "movsd\t{%1, %0|%0, %1}";
3417 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3419 return "%vmovlps\t{%1, %d0|%d0, %1}";
3426 return "%vmovd\t{%1, %0|%0, %1}";
3432 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3433 (set (attr "prefix")
3434 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3435 (const_string "orig")
3436 (const_string "maybe_vex")))
3437 (set (attr "prefix_data16")
3438 (if_then_else (eq_attr "mode" "V1DF")
3440 (const_string "*")))
3442 (cond [(eq_attr "alternative" "0,1,2")
3444 (eq_attr "alternative" "3,4,9,10")
3447 /* For SSE1, we have many fewer alternatives. */
3448 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3449 (cond [(eq_attr "alternative" "5,6")
3450 (const_string "V4SF")
3452 (const_string "V2SF"))
3454 /* xorps is one byte shorter. */
3455 (eq_attr "alternative" "5")
3456 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3458 (const_string "V4SF")
3459 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3463 (const_string "V2DF"))
3465 /* For architectures resolving dependencies on
3466 whole SSE registers use APD move to break dependency
3467 chains, otherwise use short move to avoid extra work.
3469 movaps encodes one byte shorter. */
3470 (eq_attr "alternative" "6")
3472 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3474 (const_string "V4SF")
3475 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3477 (const_string "V2DF")
3479 (const_string "DF"))
3480 /* For architectures resolving dependencies on register
3481 parts we may avoid extra work to zero out upper part
3483 (eq_attr "alternative" "7")
3485 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3487 (const_string "V1DF")
3488 (const_string "DF"))
3490 (const_string "DF")))])
3492 (define_insn "*movdf_integer"
3493 [(set (match_operand:DF 0 "nonimmediate_operand"
3494 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3495 (match_operand:DF 1 "general_operand"
3496 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3497 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3498 && optimize_function_for_speed_p (cfun)
3499 && TARGET_INTEGER_DFMODE_MOVES
3500 && (reload_in_progress || reload_completed
3501 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3502 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3503 && optimize_function_for_size_p (cfun)
3504 && standard_80387_constant_p (operands[1]))
3505 || GET_CODE (operands[1]) != CONST_DOUBLE
3506 || memory_operand (operands[0], DFmode))"
3508 switch (which_alternative)
3512 return output_387_reg_move (insn, operands);
3515 return standard_80387_constant_opcode (operands[1]);
3522 switch (get_attr_mode (insn))
3525 return "xorps\t%0, %0";
3527 return "xorpd\t%0, %0";
3529 return "pxor\t%0, %0";
3536 switch (get_attr_mode (insn))
3539 return "movaps\t{%1, %0|%0, %1}";
3541 return "movapd\t{%1, %0|%0, %1}";
3543 return "movdqa\t{%1, %0|%0, %1}";
3545 return "movq\t{%1, %0|%0, %1}";
3547 return "movsd\t{%1, %0|%0, %1}";
3549 return "movlpd\t{%1, %0|%0, %1}";
3551 return "movlps\t{%1, %0|%0, %1}";
3560 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3561 (set (attr "prefix_data16")
3562 (if_then_else (eq_attr "mode" "V1DF")
3564 (const_string "*")))
3566 (cond [(eq_attr "alternative" "0,1,2")
3568 (eq_attr "alternative" "3,4")
3571 /* For SSE1, we have many fewer alternatives. */
3572 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3573 (cond [(eq_attr "alternative" "5,6")
3574 (const_string "V4SF")
3576 (const_string "V2SF"))
3578 /* xorps is one byte shorter. */
3579 (eq_attr "alternative" "5")
3580 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3582 (const_string "V4SF")
3583 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3587 (const_string "V2DF"))
3589 /* For architectures resolving dependencies on
3590 whole SSE registers use APD move to break dependency
3591 chains, otherwise use short move to avoid extra work.
3593 movaps encodes one byte shorter. */
3594 (eq_attr "alternative" "6")
3596 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3598 (const_string "V4SF")
3599 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3601 (const_string "V2DF")
3603 (const_string "DF"))
3604 /* For architectures resolving dependencies on register
3605 parts we may avoid extra work to zero out upper part
3607 (eq_attr "alternative" "7")
3609 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3611 (const_string "V1DF")
3612 (const_string "DF"))
3614 (const_string "DF")))])
3617 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3618 (match_operand:DF 1 "general_operand" ""))]
3620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3621 && ! (ANY_FP_REG_P (operands[0]) ||
3622 (GET_CODE (operands[0]) == SUBREG
3623 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3624 && ! (ANY_FP_REG_P (operands[1]) ||
3625 (GET_CODE (operands[1]) == SUBREG
3626 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3628 "ix86_split_long_move (operands); DONE;")
3630 (define_insn "*swapdf"
3631 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3632 (match_operand:DF 1 "fp_register_operand" "+f"))
3635 "reload_completed || TARGET_80387"
3637 if (STACK_TOP_P (operands[0]))
3642 [(set_attr "type" "fxch")
3643 (set_attr "mode" "DF")])
3645 (define_expand "movxf"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3647 (match_operand:XF 1 "general_operand" ""))]
3649 "ix86_expand_move (XFmode, operands); DONE;")
3651 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3652 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3653 ;; Pushing using integer instructions is longer except for constants
3654 ;; and direct memory references.
3655 ;; (assuming that any given constant is pushed only once, but this ought to be
3656 ;; handled elsewhere).
3658 (define_insn "*pushxf_nointeger"
3659 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3660 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3661 "optimize_function_for_size_p (cfun)"
3663 /* This insn should be already split before reg-stack. */
3666 [(set_attr "type" "multi")
3667 (set_attr "unit" "i387,*,*")
3668 (set_attr "mode" "XF,SI,SI")])
3670 (define_insn "*pushxf_integer"
3671 [(set (match_operand:XF 0 "push_operand" "=<,<")
3672 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3673 "optimize_function_for_speed_p (cfun)"
3675 /* This insn should be already split before reg-stack. */
3678 [(set_attr "type" "multi")
3679 (set_attr "unit" "i387,*")
3680 (set_attr "mode" "XF,SI")])
3683 [(set (match_operand 0 "push_operand" "")
3684 (match_operand 1 "general_operand" ""))]
3686 && (GET_MODE (operands[0]) == XFmode
3687 || GET_MODE (operands[0]) == DFmode)
3688 && !ANY_FP_REG_P (operands[1])"
3690 "ix86_split_long_move (operands); DONE;")
3693 [(set (match_operand:XF 0 "push_operand" "")
3694 (match_operand:XF 1 "any_fp_register_operand" ""))]
3696 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3697 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3698 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3700 ;; Do not use integer registers when optimizing for size
3701 (define_insn "*movxf_nointeger"
3702 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3703 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3704 "optimize_function_for_size_p (cfun)
3705 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3706 && (reload_in_progress || reload_completed
3707 || standard_80387_constant_p (operands[1])
3708 || GET_CODE (operands[1]) != CONST_DOUBLE
3709 || memory_operand (operands[0], XFmode))"
3711 switch (which_alternative)
3715 return output_387_reg_move (insn, operands);
3718 return standard_80387_constant_opcode (operands[1]);
3726 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3727 (set_attr "mode" "XF,XF,XF,SI,SI")])
3729 (define_insn "*movxf_integer"
3730 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3731 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3732 "optimize_function_for_speed_p (cfun)
3733 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3734 && (reload_in_progress || reload_completed
3735 || GET_CODE (operands[1]) != CONST_DOUBLE
3736 || memory_operand (operands[0], XFmode))"
3738 switch (which_alternative)
3742 return output_387_reg_move (insn, operands);
3745 return standard_80387_constant_opcode (operands[1]);
3754 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3755 (set_attr "mode" "XF,XF,XF,SI,SI")])
3757 (define_expand "movtf"
3758 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3759 (match_operand:TF 1 "nonimmediate_operand" ""))]
3762 ix86_expand_move (TFmode, operands);
3766 (define_insn "*movtf_internal"
3767 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3768 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3772 switch (which_alternative)
3776 if (get_attr_mode (insn) == MODE_V4SF)
3777 return "%vmovaps\t{%1, %0|%0, %1}";
3779 return "%vmovdqa\t{%1, %0|%0, %1}";
3781 if (get_attr_mode (insn) == MODE_V4SF)
3782 return "%vxorps\t%0, %d0";
3784 return "%vpxor\t%0, %d0";
3792 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3793 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3795 (cond [(eq_attr "alternative" "0,2")
3797 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3799 (const_string "V4SF")
3800 (const_string "TI"))
3801 (eq_attr "alternative" "1")
3803 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3805 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3807 (const_string "V4SF")
3808 (const_string "TI"))]
3809 (const_string "DI")))])
3811 (define_insn "*pushtf_sse"
3812 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3813 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3816 /* This insn should be already split before reg-stack. */
3819 [(set_attr "type" "multi")
3820 (set_attr "unit" "sse,*,*")
3821 (set_attr "mode" "TF,SI,SI")])
3824 [(set (match_operand:TF 0 "push_operand" "")
3825 (match_operand:TF 1 "general_operand" ""))]
3826 "TARGET_SSE2 && reload_completed
3827 && !SSE_REG_P (operands[1])"
3829 "ix86_split_long_move (operands); DONE;")
3832 [(set (match_operand:TF 0 "push_operand" "")
3833 (match_operand:TF 1 "any_fp_register_operand" ""))]
3835 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3836 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3840 [(set (match_operand 0 "nonimmediate_operand" "")
3841 (match_operand 1 "general_operand" ""))]
3843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3844 && GET_MODE (operands[0]) == XFmode
3845 && ! (ANY_FP_REG_P (operands[0]) ||
3846 (GET_CODE (operands[0]) == SUBREG
3847 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3848 && ! (ANY_FP_REG_P (operands[1]) ||
3849 (GET_CODE (operands[1]) == SUBREG
3850 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3852 "ix86_split_long_move (operands); DONE;")
3855 [(set (match_operand 0 "register_operand" "")
3856 (match_operand 1 "memory_operand" ""))]
3858 && MEM_P (operands[1])
3859 && (GET_MODE (operands[0]) == TFmode
3860 || GET_MODE (operands[0]) == XFmode
3861 || GET_MODE (operands[0]) == SFmode
3862 || GET_MODE (operands[0]) == DFmode)
3863 && (operands[2] = find_constant_src (insn))"
3864 [(set (match_dup 0) (match_dup 2))]
3866 rtx c = operands[2];
3867 rtx r = operands[0];
3869 if (GET_CODE (r) == SUBREG)
3874 if (!standard_sse_constant_p (c))
3877 else if (FP_REG_P (r))
3879 if (!standard_80387_constant_p (c))
3882 else if (MMX_REG_P (r))
3887 [(set (match_operand 0 "register_operand" "")
3888 (float_extend (match_operand 1 "memory_operand" "")))]
3890 && MEM_P (operands[1])
3891 && (GET_MODE (operands[0]) == TFmode
3892 || GET_MODE (operands[0]) == XFmode
3893 || GET_MODE (operands[0]) == SFmode
3894 || GET_MODE (operands[0]) == DFmode)
3895 && (operands[2] = find_constant_src (insn))"
3896 [(set (match_dup 0) (match_dup 2))]
3898 rtx c = operands[2];
3899 rtx r = operands[0];
3901 if (GET_CODE (r) == SUBREG)
3906 if (!standard_sse_constant_p (c))
3909 else if (FP_REG_P (r))
3911 if (!standard_80387_constant_p (c))
3914 else if (MMX_REG_P (r))
3918 (define_insn "swapxf"
3919 [(set (match_operand:XF 0 "register_operand" "+f")
3920 (match_operand:XF 1 "register_operand" "+f"))
3925 if (STACK_TOP_P (operands[0]))
3930 [(set_attr "type" "fxch")
3931 (set_attr "mode" "XF")])
3933 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3935 [(set (match_operand:X87MODEF 0 "register_operand" "")
3936 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3937 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3938 && (standard_80387_constant_p (operands[1]) == 8
3939 || standard_80387_constant_p (operands[1]) == 9)"
3940 [(set (match_dup 0)(match_dup 1))
3942 (neg:X87MODEF (match_dup 0)))]
3946 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3947 if (real_isnegzero (&r))
3948 operands[1] = CONST0_RTX (<MODE>mode);
3950 operands[1] = CONST1_RTX (<MODE>mode);
3954 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3955 (match_operand:TF 1 "general_operand" ""))]
3957 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3959 "ix86_split_long_move (operands); DONE;")
3961 ;; Zero extension instructions
3963 (define_expand "zero_extendhisi2"
3964 [(set (match_operand:SI 0 "register_operand" "")
3965 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3968 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3970 operands[1] = force_reg (HImode, operands[1]);
3971 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3976 (define_insn "zero_extendhisi2_and"
3977 [(set (match_operand:SI 0 "register_operand" "=r")
3978 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3979 (clobber (reg:CC FLAGS_REG))]
3980 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3982 [(set_attr "type" "alu1")
3983 (set_attr "mode" "SI")])
3986 [(set (match_operand:SI 0 "register_operand" "")
3987 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3988 (clobber (reg:CC FLAGS_REG))]
3989 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3990 && optimize_function_for_speed_p (cfun)"
3991 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3992 (clobber (reg:CC FLAGS_REG))])]
3995 (define_insn "*zero_extendhisi2_movzwl"
3996 [(set (match_operand:SI 0 "register_operand" "=r")
3997 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3998 "!TARGET_ZERO_EXTEND_WITH_AND
3999 || optimize_function_for_size_p (cfun)"
4000 "movz{wl|x}\t{%1, %0|%0, %1}"
4001 [(set_attr "type" "imovx")
4002 (set_attr "mode" "SI")])
4004 (define_expand "zero_extendqihi2"
4006 [(set (match_operand:HI 0 "register_operand" "")
4007 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4008 (clobber (reg:CC FLAGS_REG))])]
4012 (define_insn "*zero_extendqihi2_and"
4013 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4014 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4015 (clobber (reg:CC FLAGS_REG))]
4016 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4018 [(set_attr "type" "alu1")
4019 (set_attr "mode" "HI")])
4021 (define_insn "*zero_extendqihi2_movzbw_and"
4022 [(set (match_operand:HI 0 "register_operand" "=r,r")
4023 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4024 (clobber (reg:CC FLAGS_REG))]
4025 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4027 [(set_attr "type" "imovx,alu1")
4028 (set_attr "mode" "HI")])
4030 ; zero extend to SImode here to avoid partial register stalls
4031 (define_insn "*zero_extendqihi2_movzbl"
4032 [(set (match_operand:HI 0 "register_operand" "=r")
4033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4034 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4035 && reload_completed"
4036 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4037 [(set_attr "type" "imovx")
4038 (set_attr "mode" "SI")])
4040 ;; For the movzbw case strip only the clobber
4042 [(set (match_operand:HI 0 "register_operand" "")
4043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4044 (clobber (reg:CC FLAGS_REG))]
4046 && (!TARGET_ZERO_EXTEND_WITH_AND
4047 || optimize_function_for_size_p (cfun))
4048 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4049 [(set (match_operand:HI 0 "register_operand" "")
4050 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4052 ;; When source and destination does not overlap, clear destination
4053 ;; first and then do the movb
4055 [(set (match_operand:HI 0 "register_operand" "")
4056 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4057 (clobber (reg:CC FLAGS_REG))]
4059 && ANY_QI_REG_P (operands[0])
4060 && (TARGET_ZERO_EXTEND_WITH_AND
4061 && optimize_function_for_speed_p (cfun))
4062 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4063 [(set (match_dup 0) (const_int 0))
4064 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4065 "operands[2] = gen_lowpart (QImode, operands[0]);")
4067 ;; Rest is handled by single and.
4069 [(set (match_operand:HI 0 "register_operand" "")
4070 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4071 (clobber (reg:CC FLAGS_REG))]
4073 && true_regnum (operands[0]) == true_regnum (operands[1])"
4074 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4075 (clobber (reg:CC FLAGS_REG))])]
4078 (define_expand "zero_extendqisi2"
4080 [(set (match_operand:SI 0 "register_operand" "")
4081 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4082 (clobber (reg:CC FLAGS_REG))])]
4086 (define_insn "*zero_extendqisi2_and"
4087 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4088 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4089 (clobber (reg:CC FLAGS_REG))]
4090 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4092 [(set_attr "type" "alu1")
4093 (set_attr "mode" "SI")])
4095 (define_insn "*zero_extendqisi2_movzbw_and"
4096 [(set (match_operand:SI 0 "register_operand" "=r,r")
4097 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4098 (clobber (reg:CC FLAGS_REG))]
4099 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4101 [(set_attr "type" "imovx,alu1")
4102 (set_attr "mode" "SI")])
4104 (define_insn "*zero_extendqisi2_movzbw"
4105 [(set (match_operand:SI 0 "register_operand" "=r")
4106 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4107 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4108 && reload_completed"
4109 "movz{bl|x}\t{%1, %0|%0, %1}"
4110 [(set_attr "type" "imovx")
4111 (set_attr "mode" "SI")])
4113 ;; For the movzbl case strip only the clobber
4115 [(set (match_operand:SI 0 "register_operand" "")
4116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4117 (clobber (reg:CC FLAGS_REG))]
4119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4122 (zero_extend:SI (match_dup 1)))])
4124 ;; When source and destination does not overlap, clear destination
4125 ;; first and then do the movb
4127 [(set (match_operand:SI 0 "register_operand" "")
4128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4129 (clobber (reg:CC FLAGS_REG))]
4131 && ANY_QI_REG_P (operands[0])
4132 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4133 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4135 [(set (match_dup 0) (const_int 0))
4136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4137 "operands[2] = gen_lowpart (QImode, operands[0]);")
4139 ;; Rest is handled by single and.
4141 [(set (match_operand:SI 0 "register_operand" "")
4142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4143 (clobber (reg:CC FLAGS_REG))]
4145 && true_regnum (operands[0]) == true_regnum (operands[1])"
4146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4147 (clobber (reg:CC FLAGS_REG))])]
4150 ;; %%% Kill me once multi-word ops are sane.
4151 (define_expand "zero_extendsidi2"
4152 [(set (match_operand:DI 0 "register_operand" "")
4153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4163 (define_insn "zero_extendsidi2_32"
4164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4166 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4167 (clobber (reg:CC FLAGS_REG))]
4173 movd\t{%1, %0|%0, %1}
4174 movd\t{%1, %0|%0, %1}
4175 %vmovd\t{%1, %0|%0, %1}
4176 %vmovd\t{%1, %0|%0, %1}"
4177 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4178 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4179 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4181 (define_insn "zero_extendsidi2_rex64"
4182 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4184 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4187 mov\t{%k1, %k0|%k0, %k1}
4189 movd\t{%1, %0|%0, %1}
4190 movd\t{%1, %0|%0, %1}
4191 %vmovd\t{%1, %0|%0, %1}
4192 %vmovd\t{%1, %0|%0, %1}"
4193 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4194 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4195 (set_attr "prefix_0f" "0,*,*,*,*,*")
4196 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4199 [(set (match_operand:DI 0 "memory_operand" "")
4200 (zero_extend:DI (match_dup 0)))]
4202 [(set (match_dup 4) (const_int 0))]
4203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4206 [(set (match_operand:DI 0 "register_operand" "")
4207 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4208 (clobber (reg:CC FLAGS_REG))]
4209 "!TARGET_64BIT && reload_completed
4210 && true_regnum (operands[0]) == true_regnum (operands[1])"
4211 [(set (match_dup 4) (const_int 0))]
4212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4216 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4217 (clobber (reg:CC FLAGS_REG))]
4218 "!TARGET_64BIT && reload_completed
4219 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4220 [(set (match_dup 3) (match_dup 1))
4221 (set (match_dup 4) (const_int 0))]
4222 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4224 (define_insn "zero_extendhidi2"
4225 [(set (match_operand:DI 0 "register_operand" "=r")
4226 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4228 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4229 [(set_attr "type" "imovx")
4230 (set_attr "mode" "SI")])
4232 (define_insn "zero_extendqidi2"
4233 [(set (match_operand:DI 0 "register_operand" "=r")
4234 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4236 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4237 [(set_attr "type" "imovx")
4238 (set_attr "mode" "SI")])
4240 ;; Sign extension instructions
4242 (define_expand "extendsidi2"
4243 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4244 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4245 (clobber (reg:CC FLAGS_REG))
4246 (clobber (match_scratch:SI 2 ""))])]
4251 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4256 (define_insn "*extendsidi2_1"
4257 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4258 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4259 (clobber (reg:CC FLAGS_REG))
4260 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4264 (define_insn "extendsidi2_rex64"
4265 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4266 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4270 movs{lq|x}\t{%1, %0|%0, %1}"
4271 [(set_attr "type" "imovx")
4272 (set_attr "mode" "DI")
4273 (set_attr "prefix_0f" "0")
4274 (set_attr "modrm" "0,1")])
4276 (define_insn "extendhidi2"
4277 [(set (match_operand:DI 0 "register_operand" "=r")
4278 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4280 "movs{wq|x}\t{%1, %0|%0, %1}"
4281 [(set_attr "type" "imovx")
4282 (set_attr "mode" "DI")])
4284 (define_insn "extendqidi2"
4285 [(set (match_operand:DI 0 "register_operand" "=r")
4286 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4288 "movs{bq|x}\t{%1, %0|%0, %1}"
4289 [(set_attr "type" "imovx")
4290 (set_attr "mode" "DI")])
4292 ;; Extend to memory case when source register does die.
4294 [(set (match_operand:DI 0 "memory_operand" "")
4295 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4296 (clobber (reg:CC FLAGS_REG))
4297 (clobber (match_operand:SI 2 "register_operand" ""))]
4299 && dead_or_set_p (insn, operands[1])
4300 && !reg_mentioned_p (operands[1], operands[0]))"
4301 [(set (match_dup 3) (match_dup 1))
4302 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4303 (clobber (reg:CC FLAGS_REG))])
4304 (set (match_dup 4) (match_dup 1))]
4305 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4307 ;; Extend to memory case when source register does not die.
4309 [(set (match_operand:DI 0 "memory_operand" "")
4310 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4311 (clobber (reg:CC FLAGS_REG))
4312 (clobber (match_operand:SI 2 "register_operand" ""))]
4316 split_di (&operands[0], 1, &operands[3], &operands[4]);
4318 emit_move_insn (operands[3], operands[1]);
4320 /* Generate a cltd if possible and doing so it profitable. */
4321 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4322 && true_regnum (operands[1]) == AX_REG
4323 && true_regnum (operands[2]) == DX_REG)
4325 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4329 emit_move_insn (operands[2], operands[1]);
4330 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4332 emit_move_insn (operands[4], operands[2]);
4336 ;; Extend to register case. Optimize case where source and destination
4337 ;; registers match and cases where we can use cltd.
4339 [(set (match_operand:DI 0 "register_operand" "")
4340 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4341 (clobber (reg:CC FLAGS_REG))
4342 (clobber (match_scratch:SI 2 ""))]
4346 split_di (&operands[0], 1, &operands[3], &operands[4]);
4348 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4349 emit_move_insn (operands[3], operands[1]);
4351 /* Generate a cltd if possible and doing so it profitable. */
4352 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4353 && true_regnum (operands[3]) == AX_REG)
4355 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4359 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4360 emit_move_insn (operands[4], operands[1]);
4362 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4366 (define_insn "extendhisi2"
4367 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4368 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4371 switch (get_attr_prefix_0f (insn))
4374 return "{cwtl|cwde}";
4376 return "movs{wl|x}\t{%1, %0|%0, %1}";
4379 [(set_attr "type" "imovx")
4380 (set_attr "mode" "SI")
4381 (set (attr "prefix_0f")
4382 ;; movsx is short decodable while cwtl is vector decoded.
4383 (if_then_else (and (eq_attr "cpu" "!k6")
4384 (eq_attr "alternative" "0"))
4386 (const_string "1")))
4388 (if_then_else (eq_attr "prefix_0f" "0")
4390 (const_string "1")))])
4392 (define_insn "*extendhisi2_zext"
4393 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4395 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4398 switch (get_attr_prefix_0f (insn))
4401 return "{cwtl|cwde}";
4403 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4406 [(set_attr "type" "imovx")
4407 (set_attr "mode" "SI")
4408 (set (attr "prefix_0f")
4409 ;; movsx is short decodable while cwtl is vector decoded.
4410 (if_then_else (and (eq_attr "cpu" "!k6")
4411 (eq_attr "alternative" "0"))
4413 (const_string "1")))
4415 (if_then_else (eq_attr "prefix_0f" "0")
4417 (const_string "1")))])
4419 (define_insn "extendqihi2"
4420 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4421 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4424 switch (get_attr_prefix_0f (insn))
4427 return "{cbtw|cbw}";
4429 return "movs{bw|x}\t{%1, %0|%0, %1}";
4432 [(set_attr "type" "imovx")
4433 (set_attr "mode" "HI")
4434 (set (attr "prefix_0f")
4435 ;; movsx is short decodable while cwtl is vector decoded.
4436 (if_then_else (and (eq_attr "cpu" "!k6")
4437 (eq_attr "alternative" "0"))
4439 (const_string "1")))
4441 (if_then_else (eq_attr "prefix_0f" "0")
4443 (const_string "1")))])
4445 (define_insn "extendqisi2"
4446 [(set (match_operand:SI 0 "register_operand" "=r")
4447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4449 "movs{bl|x}\t{%1, %0|%0, %1}"
4450 [(set_attr "type" "imovx")
4451 (set_attr "mode" "SI")])
4453 (define_insn "*extendqisi2_zext"
4454 [(set (match_operand:DI 0 "register_operand" "=r")
4456 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4458 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4459 [(set_attr "type" "imovx")
4460 (set_attr "mode" "SI")])
4462 ;; Conversions between float and double.
4464 ;; These are all no-ops in the model used for the 80387. So just
4467 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4468 (define_insn "*dummy_extendsfdf2"
4469 [(set (match_operand:DF 0 "push_operand" "=<")
4470 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4475 [(set (match_operand:DF 0 "push_operand" "")
4476 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4478 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4479 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4481 (define_insn "*dummy_extendsfxf2"
4482 [(set (match_operand:XF 0 "push_operand" "=<")
4483 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4488 [(set (match_operand:XF 0 "push_operand" "")
4489 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4491 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4492 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4493 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4496 [(set (match_operand:XF 0 "push_operand" "")
4497 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4499 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4500 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4501 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4503 (define_expand "extendsfdf2"
4504 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4505 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4506 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4508 /* ??? Needed for compress_float_constant since all fp constants
4509 are LEGITIMATE_CONSTANT_P. */
4510 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4512 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4513 && standard_80387_constant_p (operands[1]) > 0)
4515 operands[1] = simplify_const_unary_operation
4516 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4517 emit_move_insn_1 (operands[0], operands[1]);
4520 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4524 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4526 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4528 We do the conversion post reload to avoid producing of 128bit spills
4529 that might lead to ICE on 32bit target. The sequence unlikely combine
4532 [(set (match_operand:DF 0 "register_operand" "")
4534 (match_operand:SF 1 "nonimmediate_operand" "")))]
4535 "TARGET_USE_VECTOR_FP_CONVERTS
4536 && optimize_insn_for_speed_p ()
4537 && reload_completed && SSE_REG_P (operands[0])"
4542 (parallel [(const_int 0) (const_int 1)]))))]
4544 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4545 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4546 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4547 Try to avoid move when unpacking can be done in source. */
4548 if (REG_P (operands[1]))
4550 /* If it is unsafe to overwrite upper half of source, we need
4551 to move to destination and unpack there. */
4552 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4554 && true_regnum (operands[0]) != true_regnum (operands[1]))
4556 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4557 emit_move_insn (tmp, operands[1]);
4560 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4561 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4564 emit_insn (gen_vec_setv4sf_0 (operands[3],
4565 CONST0_RTX (V4SFmode), operands[1]));
4568 (define_insn "*extendsfdf2_mixed"
4569 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4571 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4572 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4574 switch (which_alternative)
4578 return output_387_reg_move (insn, operands);
4581 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4587 [(set_attr "type" "fmov,fmov,ssecvt")
4588 (set_attr "prefix" "orig,orig,maybe_vex")
4589 (set_attr "mode" "SF,XF,DF")])
4591 (define_insn "*extendsfdf2_sse"
4592 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4593 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4594 "TARGET_SSE2 && TARGET_SSE_MATH"
4595 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4596 [(set_attr "type" "ssecvt")
4597 (set_attr "prefix" "maybe_vex")
4598 (set_attr "mode" "DF")])
4600 (define_insn "*extendsfdf2_i387"
4601 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4602 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4604 "* return output_387_reg_move (insn, operands);"
4605 [(set_attr "type" "fmov")
4606 (set_attr "mode" "SF,XF")])
4608 (define_expand "extend<mode>xf2"
4609 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4610 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4613 /* ??? Needed for compress_float_constant since all fp constants
4614 are LEGITIMATE_CONSTANT_P. */
4615 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4617 if (standard_80387_constant_p (operands[1]) > 0)
4619 operands[1] = simplify_const_unary_operation
4620 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4621 emit_move_insn_1 (operands[0], operands[1]);
4624 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4628 (define_insn "*extend<mode>xf2_i387"
4629 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4631 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4633 "* return output_387_reg_move (insn, operands);"
4634 [(set_attr "type" "fmov")
4635 (set_attr "mode" "<MODE>,XF")])
4637 ;; %%% This seems bad bad news.
4638 ;; This cannot output into an f-reg because there is no way to be sure
4639 ;; of truncating in that case. Otherwise this is just like a simple move
4640 ;; insn. So we pretend we can output to a reg in order to get better
4641 ;; register preferencing, but we really use a stack slot.
4643 ;; Conversion from DFmode to SFmode.
4645 (define_expand "truncdfsf2"
4646 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4648 (match_operand:DF 1 "nonimmediate_operand" "")))]
4649 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4651 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4653 else if (flag_unsafe_math_optimizations)
4657 enum ix86_stack_slot slot = (virtuals_instantiated
4660 rtx temp = assign_386_stack_local (SFmode, slot);
4661 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4666 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4668 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4670 We do the conversion post reload to avoid producing of 128bit spills
4671 that might lead to ICE on 32bit target. The sequence unlikely combine
4674 [(set (match_operand:SF 0 "register_operand" "")
4676 (match_operand:DF 1 "nonimmediate_operand" "")))]
4677 "TARGET_USE_VECTOR_FP_CONVERTS
4678 && optimize_insn_for_speed_p ()
4679 && reload_completed && SSE_REG_P (operands[0])"
4682 (float_truncate:V2SF
4686 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4687 operands[3] = CONST0_RTX (V2SFmode);
4688 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4689 /* Use movsd for loading from memory, unpcklpd for registers.
4690 Try to avoid move when unpacking can be done in source, or SSE3
4691 movddup is available. */
4692 if (REG_P (operands[1]))
4695 && true_regnum (operands[0]) != true_regnum (operands[1])
4696 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4697 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4699 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4700 emit_move_insn (tmp, operands[1]);
4703 else if (!TARGET_SSE3)
4704 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4705 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4708 emit_insn (gen_sse2_loadlpd (operands[4],
4709 CONST0_RTX (V2DFmode), operands[1]));
4712 (define_expand "truncdfsf2_with_temp"
4713 [(parallel [(set (match_operand:SF 0 "" "")
4714 (float_truncate:SF (match_operand:DF 1 "" "")))
4715 (clobber (match_operand:SF 2 "" ""))])]
4718 (define_insn "*truncdfsf_fast_mixed"
4719 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4721 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4722 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4724 switch (which_alternative)
4727 return output_387_reg_move (insn, operands);
4729 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4734 [(set_attr "type" "fmov,ssecvt")
4735 (set_attr "prefix" "orig,maybe_vex")
4736 (set_attr "mode" "SF")])
4738 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4739 ;; because nothing we do here is unsafe.
4740 (define_insn "*truncdfsf_fast_sse"
4741 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4743 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4744 "TARGET_SSE2 && TARGET_SSE_MATH"
4745 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4746 [(set_attr "type" "ssecvt")
4747 (set_attr "prefix" "maybe_vex")
4748 (set_attr "mode" "SF")])
4750 (define_insn "*truncdfsf_fast_i387"
4751 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4753 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4754 "TARGET_80387 && flag_unsafe_math_optimizations"
4755 "* return output_387_reg_move (insn, operands);"
4756 [(set_attr "type" "fmov")
4757 (set_attr "mode" "SF")])
4759 (define_insn "*truncdfsf_mixed"
4760 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4762 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4763 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4764 "TARGET_MIX_SSE_I387"
4766 switch (which_alternative)
4769 return output_387_reg_move (insn, operands);
4771 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4777 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4778 (set_attr "unit" "*,*,i387,i387,i387")
4779 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4780 (set_attr "mode" "SF")])
4782 (define_insn "*truncdfsf_i387"
4783 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4785 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4786 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4789 switch (which_alternative)
4792 return output_387_reg_move (insn, operands);
4798 [(set_attr "type" "fmov,multi,multi,multi")
4799 (set_attr "unit" "*,i387,i387,i387")
4800 (set_attr "mode" "SF")])
4802 (define_insn "*truncdfsf2_i387_1"
4803 [(set (match_operand:SF 0 "memory_operand" "=m")
4805 (match_operand:DF 1 "register_operand" "f")))]
4807 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4808 && !TARGET_MIX_SSE_I387"
4809 "* return output_387_reg_move (insn, operands);"
4810 [(set_attr "type" "fmov")
4811 (set_attr "mode" "SF")])
4814 [(set (match_operand:SF 0 "register_operand" "")
4816 (match_operand:DF 1 "fp_register_operand" "")))
4817 (clobber (match_operand 2 "" ""))]
4819 [(set (match_dup 2) (match_dup 1))
4820 (set (match_dup 0) (match_dup 2))]
4822 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4825 ;; Conversion from XFmode to {SF,DF}mode
4827 (define_expand "truncxf<mode>2"
4828 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4829 (float_truncate:MODEF
4830 (match_operand:XF 1 "register_operand" "")))
4831 (clobber (match_dup 2))])]
4834 if (flag_unsafe_math_optimizations)
4836 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4837 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4838 if (reg != operands[0])
4839 emit_move_insn (operands[0], reg);
4844 enum ix86_stack_slot slot = (virtuals_instantiated
4847 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4851 (define_insn "*truncxfsf2_mixed"
4852 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4854 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4855 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4858 gcc_assert (!which_alternative);
4859 return output_387_reg_move (insn, operands);
4861 [(set_attr "type" "fmov,multi,multi,multi")
4862 (set_attr "unit" "*,i387,i387,i387")
4863 (set_attr "mode" "SF")])
4865 (define_insn "*truncxfdf2_mixed"
4866 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4868 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4869 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4872 gcc_assert (!which_alternative);
4873 return output_387_reg_move (insn, operands);
4875 [(set_attr "type" "fmov,multi,multi,multi")
4876 (set_attr "unit" "*,i387,i387,i387")
4877 (set_attr "mode" "DF")])
4879 (define_insn "truncxf<mode>2_i387_noop"
4880 [(set (match_operand:MODEF 0 "register_operand" "=f")
4881 (float_truncate:MODEF
4882 (match_operand:XF 1 "register_operand" "f")))]
4883 "TARGET_80387 && flag_unsafe_math_optimizations"
4884 "* return output_387_reg_move (insn, operands);"
4885 [(set_attr "type" "fmov")
4886 (set_attr "mode" "<MODE>")])
4888 (define_insn "*truncxf<mode>2_i387"
4889 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4890 (float_truncate:MODEF
4891 (match_operand:XF 1 "register_operand" "f")))]
4893 "* return output_387_reg_move (insn, operands);"
4894 [(set_attr "type" "fmov")
4895 (set_attr "mode" "<MODE>")])
4898 [(set (match_operand:MODEF 0 "register_operand" "")
4899 (float_truncate:MODEF
4900 (match_operand:XF 1 "register_operand" "")))
4901 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4902 "TARGET_80387 && reload_completed"
4903 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4904 (set (match_dup 0) (match_dup 2))]
4908 [(set (match_operand:MODEF 0 "memory_operand" "")
4909 (float_truncate:MODEF
4910 (match_operand:XF 1 "register_operand" "")))
4911 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4913 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4916 ;; Signed conversion to DImode.
4918 (define_expand "fix_truncxfdi2"
4919 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4920 (fix:DI (match_operand:XF 1 "register_operand" "")))
4921 (clobber (reg:CC FLAGS_REG))])]
4926 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4931 (define_expand "fix_trunc<mode>di2"
4932 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4934 (clobber (reg:CC FLAGS_REG))])]
4935 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4938 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4940 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4943 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4945 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4946 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4947 if (out != operands[0])
4948 emit_move_insn (operands[0], out);
4953 ;; Signed conversion to SImode.
4955 (define_expand "fix_truncxfsi2"
4956 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4957 (fix:SI (match_operand:XF 1 "register_operand" "")))
4958 (clobber (reg:CC FLAGS_REG))])]
4963 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4968 (define_expand "fix_trunc<mode>si2"
4969 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4970 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4971 (clobber (reg:CC FLAGS_REG))])]
4972 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4975 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4977 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4980 if (SSE_FLOAT_MODE_P (<MODE>mode))
4982 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4983 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4984 if (out != operands[0])
4985 emit_move_insn (operands[0], out);
4990 ;; Signed conversion to HImode.
4992 (define_expand "fix_trunc<mode>hi2"
4993 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4994 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4995 (clobber (reg:CC FLAGS_REG))])]
4997 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5001 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5006 ;; Unsigned conversion to SImode.
5008 (define_expand "fixuns_trunc<mode>si2"
5010 [(set (match_operand:SI 0 "register_operand" "")
5012 (match_operand:MODEF 1 "nonimmediate_operand" "")))
5014 (clobber (match_scratch:<ssevecmode> 3 ""))
5015 (clobber (match_scratch:<ssevecmode> 4 ""))])]
5016 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5018 enum machine_mode mode = <MODE>mode;
5019 enum machine_mode vecmode = <ssevecmode>mode;
5020 REAL_VALUE_TYPE TWO31r;
5023 if (optimize_insn_for_size_p ())
5026 real_ldexp (&TWO31r, &dconst1, 31);
5027 two31 = const_double_from_real_value (TWO31r, mode);
5028 two31 = ix86_build_const_vector (mode, true, two31);
5029 operands[2] = force_reg (vecmode, two31);
5032 (define_insn_and_split "*fixuns_trunc<mode>_1"
5033 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5035 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5036 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5037 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5038 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5039 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5040 && optimize_function_for_speed_p (cfun)"
5042 "&& reload_completed"
5045 ix86_split_convert_uns_si_sse (operands);
5049 ;; Unsigned conversion to HImode.
5050 ;; Without these patterns, we'll try the unsigned SI conversion which
5051 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5053 (define_expand "fixuns_trunc<mode>hi2"
5055 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5056 (set (match_operand:HI 0 "nonimmediate_operand" "")
5057 (subreg:HI (match_dup 2) 0))]
5058 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5059 "operands[2] = gen_reg_rtx (SImode);")
5061 ;; When SSE is available, it is always faster to use it!
5062 (define_insn "fix_trunc<mode>di_sse"
5063 [(set (match_operand:DI 0 "register_operand" "=r,r")
5064 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5065 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5066 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5067 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5068 [(set_attr "type" "sseicvt")
5069 (set_attr "prefix" "maybe_vex")
5070 (set_attr "prefix_rex" "1")
5071 (set_attr "mode" "<MODE>")
5072 (set_attr "athlon_decode" "double,vector")
5073 (set_attr "amdfam10_decode" "double,double")])
5075 (define_insn "fix_trunc<mode>si_sse"
5076 [(set (match_operand:SI 0 "register_operand" "=r,r")
5077 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5078 "SSE_FLOAT_MODE_P (<MODE>mode)
5079 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5080 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "prefix" "maybe_vex")
5083 (set_attr "mode" "<MODE>")
5084 (set_attr "athlon_decode" "double,vector")
5085 (set_attr "amdfam10_decode" "double,double")])
5087 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5089 [(set (match_operand:MODEF 0 "register_operand" "")
5090 (match_operand:MODEF 1 "memory_operand" ""))
5091 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5092 (fix:SSEMODEI24 (match_dup 0)))]
5093 "TARGET_SHORTEN_X87_SSE
5094 && peep2_reg_dead_p (2, operands[0])"
5095 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5098 ;; Avoid vector decoded forms of the instruction.
5100 [(match_scratch:DF 2 "Y2")
5101 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5102 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5103 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5104 [(set (match_dup 2) (match_dup 1))
5105 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5109 [(match_scratch:SF 2 "x")
5110 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5111 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5112 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5113 [(set (match_dup 2) (match_dup 1))
5114 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5117 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5118 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5119 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5120 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5122 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5123 && (TARGET_64BIT || <MODE>mode != DImode))
5125 && can_create_pseudo_p ()"
5130 if (memory_operand (operands[0], VOIDmode))
5131 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5134 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5135 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5141 [(set_attr "type" "fisttp")
5142 (set_attr "mode" "<MODE>")])
5144 (define_insn "fix_trunc<mode>_i387_fisttp"
5145 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5146 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5147 (clobber (match_scratch:XF 2 "=&1f"))]
5148 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5150 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5151 && (TARGET_64BIT || <MODE>mode != DImode))
5152 && TARGET_SSE_MATH)"
5153 "* return output_fix_trunc (insn, operands, 1);"
5154 [(set_attr "type" "fisttp")
5155 (set_attr "mode" "<MODE>")])
5157 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5158 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5159 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5160 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5161 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5162 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5164 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5165 && (TARGET_64BIT || <MODE>mode != DImode))
5166 && TARGET_SSE_MATH)"
5168 [(set_attr "type" "fisttp")
5169 (set_attr "mode" "<MODE>")])
5172 [(set (match_operand:X87MODEI 0 "register_operand" "")
5173 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5174 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5175 (clobber (match_scratch 3 ""))]
5177 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5178 (clobber (match_dup 3))])
5179 (set (match_dup 0) (match_dup 2))]
5183 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5184 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5185 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5186 (clobber (match_scratch 3 ""))]
5188 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5189 (clobber (match_dup 3))])]
5192 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5193 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5194 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5195 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5196 ;; function in i386.c.
5197 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5198 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5199 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5200 (clobber (reg:CC FLAGS_REG))]
5201 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5203 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5204 && (TARGET_64BIT || <MODE>mode != DImode))
5205 && can_create_pseudo_p ()"
5210 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5212 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5213 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5214 if (memory_operand (operands[0], VOIDmode))
5215 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5216 operands[2], operands[3]));
5219 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5220 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5221 operands[2], operands[3],
5226 [(set_attr "type" "fistp")
5227 (set_attr "i387_cw" "trunc")
5228 (set_attr "mode" "<MODE>")])
5230 (define_insn "fix_truncdi_i387"
5231 [(set (match_operand:DI 0 "memory_operand" "=m")
5232 (fix:DI (match_operand 1 "register_operand" "f")))
5233 (use (match_operand:HI 2 "memory_operand" "m"))
5234 (use (match_operand:HI 3 "memory_operand" "m"))
5235 (clobber (match_scratch:XF 4 "=&1f"))]
5236 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5238 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5239 "* return output_fix_trunc (insn, operands, 0);"
5240 [(set_attr "type" "fistp")
5241 (set_attr "i387_cw" "trunc")
5242 (set_attr "mode" "DI")])
5244 (define_insn "fix_truncdi_i387_with_temp"
5245 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5246 (fix:DI (match_operand 1 "register_operand" "f,f")))
5247 (use (match_operand:HI 2 "memory_operand" "m,m"))
5248 (use (match_operand:HI 3 "memory_operand" "m,m"))
5249 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5250 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5253 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5255 [(set_attr "type" "fistp")
5256 (set_attr "i387_cw" "trunc")
5257 (set_attr "mode" "DI")])
5260 [(set (match_operand:DI 0 "register_operand" "")
5261 (fix:DI (match_operand 1 "register_operand" "")))
5262 (use (match_operand:HI 2 "memory_operand" ""))
5263 (use (match_operand:HI 3 "memory_operand" ""))
5264 (clobber (match_operand:DI 4 "memory_operand" ""))
5265 (clobber (match_scratch 5 ""))]
5267 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5270 (clobber (match_dup 5))])
5271 (set (match_dup 0) (match_dup 4))]
5275 [(set (match_operand:DI 0 "memory_operand" "")
5276 (fix:DI (match_operand 1 "register_operand" "")))
5277 (use (match_operand:HI 2 "memory_operand" ""))
5278 (use (match_operand:HI 3 "memory_operand" ""))
5279 (clobber (match_operand:DI 4 "memory_operand" ""))
5280 (clobber (match_scratch 5 ""))]
5282 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5285 (clobber (match_dup 5))])]
5288 (define_insn "fix_trunc<mode>_i387"
5289 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5290 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5291 (use (match_operand:HI 2 "memory_operand" "m"))
5292 (use (match_operand:HI 3 "memory_operand" "m"))]
5293 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5295 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5296 "* return output_fix_trunc (insn, operands, 0);"
5297 [(set_attr "type" "fistp")
5298 (set_attr "i387_cw" "trunc")
5299 (set_attr "mode" "<MODE>")])
5301 (define_insn "fix_trunc<mode>_i387_with_temp"
5302 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5303 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5304 (use (match_operand:HI 2 "memory_operand" "m,m"))
5305 (use (match_operand:HI 3 "memory_operand" "m,m"))
5306 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5307 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5309 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5311 [(set_attr "type" "fistp")
5312 (set_attr "i387_cw" "trunc")
5313 (set_attr "mode" "<MODE>")])
5316 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5317 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5318 (use (match_operand:HI 2 "memory_operand" ""))
5319 (use (match_operand:HI 3 "memory_operand" ""))
5320 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5322 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5324 (use (match_dup 3))])
5325 (set (match_dup 0) (match_dup 4))]
5329 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5330 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5331 (use (match_operand:HI 2 "memory_operand" ""))
5332 (use (match_operand:HI 3 "memory_operand" ""))
5333 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5335 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5337 (use (match_dup 3))])]
5340 (define_insn "x86_fnstcw_1"
5341 [(set (match_operand:HI 0 "memory_operand" "=m")
5342 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5345 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5346 (set_attr "mode" "HI")
5347 (set_attr "unit" "i387")])
5349 (define_insn "x86_fldcw_1"
5350 [(set (reg:HI FPCR_REG)
5351 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5354 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5355 (set_attr "mode" "HI")
5356 (set_attr "unit" "i387")
5357 (set_attr "athlon_decode" "vector")
5358 (set_attr "amdfam10_decode" "vector")])
5360 ;; Conversion between fixed point and floating point.
5362 ;; Even though we only accept memory inputs, the backend _really_
5363 ;; wants to be able to do this between registers.
5365 (define_expand "floathi<mode>2"
5366 [(set (match_operand:X87MODEF 0 "register_operand" "")
5367 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5370 || TARGET_MIX_SSE_I387)"
5373 ;; Pre-reload splitter to add memory clobber to the pattern.
5374 (define_insn_and_split "*floathi<mode>2_1"
5375 [(set (match_operand:X87MODEF 0 "register_operand" "")
5376 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5379 || TARGET_MIX_SSE_I387)
5380 && can_create_pseudo_p ()"
5383 [(parallel [(set (match_dup 0)
5384 (float:X87MODEF (match_dup 1)))
5385 (clobber (match_dup 2))])]
5386 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5388 (define_insn "*floathi<mode>2_i387_with_temp"
5389 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5390 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5391 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5394 || TARGET_MIX_SSE_I387)"
5396 [(set_attr "type" "fmov,multi")
5397 (set_attr "mode" "<MODE>")
5398 (set_attr "unit" "*,i387")
5399 (set_attr "fp_int_src" "true")])
5401 (define_insn "*floathi<mode>2_i387"
5402 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5403 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5406 || TARGET_MIX_SSE_I387)"
5408 [(set_attr "type" "fmov")
5409 (set_attr "mode" "<MODE>")
5410 (set_attr "fp_int_src" "true")])
5413 [(set (match_operand:X87MODEF 0 "register_operand" "")
5414 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5415 (clobber (match_operand:HI 2 "memory_operand" ""))]
5417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5418 || TARGET_MIX_SSE_I387)
5419 && reload_completed"
5420 [(set (match_dup 2) (match_dup 1))
5421 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5425 [(set (match_operand:X87MODEF 0 "register_operand" "")
5426 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5427 (clobber (match_operand:HI 2 "memory_operand" ""))]
5429 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5430 || TARGET_MIX_SSE_I387)
5431 && reload_completed"
5432 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5435 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5436 [(set (match_operand:X87MODEF 0 "register_operand" "")
5438 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5440 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5441 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5444 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5445 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5446 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5448 rtx reg = gen_reg_rtx (XFmode);
5449 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5450 /* Avoid references to nonexistent function in dead code in XFmode case. */
5451 #define gen_truncxfxf2 gen_truncxfdf2
5452 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5453 #undef gen_truncxfxf2
5458 ;; Pre-reload splitter to add memory clobber to the pattern.
5459 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5460 [(set (match_operand:X87MODEF 0 "register_operand" "")
5461 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5463 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5464 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5466 || TARGET_MIX_SSE_I387))
5467 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5469 && ((<SSEMODEI24:MODE>mode == SImode
5470 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5471 && optimize_function_for_speed_p (cfun)
5472 && flag_trapping_math)
5473 || !(TARGET_INTER_UNIT_CONVERSIONS
5474 || optimize_function_for_size_p (cfun)))))
5475 && can_create_pseudo_p ()"
5478 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5479 (clobber (match_dup 2))])]
5481 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5483 /* Avoid store forwarding (partial memory) stall penalty
5484 by passing DImode value through XMM registers. */
5485 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5486 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5487 && optimize_function_for_speed_p (cfun))
5489 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5496 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5497 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5499 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5500 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5501 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5502 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5504 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5505 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5506 (set_attr "unit" "*,i387,*,*,*")
5507 (set_attr "athlon_decode" "*,*,double,direct,double")
5508 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5509 (set_attr "fp_int_src" "true")])
5511 (define_insn "*floatsi<mode>2_vector_mixed"
5512 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5513 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5514 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5515 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5519 [(set_attr "type" "fmov,sseicvt")
5520 (set_attr "mode" "<MODE>,<ssevecmode>")
5521 (set_attr "unit" "i387,*")
5522 (set_attr "athlon_decode" "*,direct")
5523 (set_attr "amdfam10_decode" "*,double")
5524 (set_attr "fp_int_src" "true")])
5526 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5527 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5529 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5530 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5531 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5532 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5534 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5535 (set_attr "mode" "<MODEF:MODE>")
5536 (set_attr "unit" "*,i387,*,*")
5537 (set_attr "athlon_decode" "*,*,double,direct")
5538 (set_attr "amdfam10_decode" "*,*,vector,double")
5539 (set_attr "fp_int_src" "true")])
5542 [(set (match_operand:MODEF 0 "register_operand" "")
5543 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5544 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5546 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5547 && TARGET_INTER_UNIT_CONVERSIONS
5549 && (SSE_REG_P (operands[0])
5550 || (GET_CODE (operands[0]) == SUBREG
5551 && SSE_REG_P (operands[0])))"
5552 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5556 [(set (match_operand:MODEF 0 "register_operand" "")
5557 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5558 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5559 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5560 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5561 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5563 && (SSE_REG_P (operands[0])
5564 || (GET_CODE (operands[0]) == SUBREG
5565 && SSE_REG_P (operands[0])))"
5566 [(set (match_dup 2) (match_dup 1))
5567 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5570 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5571 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5573 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5574 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5575 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5576 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5579 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5580 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5581 [(set_attr "type" "fmov,sseicvt,sseicvt")
5582 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5583 (set_attr "mode" "<MODEF:MODE>")
5584 (set (attr "prefix_rex")
5586 (and (eq_attr "prefix" "maybe_vex")
5587 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5589 (const_string "*")))
5590 (set_attr "unit" "i387,*,*")
5591 (set_attr "athlon_decode" "*,double,direct")
5592 (set_attr "amdfam10_decode" "*,vector,double")
5593 (set_attr "fp_int_src" "true")])
5595 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5596 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5598 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5599 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5600 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5601 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5604 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5605 [(set_attr "type" "fmov,sseicvt")
5606 (set_attr "prefix" "orig,maybe_vex")
5607 (set_attr "mode" "<MODEF:MODE>")
5608 (set (attr "prefix_rex")
5610 (and (eq_attr "prefix" "maybe_vex")
5611 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5613 (const_string "*")))
5614 (set_attr "athlon_decode" "*,direct")
5615 (set_attr "amdfam10_decode" "*,double")
5616 (set_attr "fp_int_src" "true")])
5618 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5619 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5621 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5622 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5623 "TARGET_SSE2 && TARGET_SSE_MATH
5624 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5626 [(set_attr "type" "sseicvt")
5627 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5628 (set_attr "athlon_decode" "double,direct,double")
5629 (set_attr "amdfam10_decode" "vector,double,double")
5630 (set_attr "fp_int_src" "true")])
5632 (define_insn "*floatsi<mode>2_vector_sse"
5633 [(set (match_operand:MODEF 0 "register_operand" "=x")
5634 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5635 "TARGET_SSE2 && TARGET_SSE_MATH
5636 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5638 [(set_attr "type" "sseicvt")
5639 (set_attr "mode" "<MODE>")
5640 (set_attr "athlon_decode" "direct")
5641 (set_attr "amdfam10_decode" "double")
5642 (set_attr "fp_int_src" "true")])
5645 [(set (match_operand:MODEF 0 "register_operand" "")
5646 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5647 (clobber (match_operand:SI 2 "memory_operand" ""))]
5648 "TARGET_SSE2 && TARGET_SSE_MATH
5649 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5651 && (SSE_REG_P (operands[0])
5652 || (GET_CODE (operands[0]) == SUBREG
5653 && SSE_REG_P (operands[0])))"
5656 rtx op1 = operands[1];
5658 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5660 if (GET_CODE (op1) == SUBREG)
5661 op1 = SUBREG_REG (op1);
5663 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5665 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5666 emit_insn (gen_sse2_loadld (operands[4],
5667 CONST0_RTX (V4SImode), operands[1]));
5669 /* We can ignore possible trapping value in the
5670 high part of SSE register for non-trapping math. */
5671 else if (SSE_REG_P (op1) && !flag_trapping_math)
5672 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5675 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5676 emit_move_insn (operands[2], operands[1]);
5677 emit_insn (gen_sse2_loadld (operands[4],
5678 CONST0_RTX (V4SImode), operands[2]));
5681 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5686 [(set (match_operand:MODEF 0 "register_operand" "")
5687 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5688 (clobber (match_operand:SI 2 "memory_operand" ""))]
5689 "TARGET_SSE2 && TARGET_SSE_MATH
5690 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5692 && (SSE_REG_P (operands[0])
5693 || (GET_CODE (operands[0]) == SUBREG
5694 && SSE_REG_P (operands[0])))"
5697 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5699 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5701 emit_insn (gen_sse2_loadld (operands[4],
5702 CONST0_RTX (V4SImode), operands[1]));
5704 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5709 [(set (match_operand:MODEF 0 "register_operand" "")
5710 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5711 "TARGET_SSE2 && TARGET_SSE_MATH
5712 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5714 && (SSE_REG_P (operands[0])
5715 || (GET_CODE (operands[0]) == SUBREG
5716 && SSE_REG_P (operands[0])))"
5719 rtx op1 = operands[1];
5721 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5723 if (GET_CODE (op1) == SUBREG)
5724 op1 = SUBREG_REG (op1);
5726 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5728 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5729 emit_insn (gen_sse2_loadld (operands[4],
5730 CONST0_RTX (V4SImode), operands[1]));
5732 /* We can ignore possible trapping value in the
5733 high part of SSE register for non-trapping math. */
5734 else if (SSE_REG_P (op1) && !flag_trapping_math)
5735 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5739 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5744 [(set (match_operand:MODEF 0 "register_operand" "")
5745 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5746 "TARGET_SSE2 && TARGET_SSE_MATH
5747 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5749 && (SSE_REG_P (operands[0])
5750 || (GET_CODE (operands[0]) == SUBREG
5751 && SSE_REG_P (operands[0])))"
5754 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5756 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5758 emit_insn (gen_sse2_loadld (operands[4],
5759 CONST0_RTX (V4SImode), operands[1]));
5761 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5765 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5766 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5768 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5769 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5770 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5771 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5773 [(set_attr "type" "sseicvt")
5774 (set_attr "mode" "<MODEF:MODE>")
5775 (set_attr "athlon_decode" "double,direct")
5776 (set_attr "amdfam10_decode" "vector,double")
5777 (set_attr "fp_int_src" "true")])
5779 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5780 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5782 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5783 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5784 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5785 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5786 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5787 [(set_attr "type" "sseicvt")
5788 (set_attr "prefix" "maybe_vex")
5789 (set_attr "mode" "<MODEF:MODE>")
5790 (set (attr "prefix_rex")
5792 (and (eq_attr "prefix" "maybe_vex")
5793 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5795 (const_string "*")))
5796 (set_attr "athlon_decode" "double,direct")
5797 (set_attr "amdfam10_decode" "vector,double")
5798 (set_attr "fp_int_src" "true")])
5801 [(set (match_operand:MODEF 0 "register_operand" "")
5802 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5803 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5804 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5805 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5806 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5808 && (SSE_REG_P (operands[0])
5809 || (GET_CODE (operands[0]) == SUBREG
5810 && SSE_REG_P (operands[0])))"
5811 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5814 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5815 [(set (match_operand:MODEF 0 "register_operand" "=x")
5817 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5818 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5819 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5820 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5821 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5822 [(set_attr "type" "sseicvt")
5823 (set_attr "prefix" "maybe_vex")
5824 (set_attr "mode" "<MODEF:MODE>")
5825 (set (attr "prefix_rex")
5827 (and (eq_attr "prefix" "maybe_vex")
5828 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5830 (const_string "*")))
5831 (set_attr "athlon_decode" "direct")
5832 (set_attr "amdfam10_decode" "double")
5833 (set_attr "fp_int_src" "true")])
5836 [(set (match_operand:MODEF 0 "register_operand" "")
5837 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5838 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5839 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5840 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5841 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5843 && (SSE_REG_P (operands[0])
5844 || (GET_CODE (operands[0]) == SUBREG
5845 && SSE_REG_P (operands[0])))"
5846 [(set (match_dup 2) (match_dup 1))
5847 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5851 [(set (match_operand:MODEF 0 "register_operand" "")
5852 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5853 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5854 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5855 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5857 && (SSE_REG_P (operands[0])
5858 || (GET_CODE (operands[0]) == SUBREG
5859 && SSE_REG_P (operands[0])))"
5860 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5863 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5864 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5866 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5867 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5869 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5873 [(set_attr "type" "fmov,multi")
5874 (set_attr "mode" "<X87MODEF:MODE>")
5875 (set_attr "unit" "*,i387")
5876 (set_attr "fp_int_src" "true")])
5878 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5879 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5881 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5883 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5885 [(set_attr "type" "fmov")
5886 (set_attr "mode" "<X87MODEF:MODE>")
5887 (set_attr "fp_int_src" "true")])
5890 [(set (match_operand:X87MODEF 0 "register_operand" "")
5891 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5892 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5894 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5896 && FP_REG_P (operands[0])"
5897 [(set (match_dup 2) (match_dup 1))
5898 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5902 [(set (match_operand:X87MODEF 0 "register_operand" "")
5903 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5904 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5906 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5908 && FP_REG_P (operands[0])"
5909 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5912 ;; Avoid store forwarding (partial memory) stall penalty
5913 ;; by passing DImode value through XMM registers. */
5915 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5916 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5918 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5919 (clobber (match_scratch:V4SI 3 "=X,x"))
5920 (clobber (match_scratch:V4SI 4 "=X,x"))
5921 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5922 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5923 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5924 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5926 [(set_attr "type" "multi")
5927 (set_attr "mode" "<X87MODEF:MODE>")
5928 (set_attr "unit" "i387")
5929 (set_attr "fp_int_src" "true")])
5932 [(set (match_operand:X87MODEF 0 "register_operand" "")
5933 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5934 (clobber (match_scratch:V4SI 3 ""))
5935 (clobber (match_scratch:V4SI 4 ""))
5936 (clobber (match_operand:DI 2 "memory_operand" ""))]
5937 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5938 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5939 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5941 && FP_REG_P (operands[0])"
5942 [(set (match_dup 2) (match_dup 3))
5943 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5945 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5946 Assemble the 64-bit DImode value in an xmm register. */
5947 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5948 gen_rtx_SUBREG (SImode, operands[1], 0)));
5949 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5950 gen_rtx_SUBREG (SImode, operands[1], 4)));
5951 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5953 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5957 [(set (match_operand:X87MODEF 0 "register_operand" "")
5958 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5959 (clobber (match_scratch:V4SI 3 ""))
5960 (clobber (match_scratch:V4SI 4 ""))
5961 (clobber (match_operand:DI 2 "memory_operand" ""))]
5962 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5963 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5964 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5966 && FP_REG_P (operands[0])"
5967 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5970 ;; Avoid store forwarding (partial memory) stall penalty by extending
5971 ;; SImode value to DImode through XMM register instead of pushing two
5972 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5973 ;; targets benefit from this optimization. Also note that fild
5974 ;; loads from memory only.
5976 (define_insn "*floatunssi<mode>2_1"
5977 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5978 (unsigned_float:X87MODEF
5979 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5980 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5981 (clobber (match_scratch:SI 3 "=X,x"))]
5983 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5986 [(set_attr "type" "multi")
5987 (set_attr "mode" "<MODE>")])
5990 [(set (match_operand:X87MODEF 0 "register_operand" "")
5991 (unsigned_float:X87MODEF
5992 (match_operand:SI 1 "register_operand" "")))
5993 (clobber (match_operand:DI 2 "memory_operand" ""))
5994 (clobber (match_scratch:SI 3 ""))]
5996 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5998 && reload_completed"
5999 [(set (match_dup 2) (match_dup 1))
6001 (float:X87MODEF (match_dup 2)))]
6002 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6005 [(set (match_operand:X87MODEF 0 "register_operand" "")
6006 (unsigned_float:X87MODEF
6007 (match_operand:SI 1 "memory_operand" "")))
6008 (clobber (match_operand:DI 2 "memory_operand" ""))
6009 (clobber (match_scratch:SI 3 ""))]
6011 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6013 && reload_completed"
6014 [(set (match_dup 2) (match_dup 3))
6016 (float:X87MODEF (match_dup 2)))]
6018 emit_move_insn (operands[3], operands[1]);
6019 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6022 (define_expand "floatunssi<mode>2"
6024 [(set (match_operand:X87MODEF 0 "register_operand" "")
6025 (unsigned_float:X87MODEF
6026 (match_operand:SI 1 "nonimmediate_operand" "")))
6027 (clobber (match_dup 2))
6028 (clobber (match_scratch:SI 3 ""))])]
6030 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6032 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6034 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6036 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6041 enum ix86_stack_slot slot = (virtuals_instantiated
6044 operands[2] = assign_386_stack_local (DImode, slot);
6048 (define_expand "floatunsdisf2"
6049 [(use (match_operand:SF 0 "register_operand" ""))
6050 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6051 "TARGET_64BIT && TARGET_SSE_MATH"
6052 "x86_emit_floatuns (operands); DONE;")
6054 (define_expand "floatunsdidf2"
6055 [(use (match_operand:DF 0 "register_operand" ""))
6056 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6057 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6058 && TARGET_SSE2 && TARGET_SSE_MATH"
6061 x86_emit_floatuns (operands);
6063 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6069 ;; %%% splits for addditi3
6071 (define_expand "addti3"
6072 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6073 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6074 (match_operand:TI 2 "x86_64_general_operand" "")))]
6076 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6078 (define_insn "*addti3_1"
6079 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6080 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
6081 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6082 (clobber (reg:CC FLAGS_REG))]
6083 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6087 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6088 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6089 (match_operand:TI 2 "x86_64_general_operand" "")))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "TARGET_64BIT && reload_completed"
6092 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6094 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6095 (parallel [(set (match_dup 3)
6096 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6099 (clobber (reg:CC FLAGS_REG))])]
6100 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
6102 ;; %%% splits for addsidi3
6103 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
6104 ; (plus:DI (match_operand:DI 1 "general_operand" "")
6105 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
6107 (define_expand "adddi3"
6108 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6109 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6110 (match_operand:DI 2 "x86_64_general_operand" "")))]
6112 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6114 (define_insn "*adddi3_1"
6115 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6116 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6117 (match_operand:DI 2 "general_operand" "roiF,riF")))
6118 (clobber (reg:CC FLAGS_REG))]
6119 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6124 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6125 (match_operand:DI 2 "general_operand" "")))
6126 (clobber (reg:CC FLAGS_REG))]
6127 "!TARGET_64BIT && reload_completed"
6128 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6130 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6131 (parallel [(set (match_dup 3)
6132 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6135 (clobber (reg:CC FLAGS_REG))])]
6136 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6138 (define_insn "adddi3_carry_rex64"
6139 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6140 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6141 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6142 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6145 "adc{q}\t{%2, %0|%0, %2}"
6146 [(set_attr "type" "alu")
6147 (set_attr "use_carry" "1")
6148 (set_attr "pent_pair" "pu")
6149 (set_attr "mode" "DI")])
6151 (define_insn "*adddi3_cc_rex64"
6152 [(set (reg:CC FLAGS_REG)
6153 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6154 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6156 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6157 (plus:DI (match_dup 1) (match_dup 2)))]
6158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6159 "add{q}\t{%2, %0|%0, %2}"
6160 [(set_attr "type" "alu")
6161 (set_attr "mode" "DI")])
6163 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6164 [(set (reg:CCC FLAGS_REG)
6167 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6168 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6170 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6171 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6173 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6174 [(set_attr "type" "alu")
6175 (set_attr "mode" "<MODE>")])
6177 (define_insn "*add<mode>3_cconly_overflow"
6178 [(set (reg:CCC FLAGS_REG)
6180 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6181 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6183 (clobber (match_scratch:SWI 0 "=<r>"))]
6184 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6185 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6186 [(set_attr "type" "alu")
6187 (set_attr "mode" "<MODE>")])
6189 (define_insn "*sub<mode>3_cconly_overflow"
6190 [(set (reg:CCC FLAGS_REG)
6192 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6193 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6196 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6197 [(set_attr "type" "icmp")
6198 (set_attr "mode" "<MODE>")])
6200 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6201 [(set (reg:CCC FLAGS_REG)
6203 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6204 (match_operand:SI 2 "general_operand" "g"))
6206 (set (match_operand:DI 0 "register_operand" "=r")
6207 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6208 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6209 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6210 [(set_attr "type" "alu")
6211 (set_attr "mode" "SI")])
6213 (define_insn "addqi3_carry"
6214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6215 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6216 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6217 (match_operand:QI 2 "general_operand" "qn,qm")))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6220 "adc{b}\t{%2, %0|%0, %2}"
6221 [(set_attr "type" "alu")
6222 (set_attr "use_carry" "1")
6223 (set_attr "pent_pair" "pu")
6224 (set_attr "mode" "QI")])
6226 (define_insn "addhi3_carry"
6227 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6228 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6229 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6230 (match_operand:HI 2 "general_operand" "rn,rm")))
6231 (clobber (reg:CC FLAGS_REG))]
6232 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6233 "adc{w}\t{%2, %0|%0, %2}"
6234 [(set_attr "type" "alu")
6235 (set_attr "use_carry" "1")
6236 (set_attr "pent_pair" "pu")
6237 (set_attr "mode" "HI")])
6239 (define_insn "addsi3_carry"
6240 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6241 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6242 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6243 (match_operand:SI 2 "general_operand" "ri,rm")))
6244 (clobber (reg:CC FLAGS_REG))]
6245 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6246 "adc{l}\t{%2, %0|%0, %2}"
6247 [(set_attr "type" "alu")
6248 (set_attr "use_carry" "1")
6249 (set_attr "pent_pair" "pu")
6250 (set_attr "mode" "SI")])
6252 (define_insn "*addsi3_carry_zext"
6253 [(set (match_operand:DI 0 "register_operand" "=r")
6255 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6256 (match_operand:SI 1 "nonimmediate_operand" "%0"))
6257 (match_operand:SI 2 "general_operand" "g"))))
6258 (clobber (reg:CC FLAGS_REG))]
6259 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6260 "adc{l}\t{%2, %k0|%k0, %2}"
6261 [(set_attr "type" "alu")
6262 (set_attr "use_carry" "1")
6263 (set_attr "pent_pair" "pu")
6264 (set_attr "mode" "SI")])
6266 (define_insn "*addsi3_cc"
6267 [(set (reg:CC FLAGS_REG)
6268 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6269 (match_operand:SI 2 "general_operand" "ri,rm")]
6271 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6272 (plus:SI (match_dup 1) (match_dup 2)))]
6273 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6274 "add{l}\t{%2, %0|%0, %2}"
6275 [(set_attr "type" "alu")
6276 (set_attr "mode" "SI")])
6278 (define_insn "addqi3_cc"
6279 [(set (reg:CC FLAGS_REG)
6280 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6281 (match_operand:QI 2 "general_operand" "qn,qm")]
6283 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6284 (plus:QI (match_dup 1) (match_dup 2)))]
6285 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6286 "add{b}\t{%2, %0|%0, %2}"
6287 [(set_attr "type" "alu")
6288 (set_attr "mode" "QI")])
6290 (define_expand "addsi3"
6291 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6292 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6293 (match_operand:SI 2 "general_operand" "")))]
6295 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6297 (define_insn "*lea_1"
6298 [(set (match_operand:SI 0 "register_operand" "=r")
6299 (match_operand:SI 1 "no_seg_address_operand" "p"))]
6301 "lea{l}\t{%a1, %0|%0, %a1}"
6302 [(set_attr "type" "lea")
6303 (set_attr "mode" "SI")])
6305 (define_insn "*lea_1_rex64"
6306 [(set (match_operand:SI 0 "register_operand" "=r")
6307 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6309 "lea{l}\t{%a1, %0|%0, %a1}"
6310 [(set_attr "type" "lea")
6311 (set_attr "mode" "SI")])
6313 (define_insn "*lea_1_zext"
6314 [(set (match_operand:DI 0 "register_operand" "=r")
6316 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6318 "lea{l}\t{%a1, %k0|%k0, %a1}"
6319 [(set_attr "type" "lea")
6320 (set_attr "mode" "SI")])
6322 (define_insn "*lea_2_rex64"
6323 [(set (match_operand:DI 0 "register_operand" "=r")
6324 (match_operand:DI 1 "no_seg_address_operand" "p"))]
6326 "lea{q}\t{%a1, %0|%0, %a1}"
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "DI")])
6330 ;; The lea patterns for non-Pmodes needs to be matched by several
6331 ;; insns converted to real lea by splitters.
6333 (define_insn_and_split "*lea_general_1"
6334 [(set (match_operand 0 "register_operand" "=r")
6335 (plus (plus (match_operand 1 "index_register_operand" "l")
6336 (match_operand 2 "register_operand" "r"))
6337 (match_operand 3 "immediate_operand" "i")))]
6338 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6339 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6341 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6342 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6343 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6344 || GET_MODE (operands[3]) == VOIDmode)"
6346 "&& reload_completed"
6350 operands[0] = gen_lowpart (SImode, operands[0]);
6351 operands[1] = gen_lowpart (Pmode, operands[1]);
6352 operands[2] = gen_lowpart (Pmode, operands[2]);
6353 operands[3] = gen_lowpart (Pmode, operands[3]);
6354 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6356 if (Pmode != SImode)
6357 pat = gen_rtx_SUBREG (SImode, pat, 0);
6358 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6361 [(set_attr "type" "lea")
6362 (set_attr "mode" "SI")])
6364 (define_insn_and_split "*lea_general_1_zext"
6365 [(set (match_operand:DI 0 "register_operand" "=r")
6367 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6368 (match_operand:SI 2 "register_operand" "r"))
6369 (match_operand:SI 3 "immediate_operand" "i"))))]
6372 "&& reload_completed"
6374 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6376 (match_dup 3)) 0)))]
6378 operands[1] = gen_lowpart (Pmode, operands[1]);
6379 operands[2] = gen_lowpart (Pmode, operands[2]);
6380 operands[3] = gen_lowpart (Pmode, operands[3]);
6382 [(set_attr "type" "lea")
6383 (set_attr "mode" "SI")])
6385 (define_insn_and_split "*lea_general_2"
6386 [(set (match_operand 0 "register_operand" "=r")
6387 (plus (mult (match_operand 1 "index_register_operand" "l")
6388 (match_operand 2 "const248_operand" "i"))
6389 (match_operand 3 "nonmemory_operand" "ri")))]
6390 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6391 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6392 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6393 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6394 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6395 || GET_MODE (operands[3]) == VOIDmode)"
6397 "&& reload_completed"
6401 operands[0] = gen_lowpart (SImode, operands[0]);
6402 operands[1] = gen_lowpart (Pmode, operands[1]);
6403 operands[3] = gen_lowpart (Pmode, operands[3]);
6404 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6406 if (Pmode != SImode)
6407 pat = gen_rtx_SUBREG (SImode, pat, 0);
6408 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6411 [(set_attr "type" "lea")
6412 (set_attr "mode" "SI")])
6414 (define_insn_and_split "*lea_general_2_zext"
6415 [(set (match_operand:DI 0 "register_operand" "=r")
6417 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6418 (match_operand:SI 2 "const248_operand" "n"))
6419 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6422 "&& reload_completed"
6424 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6426 (match_dup 3)) 0)))]
6428 operands[1] = gen_lowpart (Pmode, operands[1]);
6429 operands[3] = gen_lowpart (Pmode, operands[3]);
6431 [(set_attr "type" "lea")
6432 (set_attr "mode" "SI")])
6434 (define_insn_and_split "*lea_general_3"
6435 [(set (match_operand 0 "register_operand" "=r")
6436 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6437 (match_operand 2 "const248_operand" "i"))
6438 (match_operand 3 "register_operand" "r"))
6439 (match_operand 4 "immediate_operand" "i")))]
6440 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6441 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6442 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6443 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6444 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6446 "&& reload_completed"
6450 operands[0] = gen_lowpart (SImode, operands[0]);
6451 operands[1] = gen_lowpart (Pmode, operands[1]);
6452 operands[3] = gen_lowpart (Pmode, operands[3]);
6453 operands[4] = gen_lowpart (Pmode, operands[4]);
6454 pat = gen_rtx_PLUS (Pmode,
6455 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6459 if (Pmode != SImode)
6460 pat = gen_rtx_SUBREG (SImode, pat, 0);
6461 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6467 (define_insn_and_split "*lea_general_3_zext"
6468 [(set (match_operand:DI 0 "register_operand" "=r")
6470 (plus:SI (plus:SI (mult:SI
6471 (match_operand:SI 1 "index_register_operand" "l")
6472 (match_operand:SI 2 "const248_operand" "n"))
6473 (match_operand:SI 3 "register_operand" "r"))
6474 (match_operand:SI 4 "immediate_operand" "i"))))]
6477 "&& reload_completed"
6479 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6482 (match_dup 4)) 0)))]
6484 operands[1] = gen_lowpart (Pmode, operands[1]);
6485 operands[3] = gen_lowpart (Pmode, operands[3]);
6486 operands[4] = gen_lowpart (Pmode, operands[4]);
6488 [(set_attr "type" "lea")
6489 (set_attr "mode" "SI")])
6491 (define_insn "*adddi_1_rex64"
6492 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6493 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6494 (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6498 switch (get_attr_type (insn))
6501 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6502 return "lea{q}\t{%a2, %0|%0, %a2}";
6505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6506 if (operands[2] == const1_rtx)
6507 return "inc{q}\t%0";
6510 gcc_assert (operands[2] == constm1_rtx);
6511 return "dec{q}\t%0";
6515 /* Use add as much as possible to replace lea for AGU optimization. */
6516 if (which_alternative == 2 && TARGET_OPT_AGU)
6517 return "add{q}\t{%1, %0|%0, %1}";
6519 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6521 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6522 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6523 if (CONST_INT_P (operands[2])
6524 /* Avoid overflows. */
6525 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6526 && (INTVAL (operands[2]) == 128
6527 || (INTVAL (operands[2]) < 0
6528 && INTVAL (operands[2]) != -128)))
6530 operands[2] = GEN_INT (-INTVAL (operands[2]));
6531 return "sub{q}\t{%2, %0|%0, %2}";
6533 return "add{q}\t{%2, %0|%0, %2}";
6537 (cond [(and (eq_attr "alternative" "2")
6538 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6539 (const_string "lea")
6540 (eq_attr "alternative" "3")
6541 (const_string "lea")
6542 ; Current assemblers are broken and do not allow @GOTOFF in
6543 ; ought but a memory context.
6544 (match_operand:DI 2 "pic_symbolic_operand" "")
6545 (const_string "lea")
6546 (match_operand:DI 2 "incdec_operand" "")
6547 (const_string "incdec")
6549 (const_string "alu")))
6550 (set (attr "length_immediate")
6552 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6554 (const_string "*")))
6555 (set_attr "mode" "DI")])
6557 ;; Convert lea to the lea pattern to avoid flags dependency.
6559 [(set (match_operand:DI 0 "register_operand" "")
6560 (plus:DI (match_operand:DI 1 "register_operand" "")
6561 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "TARGET_64BIT && reload_completed
6564 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6566 (plus:DI (match_dup 1)
6570 (define_insn "*adddi_2_rex64"
6571 [(set (reg FLAGS_REG)
6573 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6574 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6576 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6577 (plus:DI (match_dup 1) (match_dup 2)))]
6578 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6579 && ix86_binary_operator_ok (PLUS, DImode, operands)
6580 /* Current assemblers are broken and do not allow @GOTOFF in
6581 ought but a memory context. */
6582 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6584 switch (get_attr_type (insn))
6587 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6588 if (operands[2] == const1_rtx)
6589 return "inc{q}\t%0";
6592 gcc_assert (operands[2] == constm1_rtx);
6593 return "dec{q}\t%0";
6597 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6598 /* ???? We ought to handle there the 32bit case too
6599 - do we need new constraint? */
6600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6602 if (CONST_INT_P (operands[2])
6603 /* Avoid overflows. */
6604 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6605 && (INTVAL (operands[2]) == 128
6606 || (INTVAL (operands[2]) < 0
6607 && INTVAL (operands[2]) != -128)))
6609 operands[2] = GEN_INT (-INTVAL (operands[2]));
6610 return "sub{q}\t{%2, %0|%0, %2}";
6612 return "add{q}\t{%2, %0|%0, %2}";
6616 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6617 (const_string "incdec")
6618 (const_string "alu")))
6619 (set (attr "length_immediate")
6621 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6623 (const_string "*")))
6624 (set_attr "mode" "DI")])
6626 (define_insn "*adddi_3_rex64"
6627 [(set (reg FLAGS_REG)
6628 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6629 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6630 (clobber (match_scratch:DI 0 "=r"))]
6632 && ix86_match_ccmode (insn, CCZmode)
6633 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6634 /* Current assemblers are broken and do not allow @GOTOFF in
6635 ought but a memory context. */
6636 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6638 switch (get_attr_type (insn))
6641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6642 if (operands[2] == const1_rtx)
6643 return "inc{q}\t%0";
6646 gcc_assert (operands[2] == constm1_rtx);
6647 return "dec{q}\t%0";
6651 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652 /* ???? We ought to handle there the 32bit case too
6653 - do we need new constraint? */
6654 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6655 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6656 if (CONST_INT_P (operands[2])
6657 /* Avoid overflows. */
6658 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6659 && (INTVAL (operands[2]) == 128
6660 || (INTVAL (operands[2]) < 0
6661 && INTVAL (operands[2]) != -128)))
6663 operands[2] = GEN_INT (-INTVAL (operands[2]));
6664 return "sub{q}\t{%2, %0|%0, %2}";
6666 return "add{q}\t{%2, %0|%0, %2}";
6670 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6671 (const_string "incdec")
6672 (const_string "alu")))
6673 (set (attr "length_immediate")
6675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6677 (const_string "*")))
6678 (set_attr "mode" "DI")])
6680 ; For comparisons against 1, -1 and 128, we may generate better code
6681 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6682 ; is matched then. We can't accept general immediate, because for
6683 ; case of overflows, the result is messed up.
6684 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6686 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6687 ; only for comparisons not depending on it.
6688 (define_insn "*adddi_4_rex64"
6689 [(set (reg FLAGS_REG)
6690 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6691 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6692 (clobber (match_scratch:DI 0 "=rm"))]
6694 && ix86_match_ccmode (insn, CCGCmode)"
6696 switch (get_attr_type (insn))
6699 if (operands[2] == constm1_rtx)
6700 return "inc{q}\t%0";
6703 gcc_assert (operands[2] == const1_rtx);
6704 return "dec{q}\t%0";
6708 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6709 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6710 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6711 if ((INTVAL (operands[2]) == -128
6712 || (INTVAL (operands[2]) > 0
6713 && INTVAL (operands[2]) != 128))
6714 /* Avoid overflows. */
6715 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6716 return "sub{q}\t{%2, %0|%0, %2}";
6717 operands[2] = GEN_INT (-INTVAL (operands[2]));
6718 return "add{q}\t{%2, %0|%0, %2}";
6722 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6723 (const_string "incdec")
6724 (const_string "alu")))
6725 (set (attr "length_immediate")
6727 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6729 (const_string "*")))
6730 (set_attr "mode" "DI")])
6732 (define_insn "*adddi_5_rex64"
6733 [(set (reg FLAGS_REG)
6735 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6736 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6738 (clobber (match_scratch:DI 0 "=r"))]
6740 && ix86_match_ccmode (insn, CCGOCmode)
6741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6742 /* Current assemblers are broken and do not allow @GOTOFF in
6743 ought but a memory context. */
6744 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6746 switch (get_attr_type (insn))
6749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6750 if (operands[2] == const1_rtx)
6751 return "inc{q}\t%0";
6754 gcc_assert (operands[2] == constm1_rtx);
6755 return "dec{q}\t%0";
6759 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6760 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6761 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6762 if (CONST_INT_P (operands[2])
6763 /* Avoid overflows. */
6764 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6765 && (INTVAL (operands[2]) == 128
6766 || (INTVAL (operands[2]) < 0
6767 && INTVAL (operands[2]) != -128)))
6769 operands[2] = GEN_INT (-INTVAL (operands[2]));
6770 return "sub{q}\t{%2, %0|%0, %2}";
6772 return "add{q}\t{%2, %0|%0, %2}";
6776 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6777 (const_string "incdec")
6778 (const_string "alu")))
6779 (set (attr "length_immediate")
6781 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6783 (const_string "*")))
6784 (set_attr "mode" "DI")])
6787 (define_insn "*addsi_1"
6788 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6789 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6790 (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6794 switch (get_attr_type (insn))
6797 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6798 return "lea{l}\t{%a2, %0|%0, %a2}";
6801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802 if (operands[2] == const1_rtx)
6803 return "inc{l}\t%0";
6806 gcc_assert (operands[2] == constm1_rtx);
6807 return "dec{l}\t%0";
6811 /* Use add as much as possible to replace lea for AGU optimization. */
6812 if (which_alternative == 2 && TARGET_OPT_AGU)
6813 return "add{l}\t{%1, %0|%0, %1}";
6815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6817 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6818 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6819 if (CONST_INT_P (operands[2])
6820 && (INTVAL (operands[2]) == 128
6821 || (INTVAL (operands[2]) < 0
6822 && INTVAL (operands[2]) != -128)))
6824 operands[2] = GEN_INT (-INTVAL (operands[2]));
6825 return "sub{l}\t{%2, %0|%0, %2}";
6827 return "add{l}\t{%2, %0|%0, %2}";
6831 (cond [(and (eq_attr "alternative" "2")
6832 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6833 (const_string "lea")
6834 (eq_attr "alternative" "3")
6835 (const_string "lea")
6836 ; Current assemblers are broken and do not allow @GOTOFF in
6837 ; ought but a memory context.
6838 (match_operand:SI 2 "pic_symbolic_operand" "")
6839 (const_string "lea")
6840 (match_operand:SI 2 "incdec_operand" "")
6841 (const_string "incdec")
6843 (const_string "alu")))
6844 (set (attr "length_immediate")
6846 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6848 (const_string "*")))
6849 (set_attr "mode" "SI")])
6851 ;; Convert lea to the lea pattern to avoid flags dependency.
6853 [(set (match_operand 0 "register_operand" "")
6854 (plus (match_operand 1 "register_operand" "")
6855 (match_operand 2 "nonmemory_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))]
6857 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6861 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6862 may confuse gen_lowpart. */
6863 if (GET_MODE (operands[0]) != Pmode)
6865 operands[1] = gen_lowpart (Pmode, operands[1]);
6866 operands[2] = gen_lowpart (Pmode, operands[2]);
6868 operands[0] = gen_lowpart (SImode, operands[0]);
6869 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6870 if (Pmode != SImode)
6871 pat = gen_rtx_SUBREG (SImode, pat, 0);
6872 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6876 ;; It may seem that nonimmediate operand is proper one for operand 1.
6877 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6878 ;; we take care in ix86_binary_operator_ok to not allow two memory
6879 ;; operands so proper swapping will be done in reload. This allow
6880 ;; patterns constructed from addsi_1 to match.
6881 (define_insn "addsi_1_zext"
6882 [(set (match_operand:DI 0 "register_operand" "=r,r")
6884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6885 (match_operand:SI 2 "general_operand" "g,li"))))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6889 switch (get_attr_type (insn))
6892 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6893 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6896 if (operands[2] == const1_rtx)
6897 return "inc{l}\t%k0";
6900 gcc_assert (operands[2] == constm1_rtx);
6901 return "dec{l}\t%k0";
6905 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6906 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6907 if (CONST_INT_P (operands[2])
6908 && (INTVAL (operands[2]) == 128
6909 || (INTVAL (operands[2]) < 0
6910 && INTVAL (operands[2]) != -128)))
6912 operands[2] = GEN_INT (-INTVAL (operands[2]));
6913 return "sub{l}\t{%2, %k0|%k0, %2}";
6915 return "add{l}\t{%2, %k0|%k0, %2}";
6919 (cond [(eq_attr "alternative" "1")
6920 (const_string "lea")
6921 ; Current assemblers are broken and do not allow @GOTOFF in
6922 ; ought but a memory context.
6923 (match_operand:SI 2 "pic_symbolic_operand" "")
6924 (const_string "lea")
6925 (match_operand:SI 2 "incdec_operand" "")
6926 (const_string "incdec")
6928 (const_string "alu")))
6929 (set (attr "length_immediate")
6931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6933 (const_string "*")))
6934 (set_attr "mode" "SI")])
6936 ;; Convert lea to the lea pattern to avoid flags dependency.
6938 [(set (match_operand:DI 0 "register_operand" "")
6940 (plus:SI (match_operand:SI 1 "register_operand" "")
6941 (match_operand:SI 2 "nonmemory_operand" ""))))
6942 (clobber (reg:CC FLAGS_REG))]
6943 "TARGET_64BIT && reload_completed
6944 && true_regnum (operands[0]) != true_regnum (operands[1])"
6946 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6948 operands[1] = gen_lowpart (Pmode, operands[1]);
6949 operands[2] = gen_lowpart (Pmode, operands[2]);
6952 (define_insn "*addsi_2"
6953 [(set (reg FLAGS_REG)
6955 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6956 (match_operand:SI 2 "general_operand" "g,ri"))
6958 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6959 (plus:SI (match_dup 1) (match_dup 2)))]
6960 "ix86_match_ccmode (insn, CCGOCmode)
6961 && ix86_binary_operator_ok (PLUS, SImode, operands)
6962 /* Current assemblers are broken and do not allow @GOTOFF in
6963 ought but a memory context. */
6964 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6966 switch (get_attr_type (insn))
6969 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6970 if (operands[2] == const1_rtx)
6971 return "inc{l}\t%0";
6974 gcc_assert (operands[2] == constm1_rtx);
6975 return "dec{l}\t%0";
6979 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6980 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6981 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6982 if (CONST_INT_P (operands[2])
6983 && (INTVAL (operands[2]) == 128
6984 || (INTVAL (operands[2]) < 0
6985 && INTVAL (operands[2]) != -128)))
6987 operands[2] = GEN_INT (-INTVAL (operands[2]));
6988 return "sub{l}\t{%2, %0|%0, %2}";
6990 return "add{l}\t{%2, %0|%0, %2}";
6994 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6995 (const_string "incdec")
6996 (const_string "alu")))
6997 (set (attr "length_immediate")
6999 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7001 (const_string "*")))
7002 (set_attr "mode" "SI")])
7004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7005 (define_insn "*addsi_2_zext"
7006 [(set (reg FLAGS_REG)
7008 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7009 (match_operand:SI 2 "general_operand" "g"))
7011 (set (match_operand:DI 0 "register_operand" "=r")
7012 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7013 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7014 && ix86_binary_operator_ok (PLUS, SImode, operands)
7015 /* Current assemblers are broken and do not allow @GOTOFF in
7016 ought but a memory context. */
7017 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7019 switch (get_attr_type (insn))
7022 if (operands[2] == const1_rtx)
7023 return "inc{l}\t%k0";
7026 gcc_assert (operands[2] == constm1_rtx);
7027 return "dec{l}\t%k0";
7031 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7032 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7033 if (CONST_INT_P (operands[2])
7034 && (INTVAL (operands[2]) == 128
7035 || (INTVAL (operands[2]) < 0
7036 && INTVAL (operands[2]) != -128)))
7038 operands[2] = GEN_INT (-INTVAL (operands[2]));
7039 return "sub{l}\t{%2, %k0|%k0, %2}";
7041 return "add{l}\t{%2, %k0|%k0, %2}";
7045 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7046 (const_string "incdec")
7047 (const_string "alu")))
7048 (set (attr "length_immediate")
7050 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7052 (const_string "*")))
7053 (set_attr "mode" "SI")])
7055 (define_insn "*addsi_3"
7056 [(set (reg FLAGS_REG)
7057 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7058 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7059 (clobber (match_scratch:SI 0 "=r"))]
7060 "ix86_match_ccmode (insn, CCZmode)
7061 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7062 /* Current assemblers are broken and do not allow @GOTOFF in
7063 ought but a memory context. */
7064 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7066 switch (get_attr_type (insn))
7069 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7070 if (operands[2] == const1_rtx)
7071 return "inc{l}\t%0";
7074 gcc_assert (operands[2] == constm1_rtx);
7075 return "dec{l}\t%0";
7079 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7080 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7081 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7082 if (CONST_INT_P (operands[2])
7083 && (INTVAL (operands[2]) == 128
7084 || (INTVAL (operands[2]) < 0
7085 && INTVAL (operands[2]) != -128)))
7087 operands[2] = GEN_INT (-INTVAL (operands[2]));
7088 return "sub{l}\t{%2, %0|%0, %2}";
7090 return "add{l}\t{%2, %0|%0, %2}";
7094 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7095 (const_string "incdec")
7096 (const_string "alu")))
7097 (set (attr "length_immediate")
7099 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7101 (const_string "*")))
7102 (set_attr "mode" "SI")])
7104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7105 (define_insn "*addsi_3_zext"
7106 [(set (reg FLAGS_REG)
7107 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7108 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7109 (set (match_operand:DI 0 "register_operand" "=r")
7110 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7111 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7112 && ix86_binary_operator_ok (PLUS, SImode, operands)
7113 /* Current assemblers are broken and do not allow @GOTOFF in
7114 ought but a memory context. */
7115 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7117 switch (get_attr_type (insn))
7120 if (operands[2] == const1_rtx)
7121 return "inc{l}\t%k0";
7124 gcc_assert (operands[2] == constm1_rtx);
7125 return "dec{l}\t%k0";
7129 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7130 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7131 if (CONST_INT_P (operands[2])
7132 && (INTVAL (operands[2]) == 128
7133 || (INTVAL (operands[2]) < 0
7134 && INTVAL (operands[2]) != -128)))
7136 operands[2] = GEN_INT (-INTVAL (operands[2]));
7137 return "sub{l}\t{%2, %k0|%k0, %2}";
7139 return "add{l}\t{%2, %k0|%k0, %2}";
7143 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7144 (const_string "incdec")
7145 (const_string "alu")))
7146 (set (attr "length_immediate")
7148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7150 (const_string "*")))
7151 (set_attr "mode" "SI")])
7153 ; For comparisons against 1, -1 and 128, we may generate better code
7154 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7155 ; is matched then. We can't accept general immediate, because for
7156 ; case of overflows, the result is messed up.
7157 ; This pattern also don't hold of 0x80000000, since the value overflows
7159 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7160 ; only for comparisons not depending on it.
7161 (define_insn "*addsi_4"
7162 [(set (reg FLAGS_REG)
7163 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7164 (match_operand:SI 2 "const_int_operand" "n")))
7165 (clobber (match_scratch:SI 0 "=rm"))]
7166 "ix86_match_ccmode (insn, CCGCmode)
7167 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7169 switch (get_attr_type (insn))
7172 if (operands[2] == constm1_rtx)
7173 return "inc{l}\t%0";
7176 gcc_assert (operands[2] == const1_rtx);
7177 return "dec{l}\t%0";
7181 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7182 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7183 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7184 if ((INTVAL (operands[2]) == -128
7185 || (INTVAL (operands[2]) > 0
7186 && INTVAL (operands[2]) != 128)))
7187 return "sub{l}\t{%2, %0|%0, %2}";
7188 operands[2] = GEN_INT (-INTVAL (operands[2]));
7189 return "add{l}\t{%2, %0|%0, %2}";
7193 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7194 (const_string "incdec")
7195 (const_string "alu")))
7196 (set (attr "length_immediate")
7198 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7200 (const_string "*")))
7201 (set_attr "mode" "SI")])
7203 (define_insn "*addsi_5"
7204 [(set (reg FLAGS_REG)
7206 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7207 (match_operand:SI 2 "general_operand" "g"))
7209 (clobber (match_scratch:SI 0 "=r"))]
7210 "ix86_match_ccmode (insn, CCGOCmode)
7211 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7212 /* Current assemblers are broken and do not allow @GOTOFF in
7213 ought but a memory context. */
7214 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7216 switch (get_attr_type (insn))
7219 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7220 if (operands[2] == const1_rtx)
7221 return "inc{l}\t%0";
7224 gcc_assert (operands[2] == constm1_rtx);
7225 return "dec{l}\t%0";
7229 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7230 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7232 if (CONST_INT_P (operands[2])
7233 && (INTVAL (operands[2]) == 128
7234 || (INTVAL (operands[2]) < 0
7235 && INTVAL (operands[2]) != -128)))
7237 operands[2] = GEN_INT (-INTVAL (operands[2]));
7238 return "sub{l}\t{%2, %0|%0, %2}";
7240 return "add{l}\t{%2, %0|%0, %2}";
7244 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7245 (const_string "incdec")
7246 (const_string "alu")))
7247 (set (attr "length_immediate")
7249 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7251 (const_string "*")))
7252 (set_attr "mode" "SI")])
7254 (define_expand "addhi3"
7255 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7256 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7257 (match_operand:HI 2 "general_operand" "")))]
7258 "TARGET_HIMODE_MATH"
7259 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7261 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7262 ;; type optimizations enabled by define-splits. This is not important
7263 ;; for PII, and in fact harmful because of partial register stalls.
7265 (define_insn "*addhi_1_lea"
7266 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7267 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7268 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7269 (clobber (reg:CC FLAGS_REG))]
7270 "!TARGET_PARTIAL_REG_STALL
7271 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7273 switch (get_attr_type (insn))
7278 if (operands[2] == const1_rtx)
7279 return "inc{w}\t%0";
7282 gcc_assert (operands[2] == constm1_rtx);
7283 return "dec{w}\t%0";
7287 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7288 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7289 if (CONST_INT_P (operands[2])
7290 && (INTVAL (operands[2]) == 128
7291 || (INTVAL (operands[2]) < 0
7292 && INTVAL (operands[2]) != -128)))
7294 operands[2] = GEN_INT (-INTVAL (operands[2]));
7295 return "sub{w}\t{%2, %0|%0, %2}";
7297 return "add{w}\t{%2, %0|%0, %2}";
7301 (if_then_else (eq_attr "alternative" "2")
7302 (const_string "lea")
7303 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7304 (const_string "incdec")
7305 (const_string "alu"))))
7306 (set (attr "length_immediate")
7308 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7310 (const_string "*")))
7311 (set_attr "mode" "HI,HI,SI")])
7313 (define_insn "*addhi_1"
7314 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7315 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7316 (match_operand:HI 2 "general_operand" "rn,rm")))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_PARTIAL_REG_STALL
7319 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7321 switch (get_attr_type (insn))
7324 if (operands[2] == const1_rtx)
7325 return "inc{w}\t%0";
7328 gcc_assert (operands[2] == constm1_rtx);
7329 return "dec{w}\t%0";
7333 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7334 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7335 if (CONST_INT_P (operands[2])
7336 && (INTVAL (operands[2]) == 128
7337 || (INTVAL (operands[2]) < 0
7338 && INTVAL (operands[2]) != -128)))
7340 operands[2] = GEN_INT (-INTVAL (operands[2]));
7341 return "sub{w}\t{%2, %0|%0, %2}";
7343 return "add{w}\t{%2, %0|%0, %2}";
7347 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7348 (const_string "incdec")
7349 (const_string "alu")))
7350 (set (attr "length_immediate")
7352 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7354 (const_string "*")))
7355 (set_attr "mode" "HI")])
7357 (define_insn "*addhi_2"
7358 [(set (reg FLAGS_REG)
7360 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7361 (match_operand:HI 2 "general_operand" "rmn,rn"))
7363 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7364 (plus:HI (match_dup 1) (match_dup 2)))]
7365 "ix86_match_ccmode (insn, CCGOCmode)
7366 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7368 switch (get_attr_type (insn))
7371 if (operands[2] == const1_rtx)
7372 return "inc{w}\t%0";
7375 gcc_assert (operands[2] == constm1_rtx);
7376 return "dec{w}\t%0";
7380 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7381 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7382 if (CONST_INT_P (operands[2])
7383 && (INTVAL (operands[2]) == 128
7384 || (INTVAL (operands[2]) < 0
7385 && INTVAL (operands[2]) != -128)))
7387 operands[2] = GEN_INT (-INTVAL (operands[2]));
7388 return "sub{w}\t{%2, %0|%0, %2}";
7390 return "add{w}\t{%2, %0|%0, %2}";
7394 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7395 (const_string "incdec")
7396 (const_string "alu")))
7397 (set (attr "length_immediate")
7399 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7401 (const_string "*")))
7402 (set_attr "mode" "HI")])
7404 (define_insn "*addhi_3"
7405 [(set (reg FLAGS_REG)
7406 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7407 (match_operand:HI 1 "nonimmediate_operand" "%0")))
7408 (clobber (match_scratch:HI 0 "=r"))]
7409 "ix86_match_ccmode (insn, CCZmode)
7410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7412 switch (get_attr_type (insn))
7415 if (operands[2] == const1_rtx)
7416 return "inc{w}\t%0";
7419 gcc_assert (operands[2] == constm1_rtx);
7420 return "dec{w}\t%0";
7424 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7425 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7426 if (CONST_INT_P (operands[2])
7427 && (INTVAL (operands[2]) == 128
7428 || (INTVAL (operands[2]) < 0
7429 && INTVAL (operands[2]) != -128)))
7431 operands[2] = GEN_INT (-INTVAL (operands[2]));
7432 return "sub{w}\t{%2, %0|%0, %2}";
7434 return "add{w}\t{%2, %0|%0, %2}";
7438 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7439 (const_string "incdec")
7440 (const_string "alu")))
7441 (set (attr "length_immediate")
7443 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7445 (const_string "*")))
7446 (set_attr "mode" "HI")])
7448 ; See comments above addsi_4 for details.
7449 (define_insn "*addhi_4"
7450 [(set (reg FLAGS_REG)
7451 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7452 (match_operand:HI 2 "const_int_operand" "n")))
7453 (clobber (match_scratch:HI 0 "=rm"))]
7454 "ix86_match_ccmode (insn, CCGCmode)
7455 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7457 switch (get_attr_type (insn))
7460 if (operands[2] == constm1_rtx)
7461 return "inc{w}\t%0";
7464 gcc_assert (operands[2] == const1_rtx);
7465 return "dec{w}\t%0";
7469 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7470 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7471 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7472 if ((INTVAL (operands[2]) == -128
7473 || (INTVAL (operands[2]) > 0
7474 && INTVAL (operands[2]) != 128)))
7475 return "sub{w}\t{%2, %0|%0, %2}";
7476 operands[2] = GEN_INT (-INTVAL (operands[2]));
7477 return "add{w}\t{%2, %0|%0, %2}";
7481 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7482 (const_string "incdec")
7483 (const_string "alu")))
7484 (set (attr "length_immediate")
7486 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7488 (const_string "*")))
7489 (set_attr "mode" "HI")])
7492 (define_insn "*addhi_5"
7493 [(set (reg FLAGS_REG)
7495 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7496 (match_operand:HI 2 "general_operand" "rmn"))
7498 (clobber (match_scratch:HI 0 "=r"))]
7499 "ix86_match_ccmode (insn, CCGOCmode)
7500 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7502 switch (get_attr_type (insn))
7505 if (operands[2] == const1_rtx)
7506 return "inc{w}\t%0";
7509 gcc_assert (operands[2] == constm1_rtx);
7510 return "dec{w}\t%0";
7514 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7515 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7516 if (CONST_INT_P (operands[2])
7517 && (INTVAL (operands[2]) == 128
7518 || (INTVAL (operands[2]) < 0
7519 && INTVAL (operands[2]) != -128)))
7521 operands[2] = GEN_INT (-INTVAL (operands[2]));
7522 return "sub{w}\t{%2, %0|%0, %2}";
7524 return "add{w}\t{%2, %0|%0, %2}";
7528 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7529 (const_string "incdec")
7530 (const_string "alu")))
7531 (set (attr "length_immediate")
7533 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7535 (const_string "*")))
7536 (set_attr "mode" "HI")])
7538 (define_expand "addqi3"
7539 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7540 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7541 (match_operand:QI 2 "general_operand" "")))]
7542 "TARGET_QIMODE_MATH"
7543 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7545 ;; %%% Potential partial reg stall on alternative 2. What to do?
7546 (define_insn "*addqi_1_lea"
7547 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7548 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7549 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "!TARGET_PARTIAL_REG_STALL
7552 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7554 int widen = (which_alternative == 2);
7555 switch (get_attr_type (insn))
7560 if (operands[2] == const1_rtx)
7561 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7564 gcc_assert (operands[2] == constm1_rtx);
7565 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7569 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7570 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7571 if (CONST_INT_P (operands[2])
7572 && (INTVAL (operands[2]) == 128
7573 || (INTVAL (operands[2]) < 0
7574 && INTVAL (operands[2]) != -128)))
7576 operands[2] = GEN_INT (-INTVAL (operands[2]));
7578 return "sub{l}\t{%2, %k0|%k0, %2}";
7580 return "sub{b}\t{%2, %0|%0, %2}";
7583 return "add{l}\t{%k2, %k0|%k0, %k2}";
7585 return "add{b}\t{%2, %0|%0, %2}";
7589 (if_then_else (eq_attr "alternative" "3")
7590 (const_string "lea")
7591 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7592 (const_string "incdec")
7593 (const_string "alu"))))
7594 (set (attr "length_immediate")
7596 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7598 (const_string "*")))
7599 (set_attr "mode" "QI,QI,SI,SI")])
7601 (define_insn "*addqi_1"
7602 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7603 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7604 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_PARTIAL_REG_STALL
7607 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7609 int widen = (which_alternative == 2);
7610 switch (get_attr_type (insn))
7613 if (operands[2] == const1_rtx)
7614 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7617 gcc_assert (operands[2] == constm1_rtx);
7618 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7622 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7623 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7624 if (CONST_INT_P (operands[2])
7625 && (INTVAL (operands[2]) == 128
7626 || (INTVAL (operands[2]) < 0
7627 && INTVAL (operands[2]) != -128)))
7629 operands[2] = GEN_INT (-INTVAL (operands[2]));
7631 return "sub{l}\t{%2, %k0|%k0, %2}";
7633 return "sub{b}\t{%2, %0|%0, %2}";
7636 return "add{l}\t{%k2, %k0|%k0, %k2}";
7638 return "add{b}\t{%2, %0|%0, %2}";
7642 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7643 (const_string "incdec")
7644 (const_string "alu")))
7645 (set (attr "length_immediate")
7647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7649 (const_string "*")))
7650 (set_attr "mode" "QI,QI,SI")])
7652 (define_insn "*addqi_1_slp"
7653 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7654 (plus:QI (match_dup 0)
7655 (match_operand:QI 1 "general_operand" "qn,qnm")))
7656 (clobber (reg:CC FLAGS_REG))]
7657 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7658 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7660 switch (get_attr_type (insn))
7663 if (operands[1] == const1_rtx)
7664 return "inc{b}\t%0";
7667 gcc_assert (operands[1] == constm1_rtx);
7668 return "dec{b}\t%0";
7672 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7673 if (CONST_INT_P (operands[1])
7674 && INTVAL (operands[1]) < 0)
7676 operands[1] = GEN_INT (-INTVAL (operands[1]));
7677 return "sub{b}\t{%1, %0|%0, %1}";
7679 return "add{b}\t{%1, %0|%0, %1}";
7683 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7684 (const_string "incdec")
7685 (const_string "alu1")))
7686 (set (attr "memory")
7687 (if_then_else (match_operand 1 "memory_operand" "")
7688 (const_string "load")
7689 (const_string "none")))
7690 (set_attr "mode" "QI")])
7692 (define_insn "*addqi_2"
7693 [(set (reg FLAGS_REG)
7695 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7696 (match_operand:QI 2 "general_operand" "qmn,qn"))
7698 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7699 (plus:QI (match_dup 1) (match_dup 2)))]
7700 "ix86_match_ccmode (insn, CCGOCmode)
7701 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7703 switch (get_attr_type (insn))
7706 if (operands[2] == const1_rtx)
7707 return "inc{b}\t%0";
7710 gcc_assert (operands[2] == constm1_rtx
7711 || (CONST_INT_P (operands[2])
7712 && INTVAL (operands[2]) == 255));
7713 return "dec{b}\t%0";
7717 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7718 if (CONST_INT_P (operands[2])
7719 && INTVAL (operands[2]) < 0)
7721 operands[2] = GEN_INT (-INTVAL (operands[2]));
7722 return "sub{b}\t{%2, %0|%0, %2}";
7724 return "add{b}\t{%2, %0|%0, %2}";
7728 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7729 (const_string "incdec")
7730 (const_string "alu")))
7731 (set_attr "mode" "QI")])
7733 (define_insn "*addqi_3"
7734 [(set (reg FLAGS_REG)
7735 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7736 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7737 (clobber (match_scratch:QI 0 "=q"))]
7738 "ix86_match_ccmode (insn, CCZmode)
7739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741 switch (get_attr_type (insn))
7744 if (operands[2] == const1_rtx)
7745 return "inc{b}\t%0";
7748 gcc_assert (operands[2] == constm1_rtx
7749 || (CONST_INT_P (operands[2])
7750 && INTVAL (operands[2]) == 255));
7751 return "dec{b}\t%0";
7755 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7756 if (CONST_INT_P (operands[2])
7757 && INTVAL (operands[2]) < 0)
7759 operands[2] = GEN_INT (-INTVAL (operands[2]));
7760 return "sub{b}\t{%2, %0|%0, %2}";
7762 return "add{b}\t{%2, %0|%0, %2}";
7766 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7767 (const_string "incdec")
7768 (const_string "alu")))
7769 (set_attr "mode" "QI")])
7771 ; See comments above addsi_4 for details.
7772 (define_insn "*addqi_4"
7773 [(set (reg FLAGS_REG)
7774 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7775 (match_operand:QI 2 "const_int_operand" "n")))
7776 (clobber (match_scratch:QI 0 "=qm"))]
7777 "ix86_match_ccmode (insn, CCGCmode)
7778 && (INTVAL (operands[2]) & 0xff) != 0x80"
7780 switch (get_attr_type (insn))
7783 if (operands[2] == constm1_rtx
7784 || (CONST_INT_P (operands[2])
7785 && INTVAL (operands[2]) == 255))
7786 return "inc{b}\t%0";
7789 gcc_assert (operands[2] == const1_rtx);
7790 return "dec{b}\t%0";
7794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795 if (INTVAL (operands[2]) < 0)
7797 operands[2] = GEN_INT (-INTVAL (operands[2]));
7798 return "add{b}\t{%2, %0|%0, %2}";
7800 return "sub{b}\t{%2, %0|%0, %2}";
7804 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7805 (const_string "incdec")
7806 (const_string "alu")))
7807 (set_attr "mode" "QI")])
7810 (define_insn "*addqi_5"
7811 [(set (reg FLAGS_REG)
7813 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7814 (match_operand:QI 2 "general_operand" "qmn"))
7816 (clobber (match_scratch:QI 0 "=q"))]
7817 "ix86_match_ccmode (insn, CCGOCmode)
7818 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7820 switch (get_attr_type (insn))
7823 if (operands[2] == const1_rtx)
7824 return "inc{b}\t%0";
7827 gcc_assert (operands[2] == constm1_rtx
7828 || (CONST_INT_P (operands[2])
7829 && INTVAL (operands[2]) == 255));
7830 return "dec{b}\t%0";
7834 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7835 if (CONST_INT_P (operands[2])
7836 && INTVAL (operands[2]) < 0)
7838 operands[2] = GEN_INT (-INTVAL (operands[2]));
7839 return "sub{b}\t{%2, %0|%0, %2}";
7841 return "add{b}\t{%2, %0|%0, %2}";
7845 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7846 (const_string "incdec")
7847 (const_string "alu")))
7848 (set_attr "mode" "QI")])
7851 (define_insn "addqi_ext_1"
7852 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7857 (match_operand 1 "ext_register_operand" "0")
7860 (match_operand:QI 2 "general_operand" "Qmn")))
7861 (clobber (reg:CC FLAGS_REG))]
7864 switch (get_attr_type (insn))
7867 if (operands[2] == const1_rtx)
7868 return "inc{b}\t%h0";
7871 gcc_assert (operands[2] == constm1_rtx
7872 || (CONST_INT_P (operands[2])
7873 && INTVAL (operands[2]) == 255));
7874 return "dec{b}\t%h0";
7878 return "add{b}\t{%2, %h0|%h0, %2}";
7882 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7883 (const_string "incdec")
7884 (const_string "alu")))
7885 (set_attr "modrm" "1")
7886 (set_attr "mode" "QI")])
7888 (define_insn "*addqi_ext_1_rex64"
7889 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7894 (match_operand 1 "ext_register_operand" "0")
7897 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7898 (clobber (reg:CC FLAGS_REG))]
7901 switch (get_attr_type (insn))
7904 if (operands[2] == const1_rtx)
7905 return "inc{b}\t%h0";
7908 gcc_assert (operands[2] == constm1_rtx
7909 || (CONST_INT_P (operands[2])
7910 && INTVAL (operands[2]) == 255));
7911 return "dec{b}\t%h0";
7915 return "add{b}\t{%2, %h0|%h0, %2}";
7919 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7920 (const_string "incdec")
7921 (const_string "alu")))
7922 (set_attr "modrm" "1")
7923 (set_attr "mode" "QI")])
7925 (define_insn "*addqi_ext_2"
7926 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7931 (match_operand 1 "ext_register_operand" "%0")
7935 (match_operand 2 "ext_register_operand" "Q")
7938 (clobber (reg:CC FLAGS_REG))]
7940 "add{b}\t{%h2, %h0|%h0, %h2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "QI")])
7944 ;; The patterns that match these are at the end of this file.
7946 (define_expand "addxf3"
7947 [(set (match_operand:XF 0 "register_operand" "")
7948 (plus:XF (match_operand:XF 1 "register_operand" "")
7949 (match_operand:XF 2 "register_operand" "")))]
7953 (define_expand "add<mode>3"
7954 [(set (match_operand:MODEF 0 "register_operand" "")
7955 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7956 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7957 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7958 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7961 ;; Subtract instructions
7963 ;; %%% splits for subditi3
7965 (define_expand "subti3"
7966 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7967 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7968 (match_operand:TI 2 "x86_64_general_operand" "")))]
7970 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7972 (define_insn "*subti3_1"
7973 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7974 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7975 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7976 (clobber (reg:CC FLAGS_REG))]
7977 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7981 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7982 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7983 (match_operand:TI 2 "x86_64_general_operand" "")))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "TARGET_64BIT && reload_completed"
7986 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7987 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7988 (parallel [(set (match_dup 3)
7989 (minus:DI (match_dup 4)
7990 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7992 (clobber (reg:CC FLAGS_REG))])]
7993 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7995 ;; %%% splits for subsidi3
7997 (define_expand "subdi3"
7998 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000 (match_operand:DI 2 "x86_64_general_operand" "")))]
8002 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8004 (define_insn "*subdi3_1"
8005 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
8006 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8007 (match_operand:DI 2 "general_operand" "roiF,riF")))
8008 (clobber (reg:CC FLAGS_REG))]
8009 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8013 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8014 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8015 (match_operand:DI 2 "general_operand" "")))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "!TARGET_64BIT && reload_completed"
8018 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
8019 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8020 (parallel [(set (match_dup 3)
8021 (minus:SI (match_dup 4)
8022 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
8024 (clobber (reg:CC FLAGS_REG))])]
8025 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
8027 (define_insn "subdi3_carry_rex64"
8028 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8029 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8030 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
8031 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8032 (clobber (reg:CC FLAGS_REG))]
8033 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8034 "sbb{q}\t{%2, %0|%0, %2}"
8035 [(set_attr "type" "alu")
8036 (set_attr "use_carry" "1")
8037 (set_attr "pent_pair" "pu")
8038 (set_attr "mode" "DI")])
8040 (define_insn "*subdi_1_rex64"
8041 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8042 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8043 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8044 (clobber (reg:CC FLAGS_REG))]
8045 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8046 "sub{q}\t{%2, %0|%0, %2}"
8047 [(set_attr "type" "alu")
8048 (set_attr "mode" "DI")])
8050 (define_insn "*subdi_2_rex64"
8051 [(set (reg FLAGS_REG)
8053 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8054 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8056 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8057 (minus:DI (match_dup 1) (match_dup 2)))]
8058 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8059 && ix86_binary_operator_ok (MINUS, DImode, operands)"
8060 "sub{q}\t{%2, %0|%0, %2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "mode" "DI")])
8064 (define_insn "*subdi_3_rex63"
8065 [(set (reg FLAGS_REG)
8066 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8067 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8068 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8069 (minus:DI (match_dup 1) (match_dup 2)))]
8070 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8071 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8072 "sub{q}\t{%2, %0|%0, %2}"
8073 [(set_attr "type" "alu")
8074 (set_attr "mode" "DI")])
8076 (define_insn "subqi3_carry"
8077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8078 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8079 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
8080 (match_operand:QI 2 "general_operand" "qn,qm"))))
8081 (clobber (reg:CC FLAGS_REG))]
8082 "ix86_binary_operator_ok (MINUS, QImode, operands)"
8083 "sbb{b}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "use_carry" "1")
8086 (set_attr "pent_pair" "pu")
8087 (set_attr "mode" "QI")])
8089 (define_insn "subhi3_carry"
8090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8091 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8092 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
8093 (match_operand:HI 2 "general_operand" "rn,rm"))))
8094 (clobber (reg:CC FLAGS_REG))]
8095 "ix86_binary_operator_ok (MINUS, HImode, operands)"
8096 "sbb{w}\t{%2, %0|%0, %2}"
8097 [(set_attr "type" "alu")
8098 (set_attr "use_carry" "1")
8099 (set_attr "pent_pair" "pu")
8100 (set_attr "mode" "HI")])
8102 (define_insn "subsi3_carry"
8103 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8104 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8105 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8106 (match_operand:SI 2 "general_operand" "ri,rm"))))
8107 (clobber (reg:CC FLAGS_REG))]
8108 "ix86_binary_operator_ok (MINUS, SImode, operands)"
8109 "sbb{l}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "use_carry" "1")
8112 (set_attr "pent_pair" "pu")
8113 (set_attr "mode" "SI")])
8115 (define_insn "subsi3_carry_zext"
8116 [(set (match_operand:DI 0 "register_operand" "=r")
8118 (minus:SI (match_operand:SI 1 "register_operand" "0")
8119 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8120 (match_operand:SI 2 "general_operand" "g")))))
8121 (clobber (reg:CC FLAGS_REG))]
8122 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8123 "sbb{l}\t{%2, %k0|%k0, %2}"
8124 [(set_attr "type" "alu")
8125 (set_attr "pent_pair" "pu")
8126 (set_attr "mode" "SI")])
8128 (define_expand "subsi3"
8129 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8130 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8131 (match_operand:SI 2 "general_operand" "")))]
8133 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
8135 (define_insn "*subsi_1"
8136 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8137 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8138 (match_operand:SI 2 "general_operand" "ri,rm")))
8139 (clobber (reg:CC FLAGS_REG))]
8140 "ix86_binary_operator_ok (MINUS, SImode, operands)"
8141 "sub{l}\t{%2, %0|%0, %2}"
8142 [(set_attr "type" "alu")
8143 (set_attr "mode" "SI")])
8145 (define_insn "*subsi_1_zext"
8146 [(set (match_operand:DI 0 "register_operand" "=r")
8148 (minus:SI (match_operand:SI 1 "register_operand" "0")
8149 (match_operand:SI 2 "general_operand" "g"))))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8152 "sub{l}\t{%2, %k0|%k0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI")])
8156 (define_insn "*subsi_2"
8157 [(set (reg FLAGS_REG)
8159 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8160 (match_operand:SI 2 "general_operand" "ri,rm"))
8162 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8163 (minus:SI (match_dup 1) (match_dup 2)))]
8164 "ix86_match_ccmode (insn, CCGOCmode)
8165 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8166 "sub{l}\t{%2, %0|%0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "SI")])
8170 (define_insn "*subsi_2_zext"
8171 [(set (reg FLAGS_REG)
8173 (minus:SI (match_operand:SI 1 "register_operand" "0")
8174 (match_operand:SI 2 "general_operand" "g"))
8176 (set (match_operand:DI 0 "register_operand" "=r")
8178 (minus:SI (match_dup 1)
8180 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8181 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8182 "sub{l}\t{%2, %k0|%k0, %2}"
8183 [(set_attr "type" "alu")
8184 (set_attr "mode" "SI")])
8186 (define_insn "*subsi_3"
8187 [(set (reg FLAGS_REG)
8188 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8189 (match_operand:SI 2 "general_operand" "ri,rm")))
8190 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8191 (minus:SI (match_dup 1) (match_dup 2)))]
8192 "ix86_match_ccmode (insn, CCmode)
8193 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8194 "sub{l}\t{%2, %0|%0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "mode" "SI")])
8198 (define_insn "*subsi_3_zext"
8199 [(set (reg FLAGS_REG)
8200 (compare (match_operand:SI 1 "register_operand" "0")
8201 (match_operand:SI 2 "general_operand" "g")))
8202 (set (match_operand:DI 0 "register_operand" "=r")
8204 (minus:SI (match_dup 1)
8206 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8207 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8208 "sub{l}\t{%2, %1|%1, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "DI")])
8212 (define_expand "subhi3"
8213 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8214 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8215 (match_operand:HI 2 "general_operand" "")))]
8216 "TARGET_HIMODE_MATH"
8217 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
8219 (define_insn "*subhi_1"
8220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8221 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8222 (match_operand:HI 2 "general_operand" "rn,rm")))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "ix86_binary_operator_ok (MINUS, HImode, operands)"
8225 "sub{w}\t{%2, %0|%0, %2}"
8226 [(set_attr "type" "alu")
8227 (set_attr "mode" "HI")])
8229 (define_insn "*subhi_2"
8230 [(set (reg FLAGS_REG)
8232 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8233 (match_operand:HI 2 "general_operand" "rn,rm"))
8235 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8236 (minus:HI (match_dup 1) (match_dup 2)))]
8237 "ix86_match_ccmode (insn, CCGOCmode)
8238 && ix86_binary_operator_ok (MINUS, HImode, operands)"
8239 "sub{w}\t{%2, %0|%0, %2}"
8240 [(set_attr "type" "alu")
8241 (set_attr "mode" "HI")])
8243 (define_insn "*subhi_3"
8244 [(set (reg FLAGS_REG)
8245 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8246 (match_operand:HI 2 "general_operand" "rn,rm")))
8247 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8248 (minus:HI (match_dup 1) (match_dup 2)))]
8249 "ix86_match_ccmode (insn, CCmode)
8250 && ix86_binary_operator_ok (MINUS, HImode, operands)"
8251 "sub{w}\t{%2, %0|%0, %2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "mode" "HI")])
8255 (define_expand "subqi3"
8256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8257 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8258 (match_operand:QI 2 "general_operand" "")))]
8259 "TARGET_QIMODE_MATH"
8260 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8262 (define_insn "*subqi_1"
8263 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8264 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8265 (match_operand:QI 2 "general_operand" "qn,qm")))
8266 (clobber (reg:CC FLAGS_REG))]
8267 "ix86_binary_operator_ok (MINUS, QImode, operands)"
8268 "sub{b}\t{%2, %0|%0, %2}"
8269 [(set_attr "type" "alu")
8270 (set_attr "mode" "QI")])
8272 (define_insn "*subqi_1_slp"
8273 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8274 (minus:QI (match_dup 0)
8275 (match_operand:QI 1 "general_operand" "qn,qm")))
8276 (clobber (reg:CC FLAGS_REG))]
8277 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8278 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8279 "sub{b}\t{%1, %0|%0, %1}"
8280 [(set_attr "type" "alu1")
8281 (set_attr "mode" "QI")])
8283 (define_insn "*subqi_2"
8284 [(set (reg FLAGS_REG)
8286 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8287 (match_operand:QI 2 "general_operand" "qn,qm"))
8289 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8290 (minus:QI (match_dup 1) (match_dup 2)))]
8291 "ix86_match_ccmode (insn, CCGOCmode)
8292 && ix86_binary_operator_ok (MINUS, QImode, operands)"
8293 "sub{b}\t{%2, %0|%0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "mode" "QI")])
8297 (define_insn "*subqi_3"
8298 [(set (reg FLAGS_REG)
8299 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8300 (match_operand:QI 2 "general_operand" "qn,qm")))
8301 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8302 (minus:QI (match_dup 1) (match_dup 2)))]
8303 "ix86_match_ccmode (insn, CCmode)
8304 && ix86_binary_operator_ok (MINUS, QImode, operands)"
8305 "sub{b}\t{%2, %0|%0, %2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "mode" "QI")])
8309 ;; The patterns that match these are at the end of this file.
8311 (define_expand "subxf3"
8312 [(set (match_operand:XF 0 "register_operand" "")
8313 (minus:XF (match_operand:XF 1 "register_operand" "")
8314 (match_operand:XF 2 "register_operand" "")))]
8318 (define_expand "sub<mode>3"
8319 [(set (match_operand:MODEF 0 "register_operand" "")
8320 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8321 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8322 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8323 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8326 ;; Multiply instructions
8328 (define_expand "muldi3"
8329 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8330 (mult:DI (match_operand:DI 1 "register_operand" "")
8331 (match_operand:DI 2 "x86_64_general_operand" "")))
8332 (clobber (reg:CC FLAGS_REG))])]
8337 ;; IMUL reg64, reg64, imm8 Direct
8338 ;; IMUL reg64, mem64, imm8 VectorPath
8339 ;; IMUL reg64, reg64, imm32 Direct
8340 ;; IMUL reg64, mem64, imm32 VectorPath
8341 ;; IMUL reg64, reg64 Direct
8342 ;; IMUL reg64, mem64 Direct
8344 (define_insn "*muldi3_1_rex64"
8345 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8346 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8347 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8348 (clobber (reg:CC FLAGS_REG))]
8350 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8352 imul{q}\t{%2, %1, %0|%0, %1, %2}
8353 imul{q}\t{%2, %1, %0|%0, %1, %2}
8354 imul{q}\t{%2, %0|%0, %2}"
8355 [(set_attr "type" "imul")
8356 (set_attr "prefix_0f" "0,0,1")
8357 (set (attr "athlon_decode")
8358 (cond [(eq_attr "cpu" "athlon")
8359 (const_string "vector")
8360 (eq_attr "alternative" "1")
8361 (const_string "vector")
8362 (and (eq_attr "alternative" "2")
8363 (match_operand 1 "memory_operand" ""))
8364 (const_string "vector")]
8365 (const_string "direct")))
8366 (set (attr "amdfam10_decode")
8367 (cond [(and (eq_attr "alternative" "0,1")
8368 (match_operand 1 "memory_operand" ""))
8369 (const_string "vector")]
8370 (const_string "direct")))
8371 (set_attr "mode" "DI")])
8373 (define_expand "mulsi3"
8374 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8375 (mult:SI (match_operand:SI 1 "register_operand" "")
8376 (match_operand:SI 2 "general_operand" "")))
8377 (clobber (reg:CC FLAGS_REG))])]
8382 ;; IMUL reg32, reg32, imm8 Direct
8383 ;; IMUL reg32, mem32, imm8 VectorPath
8384 ;; IMUL reg32, reg32, imm32 Direct
8385 ;; IMUL reg32, mem32, imm32 VectorPath
8386 ;; IMUL reg32, reg32 Direct
8387 ;; IMUL reg32, mem32 Direct
8389 (define_insn "*mulsi3_1"
8390 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8391 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8392 (match_operand:SI 2 "general_operand" "K,i,mr")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8396 imul{l}\t{%2, %1, %0|%0, %1, %2}
8397 imul{l}\t{%2, %1, %0|%0, %1, %2}
8398 imul{l}\t{%2, %0|%0, %2}"
8399 [(set_attr "type" "imul")
8400 (set_attr "prefix_0f" "0,0,1")
8401 (set (attr "athlon_decode")
8402 (cond [(eq_attr "cpu" "athlon")
8403 (const_string "vector")
8404 (eq_attr "alternative" "1")
8405 (const_string "vector")
8406 (and (eq_attr "alternative" "2")
8407 (match_operand 1 "memory_operand" ""))
8408 (const_string "vector")]
8409 (const_string "direct")))
8410 (set (attr "amdfam10_decode")
8411 (cond [(and (eq_attr "alternative" "0,1")
8412 (match_operand 1 "memory_operand" ""))
8413 (const_string "vector")]
8414 (const_string "direct")))
8415 (set_attr "mode" "SI")])
8417 (define_insn "*mulsi3_1_zext"
8418 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8420 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8421 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8422 (clobber (reg:CC FLAGS_REG))]
8424 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8426 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8427 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8428 imul{l}\t{%2, %k0|%k0, %2}"
8429 [(set_attr "type" "imul")
8430 (set_attr "prefix_0f" "0,0,1")
8431 (set (attr "athlon_decode")
8432 (cond [(eq_attr "cpu" "athlon")
8433 (const_string "vector")
8434 (eq_attr "alternative" "1")
8435 (const_string "vector")
8436 (and (eq_attr "alternative" "2")
8437 (match_operand 1 "memory_operand" ""))
8438 (const_string "vector")]
8439 (const_string "direct")))
8440 (set (attr "amdfam10_decode")
8441 (cond [(and (eq_attr "alternative" "0,1")
8442 (match_operand 1 "memory_operand" ""))
8443 (const_string "vector")]
8444 (const_string "direct")))
8445 (set_attr "mode" "SI")])
8447 (define_expand "mulhi3"
8448 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8449 (mult:HI (match_operand:HI 1 "register_operand" "")
8450 (match_operand:HI 2 "general_operand" "")))
8451 (clobber (reg:CC FLAGS_REG))])]
8452 "TARGET_HIMODE_MATH"
8456 ;; IMUL reg16, reg16, imm8 VectorPath
8457 ;; IMUL reg16, mem16, imm8 VectorPath
8458 ;; IMUL reg16, reg16, imm16 VectorPath
8459 ;; IMUL reg16, mem16, imm16 VectorPath
8460 ;; IMUL reg16, reg16 Direct
8461 ;; IMUL reg16, mem16 Direct
8462 (define_insn "*mulhi3_1"
8463 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8464 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8465 (match_operand:HI 2 "general_operand" "K,n,mr")))
8466 (clobber (reg:CC FLAGS_REG))]
8467 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8469 imul{w}\t{%2, %1, %0|%0, %1, %2}
8470 imul{w}\t{%2, %1, %0|%0, %1, %2}
8471 imul{w}\t{%2, %0|%0, %2}"
8472 [(set_attr "type" "imul")
8473 (set_attr "prefix_0f" "0,0,1")
8474 (set (attr "athlon_decode")
8475 (cond [(eq_attr "cpu" "athlon")
8476 (const_string "vector")
8477 (eq_attr "alternative" "1,2")
8478 (const_string "vector")]
8479 (const_string "direct")))
8480 (set (attr "amdfam10_decode")
8481 (cond [(eq_attr "alternative" "0,1")
8482 (const_string "vector")]
8483 (const_string "direct")))
8484 (set_attr "mode" "HI")])
8486 (define_expand "mulqi3"
8487 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8488 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8489 (match_operand:QI 2 "register_operand" "")))
8490 (clobber (reg:CC FLAGS_REG))])]
8491 "TARGET_QIMODE_MATH"
8498 (define_insn "*mulqi3_1"
8499 [(set (match_operand:QI 0 "register_operand" "=a")
8500 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8501 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8502 (clobber (reg:CC FLAGS_REG))]
8504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8506 [(set_attr "type" "imul")
8507 (set_attr "length_immediate" "0")
8508 (set (attr "athlon_decode")
8509 (if_then_else (eq_attr "cpu" "athlon")
8510 (const_string "vector")
8511 (const_string "direct")))
8512 (set_attr "amdfam10_decode" "direct")
8513 (set_attr "mode" "QI")])
8515 (define_expand "umulqihi3"
8516 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8517 (mult:HI (zero_extend:HI
8518 (match_operand:QI 1 "nonimmediate_operand" ""))
8520 (match_operand:QI 2 "register_operand" ""))))
8521 (clobber (reg:CC FLAGS_REG))])]
8522 "TARGET_QIMODE_MATH"
8525 (define_insn "*umulqihi3_1"
8526 [(set (match_operand:HI 0 "register_operand" "=a")
8527 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8528 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8529 (clobber (reg:CC FLAGS_REG))]
8531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8533 [(set_attr "type" "imul")
8534 (set_attr "length_immediate" "0")
8535 (set (attr "athlon_decode")
8536 (if_then_else (eq_attr "cpu" "athlon")
8537 (const_string "vector")
8538 (const_string "direct")))
8539 (set_attr "amdfam10_decode" "direct")
8540 (set_attr "mode" "QI")])
8542 (define_expand "mulqihi3"
8543 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8544 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8545 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8546 (clobber (reg:CC FLAGS_REG))])]
8547 "TARGET_QIMODE_MATH"
8550 (define_insn "*mulqihi3_insn"
8551 [(set (match_operand:HI 0 "register_operand" "=a")
8552 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8553 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8554 (clobber (reg:CC FLAGS_REG))]
8556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8558 [(set_attr "type" "imul")
8559 (set_attr "length_immediate" "0")
8560 (set (attr "athlon_decode")
8561 (if_then_else (eq_attr "cpu" "athlon")
8562 (const_string "vector")
8563 (const_string "direct")))
8564 (set_attr "amdfam10_decode" "direct")
8565 (set_attr "mode" "QI")])
8567 (define_expand "umulditi3"
8568 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8569 (mult:TI (zero_extend:TI
8570 (match_operand:DI 1 "nonimmediate_operand" ""))
8572 (match_operand:DI 2 "register_operand" ""))))
8573 (clobber (reg:CC FLAGS_REG))])]
8577 (define_insn "*umulditi3_insn"
8578 [(set (match_operand:TI 0 "register_operand" "=A")
8579 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8580 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8581 (clobber (reg:CC FLAGS_REG))]
8583 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8585 [(set_attr "type" "imul")
8586 (set_attr "length_immediate" "0")
8587 (set (attr "athlon_decode")
8588 (if_then_else (eq_attr "cpu" "athlon")
8589 (const_string "vector")
8590 (const_string "double")))
8591 (set_attr "amdfam10_decode" "double")
8592 (set_attr "mode" "DI")])
8594 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8595 (define_expand "umulsidi3"
8596 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8597 (mult:DI (zero_extend:DI
8598 (match_operand:SI 1 "nonimmediate_operand" ""))
8600 (match_operand:SI 2 "register_operand" ""))))
8601 (clobber (reg:CC FLAGS_REG))])]
8605 (define_insn "*umulsidi3_insn"
8606 [(set (match_operand:DI 0 "register_operand" "=A")
8607 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8608 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8609 (clobber (reg:CC FLAGS_REG))]
8611 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8613 [(set_attr "type" "imul")
8614 (set_attr "length_immediate" "0")
8615 (set (attr "athlon_decode")
8616 (if_then_else (eq_attr "cpu" "athlon")
8617 (const_string "vector")
8618 (const_string "double")))
8619 (set_attr "amdfam10_decode" "double")
8620 (set_attr "mode" "SI")])
8622 (define_expand "mulditi3"
8623 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8624 (mult:TI (sign_extend:TI
8625 (match_operand:DI 1 "nonimmediate_operand" ""))
8627 (match_operand:DI 2 "register_operand" ""))))
8628 (clobber (reg:CC FLAGS_REG))])]
8632 (define_insn "*mulditi3_insn"
8633 [(set (match_operand:TI 0 "register_operand" "=A")
8634 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8635 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8636 (clobber (reg:CC FLAGS_REG))]
8638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8640 [(set_attr "type" "imul")
8641 (set_attr "length_immediate" "0")
8642 (set (attr "athlon_decode")
8643 (if_then_else (eq_attr "cpu" "athlon")
8644 (const_string "vector")
8645 (const_string "double")))
8646 (set_attr "amdfam10_decode" "double")
8647 (set_attr "mode" "DI")])
8649 (define_expand "mulsidi3"
8650 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8651 (mult:DI (sign_extend:DI
8652 (match_operand:SI 1 "nonimmediate_operand" ""))
8654 (match_operand:SI 2 "register_operand" ""))))
8655 (clobber (reg:CC FLAGS_REG))])]
8659 (define_insn "*mulsidi3_insn"
8660 [(set (match_operand:DI 0 "register_operand" "=A")
8661 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8662 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8663 (clobber (reg:CC FLAGS_REG))]
8665 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8667 [(set_attr "type" "imul")
8668 (set_attr "length_immediate" "0")
8669 (set (attr "athlon_decode")
8670 (if_then_else (eq_attr "cpu" "athlon")
8671 (const_string "vector")
8672 (const_string "double")))
8673 (set_attr "amdfam10_decode" "double")
8674 (set_attr "mode" "SI")])
8676 (define_expand "umuldi3_highpart"
8677 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8680 (mult:TI (zero_extend:TI
8681 (match_operand:DI 1 "nonimmediate_operand" ""))
8683 (match_operand:DI 2 "register_operand" "")))
8685 (clobber (match_scratch:DI 3 ""))
8686 (clobber (reg:CC FLAGS_REG))])]
8690 (define_insn "*umuldi3_highpart_rex64"
8691 [(set (match_operand:DI 0 "register_operand" "=d")
8694 (mult:TI (zero_extend:TI
8695 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8697 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8699 (clobber (match_scratch:DI 3 "=1"))
8700 (clobber (reg:CC FLAGS_REG))]
8702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8704 [(set_attr "type" "imul")
8705 (set_attr "length_immediate" "0")
8706 (set (attr "athlon_decode")
8707 (if_then_else (eq_attr "cpu" "athlon")
8708 (const_string "vector")
8709 (const_string "double")))
8710 (set_attr "amdfam10_decode" "double")
8711 (set_attr "mode" "DI")])
8713 (define_expand "umulsi3_highpart"
8714 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8717 (mult:DI (zero_extend:DI
8718 (match_operand:SI 1 "nonimmediate_operand" ""))
8720 (match_operand:SI 2 "register_operand" "")))
8722 (clobber (match_scratch:SI 3 ""))
8723 (clobber (reg:CC FLAGS_REG))])]
8727 (define_insn "*umulsi3_highpart_insn"
8728 [(set (match_operand:SI 0 "register_operand" "=d")
8731 (mult:DI (zero_extend:DI
8732 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8734 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8736 (clobber (match_scratch:SI 3 "=1"))
8737 (clobber (reg:CC FLAGS_REG))]
8738 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8740 [(set_attr "type" "imul")
8741 (set_attr "length_immediate" "0")
8742 (set (attr "athlon_decode")
8743 (if_then_else (eq_attr "cpu" "athlon")
8744 (const_string "vector")
8745 (const_string "double")))
8746 (set_attr "amdfam10_decode" "double")
8747 (set_attr "mode" "SI")])
8749 (define_insn "*umulsi3_highpart_zext"
8750 [(set (match_operand:DI 0 "register_operand" "=d")
8751 (zero_extend:DI (truncate:SI
8753 (mult:DI (zero_extend:DI
8754 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8756 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8758 (clobber (match_scratch:SI 3 "=1"))
8759 (clobber (reg:CC FLAGS_REG))]
8761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8763 [(set_attr "type" "imul")
8764 (set_attr "length_immediate" "0")
8765 (set (attr "athlon_decode")
8766 (if_then_else (eq_attr "cpu" "athlon")
8767 (const_string "vector")
8768 (const_string "double")))
8769 (set_attr "amdfam10_decode" "double")
8770 (set_attr "mode" "SI")])
8772 (define_expand "smuldi3_highpart"
8773 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8776 (mult:TI (sign_extend:TI
8777 (match_operand:DI 1 "nonimmediate_operand" ""))
8779 (match_operand:DI 2 "register_operand" "")))
8781 (clobber (match_scratch:DI 3 ""))
8782 (clobber (reg:CC FLAGS_REG))])]
8786 (define_insn "*smuldi3_highpart_rex64"
8787 [(set (match_operand:DI 0 "register_operand" "=d")
8790 (mult:TI (sign_extend:TI
8791 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8793 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8795 (clobber (match_scratch:DI 3 "=1"))
8796 (clobber (reg:CC FLAGS_REG))]
8798 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8800 [(set_attr "type" "imul")
8801 (set (attr "athlon_decode")
8802 (if_then_else (eq_attr "cpu" "athlon")
8803 (const_string "vector")
8804 (const_string "double")))
8805 (set_attr "amdfam10_decode" "double")
8806 (set_attr "mode" "DI")])
8808 (define_expand "smulsi3_highpart"
8809 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8812 (mult:DI (sign_extend:DI
8813 (match_operand:SI 1 "nonimmediate_operand" ""))
8815 (match_operand:SI 2 "register_operand" "")))
8817 (clobber (match_scratch:SI 3 ""))
8818 (clobber (reg:CC FLAGS_REG))])]
8822 (define_insn "*smulsi3_highpart_insn"
8823 [(set (match_operand:SI 0 "register_operand" "=d")
8826 (mult:DI (sign_extend:DI
8827 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8829 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8831 (clobber (match_scratch:SI 3 "=1"))
8832 (clobber (reg:CC FLAGS_REG))]
8833 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8835 [(set_attr "type" "imul")
8836 (set (attr "athlon_decode")
8837 (if_then_else (eq_attr "cpu" "athlon")
8838 (const_string "vector")
8839 (const_string "double")))
8840 (set_attr "amdfam10_decode" "double")
8841 (set_attr "mode" "SI")])
8843 (define_insn "*smulsi3_highpart_zext"
8844 [(set (match_operand:DI 0 "register_operand" "=d")
8845 (zero_extend:DI (truncate:SI
8847 (mult:DI (sign_extend:DI
8848 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8850 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8852 (clobber (match_scratch:SI 3 "=1"))
8853 (clobber (reg:CC FLAGS_REG))]
8855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8857 [(set_attr "type" "imul")
8858 (set (attr "athlon_decode")
8859 (if_then_else (eq_attr "cpu" "athlon")
8860 (const_string "vector")
8861 (const_string "double")))
8862 (set_attr "amdfam10_decode" "double")
8863 (set_attr "mode" "SI")])
8865 ;; The patterns that match these are at the end of this file.
8867 (define_expand "mulxf3"
8868 [(set (match_operand:XF 0 "register_operand" "")
8869 (mult:XF (match_operand:XF 1 "register_operand" "")
8870 (match_operand:XF 2 "register_operand" "")))]
8874 (define_expand "mul<mode>3"
8875 [(set (match_operand:MODEF 0 "register_operand" "")
8876 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8877 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8878 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8879 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8882 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8885 ;; Divide instructions
8887 (define_insn "divqi3"
8888 [(set (match_operand:QI 0 "register_operand" "=a")
8889 (div:QI (match_operand:HI 1 "register_operand" "0")
8890 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "TARGET_QIMODE_MATH"
8894 [(set_attr "type" "idiv")
8895 (set_attr "mode" "QI")])
8897 (define_insn "udivqi3"
8898 [(set (match_operand:QI 0 "register_operand" "=a")
8899 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8900 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8901 (clobber (reg:CC FLAGS_REG))]
8902 "TARGET_QIMODE_MATH"
8904 [(set_attr "type" "idiv")
8905 (set_attr "mode" "QI")])
8907 ;; The patterns that match these are at the end of this file.
8909 (define_expand "divxf3"
8910 [(set (match_operand:XF 0 "register_operand" "")
8911 (div:XF (match_operand:XF 1 "register_operand" "")
8912 (match_operand:XF 2 "register_operand" "")))]
8916 (define_expand "divdf3"
8917 [(set (match_operand:DF 0 "register_operand" "")
8918 (div:DF (match_operand:DF 1 "register_operand" "")
8919 (match_operand:DF 2 "nonimmediate_operand" "")))]
8920 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8921 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8924 (define_expand "divsf3"
8925 [(set (match_operand:SF 0 "register_operand" "")
8926 (div:SF (match_operand:SF 1 "register_operand" "")
8927 (match_operand:SF 2 "nonimmediate_operand" "")))]
8928 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8931 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8932 && flag_finite_math_only && !flag_trapping_math
8933 && flag_unsafe_math_optimizations)
8935 ix86_emit_swdivsf (operands[0], operands[1],
8936 operands[2], SFmode);
8941 ;; Remainder instructions.
8943 (define_expand "divmoddi4"
8944 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8945 (div:DI (match_operand:DI 1 "register_operand" "")
8946 (match_operand:DI 2 "nonimmediate_operand" "")))
8947 (set (match_operand:DI 3 "register_operand" "")
8948 (mod:DI (match_dup 1) (match_dup 2)))
8949 (clobber (reg:CC FLAGS_REG))])]
8953 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8954 ;; Penalize eax case slightly because it results in worse scheduling
8956 (define_insn "*divmoddi4_nocltd_rex64"
8957 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8958 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8959 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8960 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8961 (mod:DI (match_dup 2) (match_dup 3)))
8962 (clobber (reg:CC FLAGS_REG))]
8963 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8965 [(set_attr "type" "multi")])
8967 (define_insn "*divmoddi4_cltd_rex64"
8968 [(set (match_operand:DI 0 "register_operand" "=a")
8969 (div:DI (match_operand:DI 2 "register_operand" "a")
8970 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8971 (set (match_operand:DI 1 "register_operand" "=&d")
8972 (mod:DI (match_dup 2) (match_dup 3)))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8976 [(set_attr "type" "multi")])
8978 (define_insn "*divmoddi_noext_rex64"
8979 [(set (match_operand:DI 0 "register_operand" "=a")
8980 (div:DI (match_operand:DI 1 "register_operand" "0")
8981 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8982 (set (match_operand:DI 3 "register_operand" "=d")
8983 (mod:DI (match_dup 1) (match_dup 2)))
8984 (use (match_operand:DI 4 "register_operand" "3"))
8985 (clobber (reg:CC FLAGS_REG))]
8988 [(set_attr "type" "idiv")
8989 (set_attr "mode" "DI")])
8992 [(set (match_operand:DI 0 "register_operand" "")
8993 (div:DI (match_operand:DI 1 "register_operand" "")
8994 (match_operand:DI 2 "nonimmediate_operand" "")))
8995 (set (match_operand:DI 3 "register_operand" "")
8996 (mod:DI (match_dup 1) (match_dup 2)))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "TARGET_64BIT && reload_completed"
8999 [(parallel [(set (match_dup 3)
9000 (ashiftrt:DI (match_dup 4) (const_int 63)))
9001 (clobber (reg:CC FLAGS_REG))])
9002 (parallel [(set (match_dup 0)
9003 (div:DI (reg:DI 0) (match_dup 2)))
9005 (mod:DI (reg:DI 0) (match_dup 2)))
9007 (clobber (reg:CC FLAGS_REG))])]
9009 /* Avoid use of cltd in favor of a mov+shift. */
9010 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9012 if (true_regnum (operands[1]))
9013 emit_move_insn (operands[0], operands[1]);
9015 emit_move_insn (operands[3], operands[1]);
9016 operands[4] = operands[3];
9020 gcc_assert (!true_regnum (operands[1]));
9021 operands[4] = operands[1];
9026 (define_expand "divmodsi4"
9027 [(parallel [(set (match_operand:SI 0 "register_operand" "")
9028 (div:SI (match_operand:SI 1 "register_operand" "")
9029 (match_operand:SI 2 "nonimmediate_operand" "")))
9030 (set (match_operand:SI 3 "register_operand" "")
9031 (mod:SI (match_dup 1) (match_dup 2)))
9032 (clobber (reg:CC FLAGS_REG))])]
9036 ;; Allow to come the parameter in eax or edx to avoid extra moves.
9037 ;; Penalize eax case slightly because it results in worse scheduling
9039 (define_insn "*divmodsi4_nocltd"
9040 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9041 (div:SI (match_operand:SI 2 "register_operand" "1,0")
9042 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9043 (set (match_operand:SI 1 "register_operand" "=&d,&d")
9044 (mod:SI (match_dup 2) (match_dup 3)))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9048 [(set_attr "type" "multi")])
9050 (define_insn "*divmodsi4_cltd"
9051 [(set (match_operand:SI 0 "register_operand" "=a")
9052 (div:SI (match_operand:SI 2 "register_operand" "a")
9053 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9054 (set (match_operand:SI 1 "register_operand" "=&d")
9055 (mod:SI (match_dup 2) (match_dup 3)))
9056 (clobber (reg:CC FLAGS_REG))]
9057 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
9059 [(set_attr "type" "multi")])
9061 (define_insn "*divmodsi_noext"
9062 [(set (match_operand:SI 0 "register_operand" "=a")
9063 (div:SI (match_operand:SI 1 "register_operand" "0")
9064 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9065 (set (match_operand:SI 3 "register_operand" "=d")
9066 (mod:SI (match_dup 1) (match_dup 2)))
9067 (use (match_operand:SI 4 "register_operand" "3"))
9068 (clobber (reg:CC FLAGS_REG))]
9071 [(set_attr "type" "idiv")
9072 (set_attr "mode" "SI")])
9075 [(set (match_operand:SI 0 "register_operand" "")
9076 (div:SI (match_operand:SI 1 "register_operand" "")
9077 (match_operand:SI 2 "nonimmediate_operand" "")))
9078 (set (match_operand:SI 3 "register_operand" "")
9079 (mod:SI (match_dup 1) (match_dup 2)))
9080 (clobber (reg:CC FLAGS_REG))]
9082 [(parallel [(set (match_dup 3)
9083 (ashiftrt:SI (match_dup 4) (const_int 31)))
9084 (clobber (reg:CC FLAGS_REG))])
9085 (parallel [(set (match_dup 0)
9086 (div:SI (reg:SI 0) (match_dup 2)))
9088 (mod:SI (reg:SI 0) (match_dup 2)))
9090 (clobber (reg:CC FLAGS_REG))])]
9092 /* Avoid use of cltd in favor of a mov+shift. */
9093 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9095 if (true_regnum (operands[1]))
9096 emit_move_insn (operands[0], operands[1]);
9098 emit_move_insn (operands[3], operands[1]);
9099 operands[4] = operands[3];
9103 gcc_assert (!true_regnum (operands[1]));
9104 operands[4] = operands[1];
9108 (define_insn "divmodhi4"
9109 [(set (match_operand:HI 0 "register_operand" "=a")
9110 (div:HI (match_operand:HI 1 "register_operand" "0")
9111 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9112 (set (match_operand:HI 3 "register_operand" "=&d")
9113 (mod:HI (match_dup 1) (match_dup 2)))
9114 (clobber (reg:CC FLAGS_REG))]
9115 "TARGET_HIMODE_MATH"
9117 [(set_attr "type" "multi")
9118 (set_attr "length_immediate" "0")
9119 (set_attr "mode" "SI")])
9121 (define_insn "udivmoddi4"
9122 [(set (match_operand:DI 0 "register_operand" "=a")
9123 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9124 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9125 (set (match_operand:DI 3 "register_operand" "=&d")
9126 (umod:DI (match_dup 1) (match_dup 2)))
9127 (clobber (reg:CC FLAGS_REG))]
9129 "xor{q}\t%3, %3\;div{q}\t%2"
9130 [(set_attr "type" "multi")
9131 (set_attr "length_immediate" "0")
9132 (set_attr "mode" "DI")])
9134 (define_insn "*udivmoddi4_noext"
9135 [(set (match_operand:DI 0 "register_operand" "=a")
9136 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9137 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9138 (set (match_operand:DI 3 "register_operand" "=d")
9139 (umod:DI (match_dup 1) (match_dup 2)))
9141 (clobber (reg:CC FLAGS_REG))]
9144 [(set_attr "type" "idiv")
9145 (set_attr "mode" "DI")])
9148 [(set (match_operand:DI 0 "register_operand" "")
9149 (udiv:DI (match_operand:DI 1 "register_operand" "")
9150 (match_operand:DI 2 "nonimmediate_operand" "")))
9151 (set (match_operand:DI 3 "register_operand" "")
9152 (umod:DI (match_dup 1) (match_dup 2)))
9153 (clobber (reg:CC FLAGS_REG))]
9154 "TARGET_64BIT && reload_completed"
9155 [(set (match_dup 3) (const_int 0))
9156 (parallel [(set (match_dup 0)
9157 (udiv:DI (match_dup 1) (match_dup 2)))
9159 (umod:DI (match_dup 1) (match_dup 2)))
9161 (clobber (reg:CC FLAGS_REG))])]
9164 (define_insn "udivmodsi4"
9165 [(set (match_operand:SI 0 "register_operand" "=a")
9166 (udiv:SI (match_operand:SI 1 "register_operand" "0")
9167 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9168 (set (match_operand:SI 3 "register_operand" "=&d")
9169 (umod:SI (match_dup 1) (match_dup 2)))
9170 (clobber (reg:CC FLAGS_REG))]
9172 "xor{l}\t%3, %3\;div{l}\t%2"
9173 [(set_attr "type" "multi")
9174 (set_attr "length_immediate" "0")
9175 (set_attr "mode" "SI")])
9177 (define_insn "*udivmodsi4_noext"
9178 [(set (match_operand:SI 0 "register_operand" "=a")
9179 (udiv:SI (match_operand:SI 1 "register_operand" "0")
9180 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9181 (set (match_operand:SI 3 "register_operand" "=d")
9182 (umod:SI (match_dup 1) (match_dup 2)))
9184 (clobber (reg:CC FLAGS_REG))]
9187 [(set_attr "type" "idiv")
9188 (set_attr "mode" "SI")])
9191 [(set (match_operand:SI 0 "register_operand" "")
9192 (udiv:SI (match_operand:SI 1 "register_operand" "")
9193 (match_operand:SI 2 "nonimmediate_operand" "")))
9194 (set (match_operand:SI 3 "register_operand" "")
9195 (umod:SI (match_dup 1) (match_dup 2)))
9196 (clobber (reg:CC FLAGS_REG))]
9198 [(set (match_dup 3) (const_int 0))
9199 (parallel [(set (match_dup 0)
9200 (udiv:SI (match_dup 1) (match_dup 2)))
9202 (umod:SI (match_dup 1) (match_dup 2)))
9204 (clobber (reg:CC FLAGS_REG))])]
9207 (define_expand "udivmodhi4"
9208 [(set (match_dup 4) (const_int 0))
9209 (parallel [(set (match_operand:HI 0 "register_operand" "")
9210 (udiv:HI (match_operand:HI 1 "register_operand" "")
9211 (match_operand:HI 2 "nonimmediate_operand" "")))
9212 (set (match_operand:HI 3 "register_operand" "")
9213 (umod:HI (match_dup 1) (match_dup 2)))
9215 (clobber (reg:CC FLAGS_REG))])]
9216 "TARGET_HIMODE_MATH"
9217 "operands[4] = gen_reg_rtx (HImode);")
9219 (define_insn "*udivmodhi_noext"
9220 [(set (match_operand:HI 0 "register_operand" "=a")
9221 (udiv:HI (match_operand:HI 1 "register_operand" "0")
9222 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9223 (set (match_operand:HI 3 "register_operand" "=d")
9224 (umod:HI (match_dup 1) (match_dup 2)))
9225 (use (match_operand:HI 4 "register_operand" "3"))
9226 (clobber (reg:CC FLAGS_REG))]
9229 [(set_attr "type" "idiv")
9230 (set_attr "mode" "HI")])
9232 ;; We cannot use div/idiv for double division, because it causes
9233 ;; "division by zero" on the overflow and that's not what we expect
9234 ;; from truncate. Because true (non truncating) double division is
9235 ;; never generated, we can't create this insn anyway.
9238 ; [(set (match_operand:SI 0 "register_operand" "=a")
9240 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
9242 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9243 ; (set (match_operand:SI 3 "register_operand" "=d")
9245 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9246 ; (clobber (reg:CC FLAGS_REG))]
9248 ; "div{l}\t{%2, %0|%0, %2}"
9249 ; [(set_attr "type" "idiv")])
9251 ;;- Logical AND instructions
9253 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9254 ;; Note that this excludes ah.
9256 (define_insn "*testdi_1_rex64"
9257 [(set (reg FLAGS_REG)
9259 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9260 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9262 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9263 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9265 test{l}\t{%k1, %k0|%k0, %k1}
9266 test{l}\t{%k1, %k0|%k0, %k1}
9267 test{q}\t{%1, %0|%0, %1}
9268 test{q}\t{%1, %0|%0, %1}
9269 test{q}\t{%1, %0|%0, %1}"
9270 [(set_attr "type" "test")
9271 (set_attr "modrm" "0,1,0,1,1")
9272 (set_attr "mode" "SI,SI,DI,DI,DI")
9273 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9275 (define_insn "testsi_1"
9276 [(set (reg FLAGS_REG)
9278 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9279 (match_operand:SI 1 "general_operand" "i,i,ri"))
9281 "ix86_match_ccmode (insn, CCNOmode)
9282 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9283 "test{l}\t{%1, %0|%0, %1}"
9284 [(set_attr "type" "test")
9285 (set_attr "modrm" "0,1,1")
9286 (set_attr "mode" "SI")
9287 (set_attr "pent_pair" "uv,np,uv")])
9289 (define_expand "testsi_ccno_1"
9290 [(set (reg:CCNO FLAGS_REG)
9292 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9293 (match_operand:SI 1 "nonmemory_operand" ""))
9298 (define_insn "*testhi_1"
9299 [(set (reg FLAGS_REG)
9300 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9301 (match_operand:HI 1 "general_operand" "n,n,rn"))
9303 "ix86_match_ccmode (insn, CCNOmode)
9304 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9305 "test{w}\t{%1, %0|%0, %1}"
9306 [(set_attr "type" "test")
9307 (set_attr "modrm" "0,1,1")
9308 (set_attr "mode" "HI")
9309 (set_attr "pent_pair" "uv,np,uv")])
9311 (define_expand "testqi_ccz_1"
9312 [(set (reg:CCZ FLAGS_REG)
9313 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9314 (match_operand:QI 1 "nonmemory_operand" ""))
9319 (define_insn "*testqi_1_maybe_si"
9320 [(set (reg FLAGS_REG)
9323 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9324 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9327 && ix86_match_ccmode (insn,
9328 CONST_INT_P (operands[1])
9329 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9331 if (which_alternative == 3)
9333 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9334 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9335 return "test{l}\t{%1, %k0|%k0, %1}";
9337 return "test{b}\t{%1, %0|%0, %1}";
9339 [(set_attr "type" "test")
9340 (set_attr "modrm" "0,1,1,1")
9341 (set_attr "mode" "QI,QI,QI,SI")
9342 (set_attr "pent_pair" "uv,np,uv,np")])
9344 (define_insn "*testqi_1"
9345 [(set (reg FLAGS_REG)
9348 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9349 (match_operand:QI 1 "general_operand" "n,n,qn"))
9351 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9352 && ix86_match_ccmode (insn, CCNOmode)"
9353 "test{b}\t{%1, %0|%0, %1}"
9354 [(set_attr "type" "test")
9355 (set_attr "modrm" "0,1,1")
9356 (set_attr "mode" "QI")
9357 (set_attr "pent_pair" "uv,np,uv")])
9359 (define_expand "testqi_ext_ccno_0"
9360 [(set (reg:CCNO FLAGS_REG)
9364 (match_operand 0 "ext_register_operand" "")
9367 (match_operand 1 "const_int_operand" ""))
9372 (define_insn "*testqi_ext_0"
9373 [(set (reg FLAGS_REG)
9377 (match_operand 0 "ext_register_operand" "Q")
9380 (match_operand 1 "const_int_operand" "n"))
9382 "ix86_match_ccmode (insn, CCNOmode)"
9383 "test{b}\t{%1, %h0|%h0, %1}"
9384 [(set_attr "type" "test")
9385 (set_attr "mode" "QI")
9386 (set_attr "length_immediate" "1")
9387 (set_attr "modrm" "1")
9388 (set_attr "pent_pair" "np")])
9390 (define_insn "*testqi_ext_1"
9391 [(set (reg FLAGS_REG)
9395 (match_operand 0 "ext_register_operand" "Q")
9399 (match_operand:QI 1 "general_operand" "Qm")))
9401 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9403 "test{b}\t{%1, %h0|%h0, %1}"
9404 [(set_attr "type" "test")
9405 (set_attr "mode" "QI")])
9407 (define_insn "*testqi_ext_1_rex64"
9408 [(set (reg FLAGS_REG)
9412 (match_operand 0 "ext_register_operand" "Q")
9416 (match_operand:QI 1 "register_operand" "Q")))
9418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9419 "test{b}\t{%1, %h0|%h0, %1}"
9420 [(set_attr "type" "test")
9421 (set_attr "mode" "QI")])
9423 (define_insn "*testqi_ext_2"
9424 [(set (reg FLAGS_REG)
9428 (match_operand 0 "ext_register_operand" "Q")
9432 (match_operand 1 "ext_register_operand" "Q")
9436 "ix86_match_ccmode (insn, CCNOmode)"
9437 "test{b}\t{%h1, %h0|%h0, %h1}"
9438 [(set_attr "type" "test")
9439 (set_attr "mode" "QI")])
9441 ;; Combine likes to form bit extractions for some tests. Humor it.
9442 (define_insn "*testqi_ext_3"
9443 [(set (reg FLAGS_REG)
9444 (compare (zero_extract:SI
9445 (match_operand 0 "nonimmediate_operand" "rm")
9446 (match_operand:SI 1 "const_int_operand" "")
9447 (match_operand:SI 2 "const_int_operand" ""))
9449 "ix86_match_ccmode (insn, CCNOmode)
9450 && INTVAL (operands[1]) > 0
9451 && INTVAL (operands[2]) >= 0
9452 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9453 && (GET_MODE (operands[0]) == SImode
9454 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9455 || GET_MODE (operands[0]) == HImode
9456 || GET_MODE (operands[0]) == QImode)"
9459 (define_insn "*testqi_ext_3_rex64"
9460 [(set (reg FLAGS_REG)
9461 (compare (zero_extract:DI
9462 (match_operand 0 "nonimmediate_operand" "rm")
9463 (match_operand:DI 1 "const_int_operand" "")
9464 (match_operand:DI 2 "const_int_operand" ""))
9467 && ix86_match_ccmode (insn, CCNOmode)
9468 && INTVAL (operands[1]) > 0
9469 && INTVAL (operands[2]) >= 0
9470 /* Ensure that resulting mask is zero or sign extended operand. */
9471 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9472 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9473 && INTVAL (operands[1]) > 32))
9474 && (GET_MODE (operands[0]) == SImode
9475 || GET_MODE (operands[0]) == DImode
9476 || GET_MODE (operands[0]) == HImode
9477 || GET_MODE (operands[0]) == QImode)"
9481 [(set (match_operand 0 "flags_reg_operand" "")
9482 (match_operator 1 "compare_operator"
9484 (match_operand 2 "nonimmediate_operand" "")
9485 (match_operand 3 "const_int_operand" "")
9486 (match_operand 4 "const_int_operand" ""))
9488 "ix86_match_ccmode (insn, CCNOmode)"
9489 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9491 rtx val = operands[2];
9492 HOST_WIDE_INT len = INTVAL (operands[3]);
9493 HOST_WIDE_INT pos = INTVAL (operands[4]);
9495 enum machine_mode mode, submode;
9497 mode = GET_MODE (val);
9500 /* ??? Combine likes to put non-volatile mem extractions in QImode
9501 no matter the size of the test. So find a mode that works. */
9502 if (! MEM_VOLATILE_P (val))
9504 mode = smallest_mode_for_size (pos + len, MODE_INT);
9505 val = adjust_address (val, mode, 0);
9508 else if (GET_CODE (val) == SUBREG
9509 && (submode = GET_MODE (SUBREG_REG (val)),
9510 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9511 && pos + len <= GET_MODE_BITSIZE (submode))
9513 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9515 val = SUBREG_REG (val);
9517 else if (mode == HImode && pos + len <= 8)
9519 /* Small HImode tests can be converted to QImode. */
9521 val = gen_lowpart (QImode, val);
9524 if (len == HOST_BITS_PER_WIDE_INT)
9527 mask = ((HOST_WIDE_INT)1 << len) - 1;
9530 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9533 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9534 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9535 ;; this is relatively important trick.
9536 ;; Do the conversion only post-reload to avoid limiting of the register class
9539 [(set (match_operand 0 "flags_reg_operand" "")
9540 (match_operator 1 "compare_operator"
9541 [(and (match_operand 2 "register_operand" "")
9542 (match_operand 3 "const_int_operand" ""))
9545 && QI_REG_P (operands[2])
9546 && GET_MODE (operands[2]) != QImode
9547 && ((ix86_match_ccmode (insn, CCZmode)
9548 && !(INTVAL (operands[3]) & ~(255 << 8)))
9549 || (ix86_match_ccmode (insn, CCNOmode)
9550 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9553 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9556 "operands[2] = gen_lowpart (SImode, operands[2]);
9557 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9560 [(set (match_operand 0 "flags_reg_operand" "")
9561 (match_operator 1 "compare_operator"
9562 [(and (match_operand 2 "nonimmediate_operand" "")
9563 (match_operand 3 "const_int_operand" ""))
9566 && GET_MODE (operands[2]) != QImode
9567 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9568 && ((ix86_match_ccmode (insn, CCZmode)
9569 && !(INTVAL (operands[3]) & ~255))
9570 || (ix86_match_ccmode (insn, CCNOmode)
9571 && !(INTVAL (operands[3]) & ~127)))"
9573 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9575 "operands[2] = gen_lowpart (QImode, operands[2]);
9576 operands[3] = gen_lowpart (QImode, operands[3]);")
9579 ;; %%% This used to optimize known byte-wide and operations to memory,
9580 ;; and sometimes to QImode registers. If this is considered useful,
9581 ;; it should be done with splitters.
9583 (define_expand "anddi3"
9584 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9588 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9590 (define_insn "*anddi_1_rex64"
9591 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9592 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9593 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9597 switch (get_attr_type (insn))
9601 enum machine_mode mode;
9603 gcc_assert (CONST_INT_P (operands[2]));
9604 if (INTVAL (operands[2]) == 0xff)
9608 gcc_assert (INTVAL (operands[2]) == 0xffff);
9612 operands[1] = gen_lowpart (mode, operands[1]);
9614 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9616 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9621 if (get_attr_mode (insn) == MODE_SI)
9622 return "and{l}\t{%k2, %k0|%k0, %k2}";
9624 return "and{q}\t{%2, %0|%0, %2}";
9627 [(set_attr "type" "alu,alu,alu,imovx")
9628 (set_attr "length_immediate" "*,*,*,0")
9629 (set (attr "prefix_rex")
9631 (and (eq_attr "type" "imovx")
9632 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9633 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9635 (const_string "*")))
9636 (set_attr "mode" "SI,DI,DI,SI")])
9638 (define_insn "*anddi_2"
9639 [(set (reg FLAGS_REG)
9640 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9641 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9643 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9644 (and:DI (match_dup 1) (match_dup 2)))]
9645 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9646 && ix86_binary_operator_ok (AND, DImode, operands)"
9648 and{l}\t{%k2, %k0|%k0, %k2}
9649 and{q}\t{%2, %0|%0, %2}
9650 and{q}\t{%2, %0|%0, %2}"
9651 [(set_attr "type" "alu")
9652 (set_attr "mode" "SI,DI,DI")])
9654 (define_expand "andsi3"
9655 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9656 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9657 (match_operand:SI 2 "general_operand" "")))]
9659 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9661 (define_insn "*andsi_1"
9662 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9663 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9664 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9665 (clobber (reg:CC FLAGS_REG))]
9666 "ix86_binary_operator_ok (AND, SImode, operands)"
9668 switch (get_attr_type (insn))
9672 enum machine_mode mode;
9674 gcc_assert (CONST_INT_P (operands[2]));
9675 if (INTVAL (operands[2]) == 0xff)
9679 gcc_assert (INTVAL (operands[2]) == 0xffff);
9683 operands[1] = gen_lowpart (mode, operands[1]);
9685 return "movz{bl|x}\t{%1, %0|%0, %1}";
9687 return "movz{wl|x}\t{%1, %0|%0, %1}";
9691 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9692 return "and{l}\t{%2, %0|%0, %2}";
9695 [(set_attr "type" "alu,alu,imovx")
9696 (set (attr "prefix_rex")
9698 (and (eq_attr "type" "imovx")
9699 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9700 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9702 (const_string "*")))
9703 (set_attr "length_immediate" "*,*,0")
9704 (set_attr "mode" "SI")])
9707 [(set (match_operand 0 "register_operand" "")
9709 (const_int -65536)))
9710 (clobber (reg:CC FLAGS_REG))]
9711 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9712 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9713 "operands[1] = gen_lowpart (HImode, operands[0]);")
9716 [(set (match_operand 0 "ext_register_operand" "")
9719 (clobber (reg:CC FLAGS_REG))]
9720 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9721 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9722 "operands[1] = gen_lowpart (QImode, operands[0]);")
9725 [(set (match_operand 0 "ext_register_operand" "")
9727 (const_int -65281)))
9728 (clobber (reg:CC FLAGS_REG))]
9729 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9730 [(parallel [(set (zero_extract:SI (match_dup 0)
9734 (zero_extract:SI (match_dup 0)
9737 (zero_extract:SI (match_dup 0)
9740 (clobber (reg:CC FLAGS_REG))])]
9741 "operands[0] = gen_lowpart (SImode, operands[0]);")
9743 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9744 (define_insn "*andsi_1_zext"
9745 [(set (match_operand:DI 0 "register_operand" "=r")
9747 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9748 (match_operand:SI 2 "general_operand" "g"))))
9749 (clobber (reg:CC FLAGS_REG))]
9750 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9751 "and{l}\t{%2, %k0|%k0, %2}"
9752 [(set_attr "type" "alu")
9753 (set_attr "mode" "SI")])
9755 (define_insn "*andsi_2"
9756 [(set (reg FLAGS_REG)
9757 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9758 (match_operand:SI 2 "general_operand" "g,ri"))
9760 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9761 (and:SI (match_dup 1) (match_dup 2)))]
9762 "ix86_match_ccmode (insn, CCNOmode)
9763 && ix86_binary_operator_ok (AND, SImode, operands)"
9764 "and{l}\t{%2, %0|%0, %2}"
9765 [(set_attr "type" "alu")
9766 (set_attr "mode" "SI")])
9768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9769 (define_insn "*andsi_2_zext"
9770 [(set (reg FLAGS_REG)
9771 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9772 (match_operand:SI 2 "general_operand" "g"))
9774 (set (match_operand:DI 0 "register_operand" "=r")
9775 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9776 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9777 && ix86_binary_operator_ok (AND, SImode, operands)"
9778 "and{l}\t{%2, %k0|%k0, %2}"
9779 [(set_attr "type" "alu")
9780 (set_attr "mode" "SI")])
9782 (define_expand "andhi3"
9783 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9784 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9785 (match_operand:HI 2 "general_operand" "")))]
9786 "TARGET_HIMODE_MATH"
9787 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9789 (define_insn "*andhi_1"
9790 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9791 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9792 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9793 (clobber (reg:CC FLAGS_REG))]
9794 "ix86_binary_operator_ok (AND, HImode, operands)"
9796 switch (get_attr_type (insn))
9799 gcc_assert (CONST_INT_P (operands[2]));
9800 gcc_assert (INTVAL (operands[2]) == 0xff);
9801 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9806 return "and{w}\t{%2, %0|%0, %2}";
9809 [(set_attr "type" "alu,alu,imovx")
9810 (set_attr "length_immediate" "*,*,0")
9811 (set (attr "prefix_rex")
9813 (and (eq_attr "type" "imovx")
9814 (match_operand 1 "ext_QIreg_nomode_operand" ""))
9816 (const_string "*")))
9817 (set_attr "mode" "HI,HI,SI")])
9819 (define_insn "*andhi_2"
9820 [(set (reg FLAGS_REG)
9821 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9822 (match_operand:HI 2 "general_operand" "rmn,rn"))
9824 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9825 (and:HI (match_dup 1) (match_dup 2)))]
9826 "ix86_match_ccmode (insn, CCNOmode)
9827 && ix86_binary_operator_ok (AND, HImode, operands)"
9828 "and{w}\t{%2, %0|%0, %2}"
9829 [(set_attr "type" "alu")
9830 (set_attr "mode" "HI")])
9832 (define_expand "andqi3"
9833 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9834 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9835 (match_operand:QI 2 "general_operand" "")))]
9836 "TARGET_QIMODE_MATH"
9837 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9839 ;; %%% Potential partial reg stall on alternative 2. What to do?
9840 (define_insn "*andqi_1"
9841 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9842 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9843 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9844 (clobber (reg:CC FLAGS_REG))]
9845 "ix86_binary_operator_ok (AND, QImode, operands)"
9847 and{b}\t{%2, %0|%0, %2}
9848 and{b}\t{%2, %0|%0, %2}
9849 and{l}\t{%k2, %k0|%k0, %k2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "QI,QI,SI")])
9853 (define_insn "*andqi_1_slp"
9854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9855 (and:QI (match_dup 0)
9856 (match_operand:QI 1 "general_operand" "qn,qmn")))
9857 (clobber (reg:CC FLAGS_REG))]
9858 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9859 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9860 "and{b}\t{%1, %0|%0, %1}"
9861 [(set_attr "type" "alu1")
9862 (set_attr "mode" "QI")])
9864 (define_insn "*andqi_2_maybe_si"
9865 [(set (reg FLAGS_REG)
9867 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9868 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9870 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9871 (and:QI (match_dup 1) (match_dup 2)))]
9872 "ix86_binary_operator_ok (AND, QImode, operands)
9873 && ix86_match_ccmode (insn,
9874 CONST_INT_P (operands[2])
9875 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9877 if (which_alternative == 2)
9879 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9880 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9881 return "and{l}\t{%2, %k0|%k0, %2}";
9883 return "and{b}\t{%2, %0|%0, %2}";
9885 [(set_attr "type" "alu")
9886 (set_attr "mode" "QI,QI,SI")])
9888 (define_insn "*andqi_2"
9889 [(set (reg FLAGS_REG)
9891 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9892 (match_operand:QI 2 "general_operand" "qmn,qn"))
9894 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9895 (and:QI (match_dup 1) (match_dup 2)))]
9896 "ix86_match_ccmode (insn, CCNOmode)
9897 && ix86_binary_operator_ok (AND, QImode, operands)"
9898 "and{b}\t{%2, %0|%0, %2}"
9899 [(set_attr "type" "alu")
9900 (set_attr "mode" "QI")])
9902 (define_insn "*andqi_2_slp"
9903 [(set (reg FLAGS_REG)
9905 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9906 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9908 (set (strict_low_part (match_dup 0))
9909 (and:QI (match_dup 0) (match_dup 1)))]
9910 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9911 && ix86_match_ccmode (insn, CCNOmode)
9912 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9913 "and{b}\t{%1, %0|%0, %1}"
9914 [(set_attr "type" "alu1")
9915 (set_attr "mode" "QI")])
9917 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9918 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9919 ;; for a QImode operand, which of course failed.
9921 (define_insn "andqi_ext_0"
9922 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9927 (match_operand 1 "ext_register_operand" "0")
9930 (match_operand 2 "const_int_operand" "n")))
9931 (clobber (reg:CC FLAGS_REG))]
9933 "and{b}\t{%2, %h0|%h0, %2}"
9934 [(set_attr "type" "alu")
9935 (set_attr "length_immediate" "1")
9936 (set_attr "modrm" "1")
9937 (set_attr "mode" "QI")])
9939 ;; Generated by peephole translating test to and. This shows up
9940 ;; often in fp comparisons.
9942 (define_insn "*andqi_ext_0_cc"
9943 [(set (reg FLAGS_REG)
9947 (match_operand 1 "ext_register_operand" "0")
9950 (match_operand 2 "const_int_operand" "n"))
9952 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9961 "ix86_match_ccmode (insn, CCNOmode)"
9962 "and{b}\t{%2, %h0|%h0, %2}"
9963 [(set_attr "type" "alu")
9964 (set_attr "length_immediate" "1")
9965 (set_attr "modrm" "1")
9966 (set_attr "mode" "QI")])
9968 (define_insn "*andqi_ext_1"
9969 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9974 (match_operand 1 "ext_register_operand" "0")
9978 (match_operand:QI 2 "general_operand" "Qm"))))
9979 (clobber (reg:CC FLAGS_REG))]
9981 "and{b}\t{%2, %h0|%h0, %2}"
9982 [(set_attr "type" "alu")
9983 (set_attr "length_immediate" "0")
9984 (set_attr "mode" "QI")])
9986 (define_insn "*andqi_ext_1_rex64"
9987 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9992 (match_operand 1 "ext_register_operand" "0")
9996 (match_operand 2 "ext_register_operand" "Q"))))
9997 (clobber (reg:CC FLAGS_REG))]
9999 "and{b}\t{%2, %h0|%h0, %2}"
10000 [(set_attr "type" "alu")
10001 (set_attr "length_immediate" "0")
10002 (set_attr "mode" "QI")])
10004 (define_insn "*andqi_ext_2"
10005 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10010 (match_operand 1 "ext_register_operand" "%0")
10014 (match_operand 2 "ext_register_operand" "Q")
10017 (clobber (reg:CC FLAGS_REG))]
10019 "and{b}\t{%h2, %h0|%h0, %h2}"
10020 [(set_attr "type" "alu")
10021 (set_attr "length_immediate" "0")
10022 (set_attr "mode" "QI")])
10024 ;; Convert wide AND instructions with immediate operand to shorter QImode
10025 ;; equivalents when possible.
10026 ;; Don't do the splitting with memory operands, since it introduces risk
10027 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
10028 ;; for size, but that can (should?) be handled by generic code instead.
10030 [(set (match_operand 0 "register_operand" "")
10031 (and (match_operand 1 "register_operand" "")
10032 (match_operand 2 "const_int_operand" "")))
10033 (clobber (reg:CC FLAGS_REG))]
10035 && QI_REG_P (operands[0])
10036 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10037 && !(~INTVAL (operands[2]) & ~(255 << 8))
10038 && GET_MODE (operands[0]) != QImode"
10039 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10040 (and:SI (zero_extract:SI (match_dup 1)
10041 (const_int 8) (const_int 8))
10043 (clobber (reg:CC FLAGS_REG))])]
10044 "operands[0] = gen_lowpart (SImode, operands[0]);
10045 operands[1] = gen_lowpart (SImode, operands[1]);
10046 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10048 ;; Since AND can be encoded with sign extended immediate, this is only
10049 ;; profitable when 7th bit is not set.
10051 [(set (match_operand 0 "register_operand" "")
10052 (and (match_operand 1 "general_operand" "")
10053 (match_operand 2 "const_int_operand" "")))
10054 (clobber (reg:CC FLAGS_REG))]
10056 && ANY_QI_REG_P (operands[0])
10057 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10058 && !(~INTVAL (operands[2]) & ~255)
10059 && !(INTVAL (operands[2]) & 128)
10060 && GET_MODE (operands[0]) != QImode"
10061 [(parallel [(set (strict_low_part (match_dup 0))
10062 (and:QI (match_dup 1)
10064 (clobber (reg:CC FLAGS_REG))])]
10065 "operands[0] = gen_lowpart (QImode, operands[0]);
10066 operands[1] = gen_lowpart (QImode, operands[1]);
10067 operands[2] = gen_lowpart (QImode, operands[2]);")
10069 ;; Logical inclusive OR instructions
10071 ;; %%% This used to optimize known byte-wide and operations to memory.
10072 ;; If this is considered useful, it should be done with splitters.
10074 (define_expand "iordi3"
10075 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10076 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
10077 (match_operand:DI 2 "x86_64_general_operand" "")))]
10079 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10081 (define_insn "*iordi_1_rex64"
10082 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10083 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10084 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
10085 (clobber (reg:CC FLAGS_REG))]
10087 && ix86_binary_operator_ok (IOR, DImode, operands)"
10088 "or{q}\t{%2, %0|%0, %2}"
10089 [(set_attr "type" "alu")
10090 (set_attr "mode" "DI")])
10092 (define_insn "*iordi_2_rex64"
10093 [(set (reg FLAGS_REG)
10094 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10095 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10097 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10098 (ior:DI (match_dup 1) (match_dup 2)))]
10100 && ix86_match_ccmode (insn, CCNOmode)
10101 && ix86_binary_operator_ok (IOR, DImode, operands)"
10102 "or{q}\t{%2, %0|%0, %2}"
10103 [(set_attr "type" "alu")
10104 (set_attr "mode" "DI")])
10106 (define_insn "*iordi_3_rex64"
10107 [(set (reg FLAGS_REG)
10108 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10109 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10111 (clobber (match_scratch:DI 0 "=r"))]
10113 && ix86_match_ccmode (insn, CCNOmode)
10114 && ix86_binary_operator_ok (IOR, DImode, operands)"
10115 "or{q}\t{%2, %0|%0, %2}"
10116 [(set_attr "type" "alu")
10117 (set_attr "mode" "DI")])
10120 (define_expand "iorsi3"
10121 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
10123 (match_operand:SI 2 "general_operand" "")))]
10125 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10127 (define_insn "*iorsi_1"
10128 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10129 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10130 (match_operand:SI 2 "general_operand" "ri,g")))
10131 (clobber (reg:CC FLAGS_REG))]
10132 "ix86_binary_operator_ok (IOR, SImode, operands)"
10133 "or{l}\t{%2, %0|%0, %2}"
10134 [(set_attr "type" "alu")
10135 (set_attr "mode" "SI")])
10137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10138 (define_insn "*iorsi_1_zext"
10139 [(set (match_operand:DI 0 "register_operand" "=r")
10141 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10142 (match_operand:SI 2 "general_operand" "g"))))
10143 (clobber (reg:CC FLAGS_REG))]
10144 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
10145 "or{l}\t{%2, %k0|%k0, %2}"
10146 [(set_attr "type" "alu")
10147 (set_attr "mode" "SI")])
10149 (define_insn "*iorsi_1_zext_imm"
10150 [(set (match_operand:DI 0 "register_operand" "=r")
10151 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10152 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10153 (clobber (reg:CC FLAGS_REG))]
10155 "or{l}\t{%2, %k0|%k0, %2}"
10156 [(set_attr "type" "alu")
10157 (set_attr "mode" "SI")])
10159 (define_insn "*iorsi_2"
10160 [(set (reg FLAGS_REG)
10161 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10162 (match_operand:SI 2 "general_operand" "g,ri"))
10164 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10165 (ior:SI (match_dup 1) (match_dup 2)))]
10166 "ix86_match_ccmode (insn, CCNOmode)
10167 && ix86_binary_operator_ok (IOR, SImode, operands)"
10168 "or{l}\t{%2, %0|%0, %2}"
10169 [(set_attr "type" "alu")
10170 (set_attr "mode" "SI")])
10172 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10173 ;; ??? Special case for immediate operand is missing - it is tricky.
10174 (define_insn "*iorsi_2_zext"
10175 [(set (reg FLAGS_REG)
10176 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10177 (match_operand:SI 2 "general_operand" "g"))
10179 (set (match_operand:DI 0 "register_operand" "=r")
10180 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10181 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10182 && ix86_binary_operator_ok (IOR, SImode, operands)"
10183 "or{l}\t{%2, %k0|%k0, %2}"
10184 [(set_attr "type" "alu")
10185 (set_attr "mode" "SI")])
10187 (define_insn "*iorsi_2_zext_imm"
10188 [(set (reg FLAGS_REG)
10189 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10190 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10192 (set (match_operand:DI 0 "register_operand" "=r")
10193 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10194 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10195 && ix86_binary_operator_ok (IOR, SImode, operands)"
10196 "or{l}\t{%2, %k0|%k0, %2}"
10197 [(set_attr "type" "alu")
10198 (set_attr "mode" "SI")])
10200 (define_insn "*iorsi_3"
10201 [(set (reg FLAGS_REG)
10202 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10203 (match_operand:SI 2 "general_operand" "g"))
10205 (clobber (match_scratch:SI 0 "=r"))]
10206 "ix86_match_ccmode (insn, CCNOmode)
10207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10208 "or{l}\t{%2, %0|%0, %2}"
10209 [(set_attr "type" "alu")
10210 (set_attr "mode" "SI")])
10212 (define_expand "iorhi3"
10213 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10214 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
10215 (match_operand:HI 2 "general_operand" "")))]
10216 "TARGET_HIMODE_MATH"
10217 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10219 (define_insn "*iorhi_1"
10220 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10221 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10222 (match_operand:HI 2 "general_operand" "rmn,rn")))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "ix86_binary_operator_ok (IOR, HImode, operands)"
10225 "or{w}\t{%2, %0|%0, %2}"
10226 [(set_attr "type" "alu")
10227 (set_attr "mode" "HI")])
10229 (define_insn "*iorhi_2"
10230 [(set (reg FLAGS_REG)
10231 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10232 (match_operand:HI 2 "general_operand" "rmn,rn"))
10234 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10235 (ior:HI (match_dup 1) (match_dup 2)))]
10236 "ix86_match_ccmode (insn, CCNOmode)
10237 && ix86_binary_operator_ok (IOR, HImode, operands)"
10238 "or{w}\t{%2, %0|%0, %2}"
10239 [(set_attr "type" "alu")
10240 (set_attr "mode" "HI")])
10242 (define_insn "*iorhi_3"
10243 [(set (reg FLAGS_REG)
10244 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10245 (match_operand:HI 2 "general_operand" "rmn"))
10247 (clobber (match_scratch:HI 0 "=r"))]
10248 "ix86_match_ccmode (insn, CCNOmode)
10249 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10250 "or{w}\t{%2, %0|%0, %2}"
10251 [(set_attr "type" "alu")
10252 (set_attr "mode" "HI")])
10254 (define_expand "iorqi3"
10255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10256 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10257 (match_operand:QI 2 "general_operand" "")))]
10258 "TARGET_QIMODE_MATH"
10259 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10261 ;; %%% Potential partial reg stall on alternative 2. What to do?
10262 (define_insn "*iorqi_1"
10263 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10264 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10265 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "ix86_binary_operator_ok (IOR, QImode, operands)"
10269 or{b}\t{%2, %0|%0, %2}
10270 or{b}\t{%2, %0|%0, %2}
10271 or{l}\t{%k2, %k0|%k0, %k2}"
10272 [(set_attr "type" "alu")
10273 (set_attr "mode" "QI,QI,SI")])
10275 (define_insn "*iorqi_1_slp"
10276 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10277 (ior:QI (match_dup 0)
10278 (match_operand:QI 1 "general_operand" "qmn,qn")))
10279 (clobber (reg:CC FLAGS_REG))]
10280 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10281 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10282 "or{b}\t{%1, %0|%0, %1}"
10283 [(set_attr "type" "alu1")
10284 (set_attr "mode" "QI")])
10286 (define_insn "*iorqi_2"
10287 [(set (reg FLAGS_REG)
10288 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10289 (match_operand:QI 2 "general_operand" "qmn,qn"))
10291 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10292 (ior:QI (match_dup 1) (match_dup 2)))]
10293 "ix86_match_ccmode (insn, CCNOmode)
10294 && ix86_binary_operator_ok (IOR, QImode, operands)"
10295 "or{b}\t{%2, %0|%0, %2}"
10296 [(set_attr "type" "alu")
10297 (set_attr "mode" "QI")])
10299 (define_insn "*iorqi_2_slp"
10300 [(set (reg FLAGS_REG)
10301 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10302 (match_operand:QI 1 "general_operand" "qmn,qn"))
10304 (set (strict_low_part (match_dup 0))
10305 (ior:QI (match_dup 0) (match_dup 1)))]
10306 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10307 && ix86_match_ccmode (insn, CCNOmode)
10308 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10309 "or{b}\t{%1, %0|%0, %1}"
10310 [(set_attr "type" "alu1")
10311 (set_attr "mode" "QI")])
10313 (define_insn "*iorqi_3"
10314 [(set (reg FLAGS_REG)
10315 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10316 (match_operand:QI 2 "general_operand" "qmn"))
10318 (clobber (match_scratch:QI 0 "=q"))]
10319 "ix86_match_ccmode (insn, CCNOmode)
10320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10321 "or{b}\t{%2, %0|%0, %2}"
10322 [(set_attr "type" "alu")
10323 (set_attr "mode" "QI")])
10325 (define_insn "*iorqi_ext_0"
10326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10331 (match_operand 1 "ext_register_operand" "0")
10334 (match_operand 2 "const_int_operand" "n")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10337 "or{b}\t{%2, %h0|%h0, %2}"
10338 [(set_attr "type" "alu")
10339 (set_attr "length_immediate" "1")
10340 (set_attr "modrm" "1")
10341 (set_attr "mode" "QI")])
10343 (define_insn "*iorqi_ext_1"
10344 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10349 (match_operand 1 "ext_register_operand" "0")
10353 (match_operand:QI 2 "general_operand" "Qm"))))
10354 (clobber (reg:CC FLAGS_REG))]
10356 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10357 "or{b}\t{%2, %h0|%h0, %2}"
10358 [(set_attr "type" "alu")
10359 (set_attr "length_immediate" "0")
10360 (set_attr "mode" "QI")])
10362 (define_insn "*iorqi_ext_1_rex64"
10363 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10368 (match_operand 1 "ext_register_operand" "0")
10372 (match_operand 2 "ext_register_operand" "Q"))))
10373 (clobber (reg:CC FLAGS_REG))]
10375 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10376 "or{b}\t{%2, %h0|%h0, %2}"
10377 [(set_attr "type" "alu")
10378 (set_attr "length_immediate" "0")
10379 (set_attr "mode" "QI")])
10381 (define_insn "*iorqi_ext_2"
10382 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10386 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10389 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10392 (clobber (reg:CC FLAGS_REG))]
10393 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10394 "ior{b}\t{%h2, %h0|%h0, %h2}"
10395 [(set_attr "type" "alu")
10396 (set_attr "length_immediate" "0")
10397 (set_attr "mode" "QI")])
10400 [(set (match_operand 0 "register_operand" "")
10401 (ior (match_operand 1 "register_operand" "")
10402 (match_operand 2 "const_int_operand" "")))
10403 (clobber (reg:CC FLAGS_REG))]
10405 && QI_REG_P (operands[0])
10406 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10407 && !(INTVAL (operands[2]) & ~(255 << 8))
10408 && GET_MODE (operands[0]) != QImode"
10409 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10410 (ior:SI (zero_extract:SI (match_dup 1)
10411 (const_int 8) (const_int 8))
10413 (clobber (reg:CC FLAGS_REG))])]
10414 "operands[0] = gen_lowpart (SImode, operands[0]);
10415 operands[1] = gen_lowpart (SImode, operands[1]);
10416 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10418 ;; Since OR can be encoded with sign extended immediate, this is only
10419 ;; profitable when 7th bit is set.
10421 [(set (match_operand 0 "register_operand" "")
10422 (ior (match_operand 1 "general_operand" "")
10423 (match_operand 2 "const_int_operand" "")))
10424 (clobber (reg:CC FLAGS_REG))]
10426 && ANY_QI_REG_P (operands[0])
10427 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10428 && !(INTVAL (operands[2]) & ~255)
10429 && (INTVAL (operands[2]) & 128)
10430 && GET_MODE (operands[0]) != QImode"
10431 [(parallel [(set (strict_low_part (match_dup 0))
10432 (ior:QI (match_dup 1)
10434 (clobber (reg:CC FLAGS_REG))])]
10435 "operands[0] = gen_lowpart (QImode, operands[0]);
10436 operands[1] = gen_lowpart (QImode, operands[1]);
10437 operands[2] = gen_lowpart (QImode, operands[2]);")
10439 ;; Logical XOR instructions
10441 ;; %%% This used to optimize known byte-wide and operations to memory.
10442 ;; If this is considered useful, it should be done with splitters.
10444 (define_expand "xordi3"
10445 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10446 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10447 (match_operand:DI 2 "x86_64_general_operand" "")))]
10449 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10451 (define_insn "*xordi_1_rex64"
10452 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10453 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10454 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10455 (clobber (reg:CC FLAGS_REG))]
10457 && ix86_binary_operator_ok (XOR, DImode, operands)"
10458 "xor{q}\t{%2, %0|%0, %2}"
10459 [(set_attr "type" "alu")
10460 (set_attr "mode" "DI")])
10462 (define_insn "*xordi_2_rex64"
10463 [(set (reg FLAGS_REG)
10464 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10465 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10467 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10468 (xor:DI (match_dup 1) (match_dup 2)))]
10470 && ix86_match_ccmode (insn, CCNOmode)
10471 && ix86_binary_operator_ok (XOR, DImode, operands)"
10472 "xor{q}\t{%2, %0|%0, %2}"
10473 [(set_attr "type" "alu")
10474 (set_attr "mode" "DI")])
10476 (define_insn "*xordi_3_rex64"
10477 [(set (reg FLAGS_REG)
10478 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10479 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10481 (clobber (match_scratch:DI 0 "=r"))]
10483 && ix86_match_ccmode (insn, CCNOmode)
10484 && ix86_binary_operator_ok (XOR, DImode, operands)"
10485 "xor{q}\t{%2, %0|%0, %2}"
10486 [(set_attr "type" "alu")
10487 (set_attr "mode" "DI")])
10489 (define_expand "xorsi3"
10490 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10491 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10492 (match_operand:SI 2 "general_operand" "")))]
10494 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10496 (define_insn "*xorsi_1"
10497 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10498 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10499 (match_operand:SI 2 "general_operand" "ri,rm")))
10500 (clobber (reg:CC FLAGS_REG))]
10501 "ix86_binary_operator_ok (XOR, SImode, operands)"
10502 "xor{l}\t{%2, %0|%0, %2}"
10503 [(set_attr "type" "alu")
10504 (set_attr "mode" "SI")])
10506 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10507 ;; Add speccase for immediates
10508 (define_insn "*xorsi_1_zext"
10509 [(set (match_operand:DI 0 "register_operand" "=r")
10511 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10512 (match_operand:SI 2 "general_operand" "g"))))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10515 "xor{l}\t{%2, %k0|%k0, %2}"
10516 [(set_attr "type" "alu")
10517 (set_attr "mode" "SI")])
10519 (define_insn "*xorsi_1_zext_imm"
10520 [(set (match_operand:DI 0 "register_operand" "=r")
10521 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10522 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10523 (clobber (reg:CC FLAGS_REG))]
10524 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10525 "xor{l}\t{%2, %k0|%k0, %2}"
10526 [(set_attr "type" "alu")
10527 (set_attr "mode" "SI")])
10529 (define_insn "*xorsi_2"
10530 [(set (reg FLAGS_REG)
10531 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10532 (match_operand:SI 2 "general_operand" "g,ri"))
10534 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10535 (xor:SI (match_dup 1) (match_dup 2)))]
10536 "ix86_match_ccmode (insn, CCNOmode)
10537 && ix86_binary_operator_ok (XOR, SImode, operands)"
10538 "xor{l}\t{%2, %0|%0, %2}"
10539 [(set_attr "type" "alu")
10540 (set_attr "mode" "SI")])
10542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10543 ;; ??? Special case for immediate operand is missing - it is tricky.
10544 (define_insn "*xorsi_2_zext"
10545 [(set (reg FLAGS_REG)
10546 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10547 (match_operand:SI 2 "general_operand" "g"))
10549 (set (match_operand:DI 0 "register_operand" "=r")
10550 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10551 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10552 && ix86_binary_operator_ok (XOR, SImode, operands)"
10553 "xor{l}\t{%2, %k0|%k0, %2}"
10554 [(set_attr "type" "alu")
10555 (set_attr "mode" "SI")])
10557 (define_insn "*xorsi_2_zext_imm"
10558 [(set (reg FLAGS_REG)
10559 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10560 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10562 (set (match_operand:DI 0 "register_operand" "=r")
10563 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10564 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10565 && ix86_binary_operator_ok (XOR, SImode, operands)"
10566 "xor{l}\t{%2, %k0|%k0, %2}"
10567 [(set_attr "type" "alu")
10568 (set_attr "mode" "SI")])
10570 (define_insn "*xorsi_3"
10571 [(set (reg FLAGS_REG)
10572 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10573 (match_operand:SI 2 "general_operand" "g"))
10575 (clobber (match_scratch:SI 0 "=r"))]
10576 "ix86_match_ccmode (insn, CCNOmode)
10577 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10578 "xor{l}\t{%2, %0|%0, %2}"
10579 [(set_attr "type" "alu")
10580 (set_attr "mode" "SI")])
10582 (define_expand "xorhi3"
10583 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10584 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10585 (match_operand:HI 2 "general_operand" "")))]
10586 "TARGET_HIMODE_MATH"
10587 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10589 (define_insn "*xorhi_1"
10590 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10591 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10592 (match_operand:HI 2 "general_operand" "rmn,rn")))
10593 (clobber (reg:CC FLAGS_REG))]
10594 "ix86_binary_operator_ok (XOR, HImode, operands)"
10595 "xor{w}\t{%2, %0|%0, %2}"
10596 [(set_attr "type" "alu")
10597 (set_attr "mode" "HI")])
10599 (define_insn "*xorhi_2"
10600 [(set (reg FLAGS_REG)
10601 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10602 (match_operand:HI 2 "general_operand" "rmn,rn"))
10604 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10605 (xor:HI (match_dup 1) (match_dup 2)))]
10606 "ix86_match_ccmode (insn, CCNOmode)
10607 && ix86_binary_operator_ok (XOR, HImode, operands)"
10608 "xor{w}\t{%2, %0|%0, %2}"
10609 [(set_attr "type" "alu")
10610 (set_attr "mode" "HI")])
10612 (define_insn "*xorhi_3"
10613 [(set (reg FLAGS_REG)
10614 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10615 (match_operand:HI 2 "general_operand" "rmn"))
10617 (clobber (match_scratch:HI 0 "=r"))]
10618 "ix86_match_ccmode (insn, CCNOmode)
10619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10620 "xor{w}\t{%2, %0|%0, %2}"
10621 [(set_attr "type" "alu")
10622 (set_attr "mode" "HI")])
10624 (define_expand "xorqi3"
10625 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10626 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10627 (match_operand:QI 2 "general_operand" "")))]
10628 "TARGET_QIMODE_MATH"
10629 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10631 ;; %%% Potential partial reg stall on alternative 2. What to do?
10632 (define_insn "*xorqi_1"
10633 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10634 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10635 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "ix86_binary_operator_ok (XOR, QImode, operands)"
10639 xor{b}\t{%2, %0|%0, %2}
10640 xor{b}\t{%2, %0|%0, %2}
10641 xor{l}\t{%k2, %k0|%k0, %k2}"
10642 [(set_attr "type" "alu")
10643 (set_attr "mode" "QI,QI,SI")])
10645 (define_insn "*xorqi_1_slp"
10646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10647 (xor:QI (match_dup 0)
10648 (match_operand:QI 1 "general_operand" "qn,qmn")))
10649 (clobber (reg:CC FLAGS_REG))]
10650 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10651 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10652 "xor{b}\t{%1, %0|%0, %1}"
10653 [(set_attr "type" "alu1")
10654 (set_attr "mode" "QI")])
10656 (define_insn "*xorqi_ext_0"
10657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10662 (match_operand 1 "ext_register_operand" "0")
10665 (match_operand 2 "const_int_operand" "n")))
10666 (clobber (reg:CC FLAGS_REG))]
10667 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10668 "xor{b}\t{%2, %h0|%h0, %2}"
10669 [(set_attr "type" "alu")
10670 (set_attr "length_immediate" "1")
10671 (set_attr "modrm" "1")
10672 (set_attr "mode" "QI")])
10674 (define_insn "*xorqi_ext_1"
10675 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10680 (match_operand 1 "ext_register_operand" "0")
10684 (match_operand:QI 2 "general_operand" "Qm"))))
10685 (clobber (reg:CC FLAGS_REG))]
10687 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10688 "xor{b}\t{%2, %h0|%h0, %2}"
10689 [(set_attr "type" "alu")
10690 (set_attr "length_immediate" "0")
10691 (set_attr "mode" "QI")])
10693 (define_insn "*xorqi_ext_1_rex64"
10694 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10699 (match_operand 1 "ext_register_operand" "0")
10703 (match_operand 2 "ext_register_operand" "Q"))))
10704 (clobber (reg:CC FLAGS_REG))]
10706 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10707 "xor{b}\t{%2, %h0|%h0, %2}"
10708 [(set_attr "type" "alu")
10709 (set_attr "length_immediate" "0")
10710 (set_attr "mode" "QI")])
10712 (define_insn "*xorqi_ext_2"
10713 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10717 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10720 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10723 (clobber (reg:CC FLAGS_REG))]
10724 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10725 "xor{b}\t{%h2, %h0|%h0, %h2}"
10726 [(set_attr "type" "alu")
10727 (set_attr "length_immediate" "0")
10728 (set_attr "mode" "QI")])
10730 (define_insn "*xorqi_cc_1"
10731 [(set (reg FLAGS_REG)
10733 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10734 (match_operand:QI 2 "general_operand" "qmn,qn"))
10736 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10737 (xor:QI (match_dup 1) (match_dup 2)))]
10738 "ix86_match_ccmode (insn, CCNOmode)
10739 && ix86_binary_operator_ok (XOR, QImode, operands)"
10740 "xor{b}\t{%2, %0|%0, %2}"
10741 [(set_attr "type" "alu")
10742 (set_attr "mode" "QI")])
10744 (define_insn "*xorqi_2_slp"
10745 [(set (reg FLAGS_REG)
10746 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10747 (match_operand:QI 1 "general_operand" "qmn,qn"))
10749 (set (strict_low_part (match_dup 0))
10750 (xor:QI (match_dup 0) (match_dup 1)))]
10751 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10752 && ix86_match_ccmode (insn, CCNOmode)
10753 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10754 "xor{b}\t{%1, %0|%0, %1}"
10755 [(set_attr "type" "alu1")
10756 (set_attr "mode" "QI")])
10758 (define_insn "*xorqi_cc_2"
10759 [(set (reg FLAGS_REG)
10761 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10762 (match_operand:QI 2 "general_operand" "qmn"))
10764 (clobber (match_scratch:QI 0 "=q"))]
10765 "ix86_match_ccmode (insn, CCNOmode)
10766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10767 "xor{b}\t{%2, %0|%0, %2}"
10768 [(set_attr "type" "alu")
10769 (set_attr "mode" "QI")])
10771 (define_insn "*xorqi_cc_ext_1"
10772 [(set (reg FLAGS_REG)
10776 (match_operand 1 "ext_register_operand" "0")
10779 (match_operand:QI 2 "general_operand" "qmn"))
10781 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10785 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10787 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10788 "xor{b}\t{%2, %h0|%h0, %2}"
10789 [(set_attr "type" "alu")
10790 (set_attr "modrm" "1")
10791 (set_attr "mode" "QI")])
10793 (define_insn "*xorqi_cc_ext_1_rex64"
10794 [(set (reg FLAGS_REG)
10798 (match_operand 1 "ext_register_operand" "0")
10801 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10803 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10807 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10809 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10810 "xor{b}\t{%2, %h0|%h0, %2}"
10811 [(set_attr "type" "alu")
10812 (set_attr "modrm" "1")
10813 (set_attr "mode" "QI")])
10815 (define_expand "xorqi_cc_ext_1"
10817 (set (reg:CCNO FLAGS_REG)
10821 (match_operand 1 "ext_register_operand" "")
10824 (match_operand:QI 2 "general_operand" ""))
10826 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10830 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10836 [(set (match_operand 0 "register_operand" "")
10837 (xor (match_operand 1 "register_operand" "")
10838 (match_operand 2 "const_int_operand" "")))
10839 (clobber (reg:CC FLAGS_REG))]
10841 && QI_REG_P (operands[0])
10842 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10843 && !(INTVAL (operands[2]) & ~(255 << 8))
10844 && GET_MODE (operands[0]) != QImode"
10845 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10846 (xor:SI (zero_extract:SI (match_dup 1)
10847 (const_int 8) (const_int 8))
10849 (clobber (reg:CC FLAGS_REG))])]
10850 "operands[0] = gen_lowpart (SImode, operands[0]);
10851 operands[1] = gen_lowpart (SImode, operands[1]);
10852 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10854 ;; Since XOR can be encoded with sign extended immediate, this is only
10855 ;; profitable when 7th bit is set.
10857 [(set (match_operand 0 "register_operand" "")
10858 (xor (match_operand 1 "general_operand" "")
10859 (match_operand 2 "const_int_operand" "")))
10860 (clobber (reg:CC FLAGS_REG))]
10862 && ANY_QI_REG_P (operands[0])
10863 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10864 && !(INTVAL (operands[2]) & ~255)
10865 && (INTVAL (operands[2]) & 128)
10866 && GET_MODE (operands[0]) != QImode"
10867 [(parallel [(set (strict_low_part (match_dup 0))
10868 (xor:QI (match_dup 1)
10870 (clobber (reg:CC FLAGS_REG))])]
10871 "operands[0] = gen_lowpart (QImode, operands[0]);
10872 operands[1] = gen_lowpart (QImode, operands[1]);
10873 operands[2] = gen_lowpart (QImode, operands[2]);")
10875 ;; Negation instructions
10877 (define_expand "negti2"
10878 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10879 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10881 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10883 (define_insn "*negti2_1"
10884 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10885 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10886 (clobber (reg:CC FLAGS_REG))]
10888 && ix86_unary_operator_ok (NEG, TImode, operands)"
10892 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10893 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10894 (clobber (reg:CC FLAGS_REG))]
10895 "TARGET_64BIT && reload_completed"
10897 [(set (reg:CCZ FLAGS_REG)
10898 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10899 (set (match_dup 0) (neg:DI (match_dup 1)))])
10901 [(set (match_dup 2)
10902 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10905 (clobber (reg:CC FLAGS_REG))])
10907 [(set (match_dup 2)
10908 (neg:DI (match_dup 2)))
10909 (clobber (reg:CC FLAGS_REG))])]
10910 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10912 (define_expand "negdi2"
10913 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10914 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10916 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10918 (define_insn "*negdi2_1"
10919 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10920 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10921 (clobber (reg:CC FLAGS_REG))]
10923 && ix86_unary_operator_ok (NEG, DImode, operands)"
10927 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10928 (neg:DI (match_operand:DI 1 "general_operand" "")))
10929 (clobber (reg:CC FLAGS_REG))]
10930 "!TARGET_64BIT && reload_completed"
10932 [(set (reg:CCZ FLAGS_REG)
10933 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10934 (set (match_dup 0) (neg:SI (match_dup 1)))])
10936 [(set (match_dup 2)
10937 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10940 (clobber (reg:CC FLAGS_REG))])
10942 [(set (match_dup 2)
10943 (neg:SI (match_dup 2)))
10944 (clobber (reg:CC FLAGS_REG))])]
10945 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10947 (define_insn "*negdi2_1_rex64"
10948 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10949 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10953 [(set_attr "type" "negnot")
10954 (set_attr "mode" "DI")])
10956 ;; The problem with neg is that it does not perform (compare x 0),
10957 ;; it really performs (compare 0 x), which leaves us with the zero
10958 ;; flag being the only useful item.
10960 (define_insn "*negdi2_cmpz_rex64"
10961 [(set (reg:CCZ FLAGS_REG)
10962 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10964 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10965 (neg:DI (match_dup 1)))]
10966 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10968 [(set_attr "type" "negnot")
10969 (set_attr "mode" "DI")])
10972 (define_expand "negsi2"
10973 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10976 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10978 (define_insn "*negsi2_1"
10979 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10980 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10981 (clobber (reg:CC FLAGS_REG))]
10982 "ix86_unary_operator_ok (NEG, SImode, operands)"
10984 [(set_attr "type" "negnot")
10985 (set_attr "mode" "SI")])
10987 ;; Combine is quite creative about this pattern.
10988 (define_insn "*negsi2_1_zext"
10989 [(set (match_operand:DI 0 "register_operand" "=r")
10990 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10993 (clobber (reg:CC FLAGS_REG))]
10994 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10996 [(set_attr "type" "negnot")
10997 (set_attr "mode" "SI")])
10999 ;; The problem with neg is that it does not perform (compare x 0),
11000 ;; it really performs (compare 0 x), which leaves us with the zero
11001 ;; flag being the only useful item.
11003 (define_insn "*negsi2_cmpz"
11004 [(set (reg:CCZ FLAGS_REG)
11005 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11007 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11008 (neg:SI (match_dup 1)))]
11009 "ix86_unary_operator_ok (NEG, SImode, operands)"
11011 [(set_attr "type" "negnot")
11012 (set_attr "mode" "SI")])
11014 (define_insn "*negsi2_cmpz_zext"
11015 [(set (reg:CCZ FLAGS_REG)
11016 (compare:CCZ (lshiftrt:DI
11018 (match_operand:DI 1 "register_operand" "0")
11022 (set (match_operand:DI 0 "register_operand" "=r")
11023 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11026 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
11028 [(set_attr "type" "negnot")
11029 (set_attr "mode" "SI")])
11031 (define_expand "neghi2"
11032 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11033 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11034 "TARGET_HIMODE_MATH"
11035 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11037 (define_insn "*neghi2_1"
11038 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11039 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
11040 (clobber (reg:CC FLAGS_REG))]
11041 "ix86_unary_operator_ok (NEG, HImode, operands)"
11043 [(set_attr "type" "negnot")
11044 (set_attr "mode" "HI")])
11046 (define_insn "*neghi2_cmpz"
11047 [(set (reg:CCZ FLAGS_REG)
11048 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11050 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11051 (neg:HI (match_dup 1)))]
11052 "ix86_unary_operator_ok (NEG, HImode, operands)"
11054 [(set_attr "type" "negnot")
11055 (set_attr "mode" "HI")])
11057 (define_expand "negqi2"
11058 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11059 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11060 "TARGET_QIMODE_MATH"
11061 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11063 (define_insn "*negqi2_1"
11064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11065 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "ix86_unary_operator_ok (NEG, QImode, operands)"
11069 [(set_attr "type" "negnot")
11070 (set_attr "mode" "QI")])
11072 (define_insn "*negqi2_cmpz"
11073 [(set (reg:CCZ FLAGS_REG)
11074 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11076 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11077 (neg:QI (match_dup 1)))]
11078 "ix86_unary_operator_ok (NEG, QImode, operands)"
11080 [(set_attr "type" "negnot")
11081 (set_attr "mode" "QI")])
11083 ;; Changing of sign for FP values is doable using integer unit too.
11085 (define_expand "<code><mode>2"
11086 [(set (match_operand:X87MODEF 0 "register_operand" "")
11087 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
11088 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11089 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
11091 (define_insn "*absneg<mode>2_mixed"
11092 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11093 (match_operator:MODEF 3 "absneg_operator"
11094 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11095 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
11100 (define_insn "*absneg<mode>2_sse"
11101 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11102 (match_operator:MODEF 3 "absneg_operator"
11103 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11104 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
11109 (define_insn "*absneg<mode>2_i387"
11110 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11111 (match_operator:X87MODEF 3 "absneg_operator"
11112 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
11113 (use (match_operand 2 "" ""))
11114 (clobber (reg:CC FLAGS_REG))]
11115 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11118 (define_expand "<code>tf2"
11119 [(set (match_operand:TF 0 "register_operand" "")
11120 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
11122 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
11124 (define_insn "*absnegtf2_sse"
11125 [(set (match_operand:TF 0 "register_operand" "=x,x")
11126 (match_operator:TF 3 "absneg_operator"
11127 [(match_operand:TF 1 "register_operand" "0,x")]))
11128 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
11129 (clobber (reg:CC FLAGS_REG))]
11133 ;; Splitters for fp abs and neg.
11136 [(set (match_operand 0 "fp_register_operand" "")
11137 (match_operator 1 "absneg_operator" [(match_dup 0)]))
11138 (use (match_operand 2 "" ""))
11139 (clobber (reg:CC FLAGS_REG))]
11141 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
11144 [(set (match_operand 0 "register_operand" "")
11145 (match_operator 3 "absneg_operator"
11146 [(match_operand 1 "register_operand" "")]))
11147 (use (match_operand 2 "nonimmediate_operand" ""))
11148 (clobber (reg:CC FLAGS_REG))]
11149 "reload_completed && SSE_REG_P (operands[0])"
11150 [(set (match_dup 0) (match_dup 3))]
11152 enum machine_mode mode = GET_MODE (operands[0]);
11153 enum machine_mode vmode = GET_MODE (operands[2]);
11156 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11157 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
11158 if (operands_match_p (operands[0], operands[2]))
11161 operands[1] = operands[2];
11164 if (GET_CODE (operands[3]) == ABS)
11165 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11167 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11172 [(set (match_operand:SF 0 "register_operand" "")
11173 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11174 (use (match_operand:V4SF 2 "" ""))
11175 (clobber (reg:CC FLAGS_REG))]
11177 [(parallel [(set (match_dup 0) (match_dup 1))
11178 (clobber (reg:CC FLAGS_REG))])]
11181 operands[0] = gen_lowpart (SImode, operands[0]);
11182 if (GET_CODE (operands[1]) == ABS)
11184 tmp = gen_int_mode (0x7fffffff, SImode);
11185 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11189 tmp = gen_int_mode (0x80000000, SImode);
11190 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11196 [(set (match_operand:DF 0 "register_operand" "")
11197 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11198 (use (match_operand 2 "" ""))
11199 (clobber (reg:CC FLAGS_REG))]
11201 [(parallel [(set (match_dup 0) (match_dup 1))
11202 (clobber (reg:CC FLAGS_REG))])]
11207 tmp = gen_lowpart (DImode, operands[0]);
11208 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11211 if (GET_CODE (operands[1]) == ABS)
11214 tmp = gen_rtx_NOT (DImode, tmp);
11218 operands[0] = gen_highpart (SImode, operands[0]);
11219 if (GET_CODE (operands[1]) == ABS)
11221 tmp = gen_int_mode (0x7fffffff, SImode);
11222 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11226 tmp = gen_int_mode (0x80000000, SImode);
11227 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11234 [(set (match_operand:XF 0 "register_operand" "")
11235 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11236 (use (match_operand 2 "" ""))
11237 (clobber (reg:CC FLAGS_REG))]
11239 [(parallel [(set (match_dup 0) (match_dup 1))
11240 (clobber (reg:CC FLAGS_REG))])]
11243 operands[0] = gen_rtx_REG (SImode,
11244 true_regnum (operands[0])
11245 + (TARGET_64BIT ? 1 : 2));
11246 if (GET_CODE (operands[1]) == ABS)
11248 tmp = GEN_INT (0x7fff);
11249 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11253 tmp = GEN_INT (0x8000);
11254 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11259 ;; Conditionalize these after reload. If they match before reload, we
11260 ;; lose the clobber and ability to use integer instructions.
11262 (define_insn "*<code><mode>2_1"
11263 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11264 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11266 && (reload_completed
11267 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11269 [(set_attr "type" "fsgn")
11270 (set_attr "mode" "<MODE>")])
11272 (define_insn "*<code>extendsfdf2"
11273 [(set (match_operand:DF 0 "register_operand" "=f")
11274 (absneg:DF (float_extend:DF
11275 (match_operand:SF 1 "register_operand" "0"))))]
11276 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11278 [(set_attr "type" "fsgn")
11279 (set_attr "mode" "DF")])
11281 (define_insn "*<code>extendsfxf2"
11282 [(set (match_operand:XF 0 "register_operand" "=f")
11283 (absneg:XF (float_extend:XF
11284 (match_operand:SF 1 "register_operand" "0"))))]
11287 [(set_attr "type" "fsgn")
11288 (set_attr "mode" "XF")])
11290 (define_insn "*<code>extenddfxf2"
11291 [(set (match_operand:XF 0 "register_operand" "=f")
11292 (absneg:XF (float_extend:XF
11293 (match_operand:DF 1 "register_operand" "0"))))]
11296 [(set_attr "type" "fsgn")
11297 (set_attr "mode" "XF")])
11299 ;; Copysign instructions
11301 (define_mode_iterator CSGNMODE [SF DF TF])
11302 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11304 (define_expand "copysign<mode>3"
11305 [(match_operand:CSGNMODE 0 "register_operand" "")
11306 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11307 (match_operand:CSGNMODE 2 "register_operand" "")]
11308 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11309 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11311 ix86_expand_copysign (operands);
11315 (define_insn_and_split "copysign<mode>3_const"
11316 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11318 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11319 (match_operand:CSGNMODE 2 "register_operand" "0")
11320 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11322 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11323 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11325 "&& reload_completed"
11328 ix86_split_copysign_const (operands);
11332 (define_insn "copysign<mode>3_var"
11333 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11335 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11336 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11337 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11338 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11340 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11341 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11342 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11346 [(set (match_operand:CSGNMODE 0 "register_operand" "")
11348 [(match_operand:CSGNMODE 2 "register_operand" "")
11349 (match_operand:CSGNMODE 3 "register_operand" "")
11350 (match_operand:<CSGNVMODE> 4 "" "")
11351 (match_operand:<CSGNVMODE> 5 "" "")]
11353 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11354 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11355 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11356 && reload_completed"
11359 ix86_split_copysign_var (operands);
11363 ;; One complement instructions
11365 (define_expand "one_cmpldi2"
11366 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11367 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11369 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11371 (define_insn "*one_cmpldi2_1_rex64"
11372 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11373 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11374 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11376 [(set_attr "type" "negnot")
11377 (set_attr "mode" "DI")])
11379 (define_insn "*one_cmpldi2_2_rex64"
11380 [(set (reg FLAGS_REG)
11381 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11383 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384 (not:DI (match_dup 1)))]
11385 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11386 && ix86_unary_operator_ok (NOT, DImode, operands)"
11388 [(set_attr "type" "alu1")
11389 (set_attr "mode" "DI")])
11392 [(set (match_operand 0 "flags_reg_operand" "")
11393 (match_operator 2 "compare_operator"
11394 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11396 (set (match_operand:DI 1 "nonimmediate_operand" "")
11397 (not:DI (match_dup 3)))]
11398 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11399 [(parallel [(set (match_dup 0)
11401 [(xor:DI (match_dup 3) (const_int -1))
11404 (xor:DI (match_dup 3) (const_int -1)))])]
11407 (define_expand "one_cmplsi2"
11408 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11409 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11411 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11413 (define_insn "*one_cmplsi2_1"
11414 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11415 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11416 "ix86_unary_operator_ok (NOT, SImode, operands)"
11418 [(set_attr "type" "negnot")
11419 (set_attr "mode" "SI")])
11421 ;; ??? Currently never generated - xor is used instead.
11422 (define_insn "*one_cmplsi2_1_zext"
11423 [(set (match_operand:DI 0 "register_operand" "=r")
11424 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11425 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11427 [(set_attr "type" "negnot")
11428 (set_attr "mode" "SI")])
11430 (define_insn "*one_cmplsi2_2"
11431 [(set (reg FLAGS_REG)
11432 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11434 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11435 (not:SI (match_dup 1)))]
11436 "ix86_match_ccmode (insn, CCNOmode)
11437 && ix86_unary_operator_ok (NOT, SImode, operands)"
11439 [(set_attr "type" "alu1")
11440 (set_attr "mode" "SI")])
11443 [(set (match_operand 0 "flags_reg_operand" "")
11444 (match_operator 2 "compare_operator"
11445 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11447 (set (match_operand:SI 1 "nonimmediate_operand" "")
11448 (not:SI (match_dup 3)))]
11449 "ix86_match_ccmode (insn, CCNOmode)"
11450 [(parallel [(set (match_dup 0)
11451 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11454 (xor:SI (match_dup 3) (const_int -1)))])]
11457 ;; ??? Currently never generated - xor is used instead.
11458 (define_insn "*one_cmplsi2_2_zext"
11459 [(set (reg FLAGS_REG)
11460 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11462 (set (match_operand:DI 0 "register_operand" "=r")
11463 (zero_extend:DI (not:SI (match_dup 1))))]
11464 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11465 && ix86_unary_operator_ok (NOT, SImode, operands)"
11467 [(set_attr "type" "alu1")
11468 (set_attr "mode" "SI")])
11471 [(set (match_operand 0 "flags_reg_operand" "")
11472 (match_operator 2 "compare_operator"
11473 [(not:SI (match_operand:SI 3 "register_operand" ""))
11475 (set (match_operand:DI 1 "register_operand" "")
11476 (zero_extend:DI (not:SI (match_dup 3))))]
11477 "ix86_match_ccmode (insn, CCNOmode)"
11478 [(parallel [(set (match_dup 0)
11479 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11482 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11485 (define_expand "one_cmplhi2"
11486 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11487 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11488 "TARGET_HIMODE_MATH"
11489 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11491 (define_insn "*one_cmplhi2_1"
11492 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11493 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11494 "ix86_unary_operator_ok (NOT, HImode, operands)"
11496 [(set_attr "type" "negnot")
11497 (set_attr "mode" "HI")])
11499 (define_insn "*one_cmplhi2_2"
11500 [(set (reg FLAGS_REG)
11501 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11503 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504 (not:HI (match_dup 1)))]
11505 "ix86_match_ccmode (insn, CCNOmode)
11506 && ix86_unary_operator_ok (NEG, HImode, operands)"
11508 [(set_attr "type" "alu1")
11509 (set_attr "mode" "HI")])
11512 [(set (match_operand 0 "flags_reg_operand" "")
11513 (match_operator 2 "compare_operator"
11514 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11516 (set (match_operand:HI 1 "nonimmediate_operand" "")
11517 (not:HI (match_dup 3)))]
11518 "ix86_match_ccmode (insn, CCNOmode)"
11519 [(parallel [(set (match_dup 0)
11520 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11523 (xor:HI (match_dup 3) (const_int -1)))])]
11526 ;; %%% Potential partial reg stall on alternative 1. What to do?
11527 (define_expand "one_cmplqi2"
11528 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11529 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11530 "TARGET_QIMODE_MATH"
11531 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11533 (define_insn "*one_cmplqi2_1"
11534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11535 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11536 "ix86_unary_operator_ok (NOT, QImode, operands)"
11540 [(set_attr "type" "negnot")
11541 (set_attr "mode" "QI,SI")])
11543 (define_insn "*one_cmplqi2_2"
11544 [(set (reg FLAGS_REG)
11545 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11547 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11548 (not:QI (match_dup 1)))]
11549 "ix86_match_ccmode (insn, CCNOmode)
11550 && ix86_unary_operator_ok (NOT, QImode, operands)"
11552 [(set_attr "type" "alu1")
11553 (set_attr "mode" "QI")])
11556 [(set (match_operand 0 "flags_reg_operand" "")
11557 (match_operator 2 "compare_operator"
11558 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11560 (set (match_operand:QI 1 "nonimmediate_operand" "")
11561 (not:QI (match_dup 3)))]
11562 "ix86_match_ccmode (insn, CCNOmode)"
11563 [(parallel [(set (match_dup 0)
11564 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11567 (xor:QI (match_dup 3) (const_int -1)))])]
11570 ;; Arithmetic shift instructions
11572 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11573 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11574 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11575 ;; from the assembler input.
11577 ;; This instruction shifts the target reg/mem as usual, but instead of
11578 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11579 ;; is a left shift double, bits are taken from the high order bits of
11580 ;; reg, else if the insn is a shift right double, bits are taken from the
11581 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11582 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11584 ;; Since sh[lr]d does not change the `reg' operand, that is done
11585 ;; separately, making all shifts emit pairs of shift double and normal
11586 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11587 ;; support a 63 bit shift, each shift where the count is in a reg expands
11588 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11590 ;; If the shift count is a constant, we need never emit more than one
11591 ;; shift pair, instead using moves and sign extension for counts greater
11594 (define_expand "ashlti3"
11595 [(set (match_operand:TI 0 "register_operand" "")
11596 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11597 (match_operand:QI 2 "nonmemory_operand" "")))]
11599 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11601 ;; This pattern must be defined before *ashlti3_1 to prevent
11602 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11604 (define_insn "*avx_ashlti3"
11605 [(set (match_operand:TI 0 "register_operand" "=x")
11606 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11607 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11610 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11611 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11613 [(set_attr "type" "sseishft")
11614 (set_attr "prefix" "vex")
11615 (set_attr "length_immediate" "1")
11616 (set_attr "mode" "TI")])
11618 (define_insn "sse2_ashlti3"
11619 [(set (match_operand:TI 0 "register_operand" "=x")
11620 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11621 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11624 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11625 return "pslldq\t{%2, %0|%0, %2}";
11627 [(set_attr "type" "sseishft")
11628 (set_attr "prefix_data16" "1")
11629 (set_attr "length_immediate" "1")
11630 (set_attr "mode" "TI")])
11632 (define_insn "*ashlti3_1"
11633 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11634 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11635 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11636 (clobber (reg:CC FLAGS_REG))]
11639 [(set_attr "type" "multi")])
11642 [(match_scratch:DI 3 "r")
11643 (parallel [(set (match_operand:TI 0 "register_operand" "")
11644 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11645 (match_operand:QI 2 "nonmemory_operand" "")))
11646 (clobber (reg:CC FLAGS_REG))])
11650 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11653 [(set (match_operand:TI 0 "register_operand" "")
11654 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11655 (match_operand:QI 2 "nonmemory_operand" "")))
11656 (clobber (reg:CC FLAGS_REG))]
11657 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11658 ? epilogue_completed : reload_completed)"
11660 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11662 (define_insn "x86_64_shld"
11663 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11664 (ior:DI (ashift:DI (match_dup 0)
11665 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11666 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11667 (minus:QI (const_int 64) (match_dup 2)))))
11668 (clobber (reg:CC FLAGS_REG))]
11670 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11671 [(set_attr "type" "ishift")
11672 (set_attr "prefix_0f" "1")
11673 (set_attr "mode" "DI")
11674 (set_attr "athlon_decode" "vector")
11675 (set_attr "amdfam10_decode" "vector")])
11677 (define_expand "x86_64_shift_adj_1"
11678 [(set (reg:CCZ FLAGS_REG)
11679 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11682 (set (match_operand:DI 0 "register_operand" "")
11683 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11684 (match_operand:DI 1 "register_operand" "")
11687 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11688 (match_operand:DI 3 "register_operand" "r")
11693 (define_expand "x86_64_shift_adj_2"
11694 [(use (match_operand:DI 0 "register_operand" ""))
11695 (use (match_operand:DI 1 "register_operand" ""))
11696 (use (match_operand:QI 2 "register_operand" ""))]
11699 rtx label = gen_label_rtx ();
11702 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11704 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11705 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11706 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11707 gen_rtx_LABEL_REF (VOIDmode, label),
11709 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11710 JUMP_LABEL (tmp) = label;
11712 emit_move_insn (operands[0], operands[1]);
11713 ix86_expand_clear (operands[1]);
11715 emit_label (label);
11716 LABEL_NUSES (label) = 1;
11721 (define_expand "ashldi3"
11722 [(set (match_operand:DI 0 "shiftdi_operand" "")
11723 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11724 (match_operand:QI 2 "nonmemory_operand" "")))]
11726 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11728 (define_insn "*ashldi3_1_rex64"
11729 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11730 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11731 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11732 (clobber (reg:CC FLAGS_REG))]
11733 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11735 switch (get_attr_type (insn))
11738 gcc_assert (operands[2] == const1_rtx);
11739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11740 return "add{q}\t%0, %0";
11743 gcc_assert (CONST_INT_P (operands[2]));
11744 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11745 operands[1] = gen_rtx_MULT (DImode, operands[1],
11746 GEN_INT (1 << INTVAL (operands[2])));
11747 return "lea{q}\t{%a1, %0|%0, %a1}";
11750 if (REG_P (operands[2]))
11751 return "sal{q}\t{%b2, %0|%0, %b2}";
11752 else if (operands[2] == const1_rtx
11753 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11754 return "sal{q}\t%0";
11756 return "sal{q}\t{%2, %0|%0, %2}";
11759 [(set (attr "type")
11760 (cond [(eq_attr "alternative" "1")
11761 (const_string "lea")
11762 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11764 (match_operand 0 "register_operand" ""))
11765 (match_operand 2 "const1_operand" ""))
11766 (const_string "alu")
11768 (const_string "ishift")))
11769 (set (attr "length_immediate")
11771 (ior (eq_attr "type" "alu")
11772 (and (eq_attr "type" "ishift")
11773 (and (match_operand 2 "const1_operand" "")
11774 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11777 (const_string "*")))
11778 (set_attr "mode" "DI")])
11780 ;; Convert lea to the lea pattern to avoid flags dependency.
11782 [(set (match_operand:DI 0 "register_operand" "")
11783 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11784 (match_operand:QI 2 "immediate_operand" "")))
11785 (clobber (reg:CC FLAGS_REG))]
11786 "TARGET_64BIT && reload_completed
11787 && true_regnum (operands[0]) != true_regnum (operands[1])"
11788 [(set (match_dup 0)
11789 (mult:DI (match_dup 1)
11791 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags. We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashldi3_cmp_rex64"
11797 [(set (reg FLAGS_REG)
11799 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11802 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11803 (ashift:DI (match_dup 1) (match_dup 2)))]
11805 && (optimize_function_for_size_p (cfun)
11806 || !TARGET_PARTIAL_FLAG_REG_STALL
11807 || (operands[2] == const1_rtx
11809 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11810 && ix86_match_ccmode (insn, CCGOCmode)
11811 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11813 switch (get_attr_type (insn))
11816 gcc_assert (operands[2] == const1_rtx);
11817 return "add{q}\t%0, %0";
11820 if (REG_P (operands[2]))
11821 return "sal{q}\t{%b2, %0|%0, %b2}";
11822 else if (operands[2] == const1_rtx
11823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11824 return "sal{q}\t%0";
11826 return "sal{q}\t{%2, %0|%0, %2}";
11829 [(set (attr "type")
11830 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11832 (match_operand 0 "register_operand" ""))
11833 (match_operand 2 "const1_operand" ""))
11834 (const_string "alu")
11836 (const_string "ishift")))
11837 (set (attr "length_immediate")
11839 (ior (eq_attr "type" "alu")
11840 (and (eq_attr "type" "ishift")
11841 (and (match_operand 2 "const1_operand" "")
11842 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11845 (const_string "*")))
11846 (set_attr "mode" "DI")])
11848 (define_insn "*ashldi3_cconly_rex64"
11849 [(set (reg FLAGS_REG)
11851 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11852 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11854 (clobber (match_scratch:DI 0 "=r"))]
11856 && (optimize_function_for_size_p (cfun)
11857 || !TARGET_PARTIAL_FLAG_REG_STALL
11858 || (operands[2] == const1_rtx
11860 || TARGET_DOUBLE_WITH_ADD)))
11861 && ix86_match_ccmode (insn, CCGOCmode)
11862 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11864 switch (get_attr_type (insn))
11867 gcc_assert (operands[2] == const1_rtx);
11868 return "add{q}\t%0, %0";
11871 if (REG_P (operands[2]))
11872 return "sal{q}\t{%b2, %0|%0, %b2}";
11873 else if (operands[2] == const1_rtx
11874 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11875 return "sal{q}\t%0";
11877 return "sal{q}\t{%2, %0|%0, %2}";
11880 [(set (attr "type")
11881 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11883 (match_operand 0 "register_operand" ""))
11884 (match_operand 2 "const1_operand" ""))
11885 (const_string "alu")
11887 (const_string "ishift")))
11888 (set (attr "length_immediate")
11890 (ior (eq_attr "type" "alu")
11891 (and (eq_attr "type" "ishift")
11892 (and (match_operand 2 "const1_operand" "")
11893 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11896 (const_string "*")))
11897 (set_attr "mode" "DI")])
11899 (define_insn "*ashldi3_1"
11900 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11901 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11902 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11903 (clobber (reg:CC FLAGS_REG))]
11906 [(set_attr "type" "multi")])
11908 ;; By default we don't ask for a scratch register, because when DImode
11909 ;; values are manipulated, registers are already at a premium. But if
11910 ;; we have one handy, we won't turn it away.
11912 [(match_scratch:SI 3 "r")
11913 (parallel [(set (match_operand:DI 0 "register_operand" "")
11914 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11915 (match_operand:QI 2 "nonmemory_operand" "")))
11916 (clobber (reg:CC FLAGS_REG))])
11918 "!TARGET_64BIT && TARGET_CMOVE"
11920 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11923 [(set (match_operand:DI 0 "register_operand" "")
11924 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11925 (match_operand:QI 2 "nonmemory_operand" "")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11928 ? epilogue_completed : reload_completed)"
11930 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11932 (define_insn "x86_shld"
11933 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11934 (ior:SI (ashift:SI (match_dup 0)
11935 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11936 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11937 (minus:QI (const_int 32) (match_dup 2)))))
11938 (clobber (reg:CC FLAGS_REG))]
11940 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11941 [(set_attr "type" "ishift")
11942 (set_attr "prefix_0f" "1")
11943 (set_attr "mode" "SI")
11944 (set_attr "pent_pair" "np")
11945 (set_attr "athlon_decode" "vector")
11946 (set_attr "amdfam10_decode" "vector")])
11948 (define_expand "x86_shift_adj_1"
11949 [(set (reg:CCZ FLAGS_REG)
11950 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11953 (set (match_operand:SI 0 "register_operand" "")
11954 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11955 (match_operand:SI 1 "register_operand" "")
11958 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11959 (match_operand:SI 3 "register_operand" "r")
11964 (define_expand "x86_shift_adj_2"
11965 [(use (match_operand:SI 0 "register_operand" ""))
11966 (use (match_operand:SI 1 "register_operand" ""))
11967 (use (match_operand:QI 2 "register_operand" ""))]
11970 rtx label = gen_label_rtx ();
11973 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11975 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11976 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11977 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11978 gen_rtx_LABEL_REF (VOIDmode, label),
11980 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11981 JUMP_LABEL (tmp) = label;
11983 emit_move_insn (operands[0], operands[1]);
11984 ix86_expand_clear (operands[1]);
11986 emit_label (label);
11987 LABEL_NUSES (label) = 1;
11992 (define_expand "ashlsi3"
11993 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11994 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11995 (match_operand:QI 2 "nonmemory_operand" "")))]
11997 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11999 (define_insn "*ashlsi3_1"
12000 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
12001 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
12002 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12003 (clobber (reg:CC FLAGS_REG))]
12004 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12006 switch (get_attr_type (insn))
12009 gcc_assert (operands[2] == const1_rtx);
12010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
12011 return "add{l}\t%0, %0";
12017 if (REG_P (operands[2]))
12018 return "sal{l}\t{%b2, %0|%0, %b2}";
12019 else if (operands[2] == const1_rtx
12020 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12021 return "sal{l}\t%0";
12023 return "sal{l}\t{%2, %0|%0, %2}";
12026 [(set (attr "type")
12027 (cond [(eq_attr "alternative" "1")
12028 (const_string "lea")
12029 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12031 (match_operand 0 "register_operand" ""))
12032 (match_operand 2 "const1_operand" ""))
12033 (const_string "alu")
12035 (const_string "ishift")))
12036 (set (attr "length_immediate")
12038 (ior (eq_attr "type" "alu")
12039 (and (eq_attr "type" "ishift")
12040 (and (match_operand 2 "const1_operand" "")
12041 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12044 (const_string "*")))
12045 (set_attr "mode" "SI")])
12047 ;; Convert lea to the lea pattern to avoid flags dependency.
12049 [(set (match_operand 0 "register_operand" "")
12050 (ashift (match_operand 1 "index_register_operand" "")
12051 (match_operand:QI 2 "const_int_operand" "")))
12052 (clobber (reg:CC FLAGS_REG))]
12054 && true_regnum (operands[0]) != true_regnum (operands[1])
12055 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
12059 enum machine_mode mode = GET_MODE (operands[0]);
12061 if (GET_MODE_SIZE (mode) < 4)
12062 operands[0] = gen_lowpart (SImode, operands[0]);
12064 operands[1] = gen_lowpart (Pmode, operands[1]);
12065 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12067 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12068 if (Pmode != SImode)
12069 pat = gen_rtx_SUBREG (SImode, pat, 0);
12070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12074 ;; Rare case of shifting RSP is handled by generating move and shift
12076 [(set (match_operand 0 "register_operand" "")
12077 (ashift (match_operand 1 "register_operand" "")
12078 (match_operand:QI 2 "const_int_operand" "")))
12079 (clobber (reg:CC FLAGS_REG))]
12081 && true_regnum (operands[0]) != true_regnum (operands[1])"
12085 emit_move_insn (operands[0], operands[1]);
12086 pat = gen_rtx_SET (VOIDmode, operands[0],
12087 gen_rtx_ASHIFT (GET_MODE (operands[0]),
12088 operands[0], operands[2]));
12089 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12090 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12094 (define_insn "*ashlsi3_1_zext"
12095 [(set (match_operand:DI 0 "register_operand" "=r,r")
12096 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
12097 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
12098 (clobber (reg:CC FLAGS_REG))]
12099 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12101 switch (get_attr_type (insn))
12104 gcc_assert (operands[2] == const1_rtx);
12105 return "add{l}\t%k0, %k0";
12111 if (REG_P (operands[2]))
12112 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12113 else if (operands[2] == const1_rtx
12114 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12115 return "sal{l}\t%k0";
12117 return "sal{l}\t{%2, %k0|%k0, %2}";
12120 [(set (attr "type")
12121 (cond [(eq_attr "alternative" "1")
12122 (const_string "lea")
12123 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12125 (match_operand 2 "const1_operand" ""))
12126 (const_string "alu")
12128 (const_string "ishift")))
12129 (set (attr "length_immediate")
12131 (ior (eq_attr "type" "alu")
12132 (and (eq_attr "type" "ishift")
12133 (and (match_operand 2 "const1_operand" "")
12134 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12137 (const_string "*")))
12138 (set_attr "mode" "SI")])
12140 ;; Convert lea to the lea pattern to avoid flags dependency.
12142 [(set (match_operand:DI 0 "register_operand" "")
12143 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12144 (match_operand:QI 2 "const_int_operand" ""))))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "TARGET_64BIT && reload_completed
12147 && true_regnum (operands[0]) != true_regnum (operands[1])"
12148 [(set (match_dup 0) (zero_extend:DI
12149 (subreg:SI (mult:SI (match_dup 1)
12150 (match_dup 2)) 0)))]
12152 operands[1] = gen_lowpart (Pmode, operands[1]);
12153 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12156 ;; This pattern can't accept a variable shift count, since shifts by
12157 ;; zero don't affect the flags. We assume that shifts by constant
12158 ;; zero are optimized away.
12159 (define_insn "*ashlsi3_cmp"
12160 [(set (reg FLAGS_REG)
12162 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12165 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166 (ashift:SI (match_dup 1) (match_dup 2)))]
12167 "(optimize_function_for_size_p (cfun)
12168 || !TARGET_PARTIAL_FLAG_REG_STALL
12169 || (operands[2] == const1_rtx
12171 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12172 && ix86_match_ccmode (insn, CCGOCmode)
12173 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12175 switch (get_attr_type (insn))
12178 gcc_assert (operands[2] == const1_rtx);
12179 return "add{l}\t%0, %0";
12182 if (REG_P (operands[2]))
12183 return "sal{l}\t{%b2, %0|%0, %b2}";
12184 else if (operands[2] == const1_rtx
12185 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12186 return "sal{l}\t%0";
12188 return "sal{l}\t{%2, %0|%0, %2}";
12191 [(set (attr "type")
12192 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12194 (match_operand 0 "register_operand" ""))
12195 (match_operand 2 "const1_operand" ""))
12196 (const_string "alu")
12198 (const_string "ishift")))
12199 (set (attr "length_immediate")
12201 (ior (eq_attr "type" "alu")
12202 (and (eq_attr "type" "ishift")
12203 (and (match_operand 2 "const1_operand" "")
12204 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12207 (const_string "*")))
12208 (set_attr "mode" "SI")])
12210 (define_insn "*ashlsi3_cconly"
12211 [(set (reg FLAGS_REG)
12213 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12214 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12216 (clobber (match_scratch:SI 0 "=r"))]
12217 "(optimize_function_for_size_p (cfun)
12218 || !TARGET_PARTIAL_FLAG_REG_STALL
12219 || (operands[2] == const1_rtx
12221 || TARGET_DOUBLE_WITH_ADD)))
12222 && ix86_match_ccmode (insn, CCGOCmode)
12223 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12225 switch (get_attr_type (insn))
12228 gcc_assert (operands[2] == const1_rtx);
12229 return "add{l}\t%0, %0";
12232 if (REG_P (operands[2]))
12233 return "sal{l}\t{%b2, %0|%0, %b2}";
12234 else if (operands[2] == const1_rtx
12235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12236 return "sal{l}\t%0";
12238 return "sal{l}\t{%2, %0|%0, %2}";
12241 [(set (attr "type")
12242 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12244 (match_operand 0 "register_operand" ""))
12245 (match_operand 2 "const1_operand" ""))
12246 (const_string "alu")
12248 (const_string "ishift")))
12249 (set (attr "length_immediate")
12251 (ior (eq_attr "type" "alu")
12252 (and (eq_attr "type" "ishift")
12253 (and (match_operand 2 "const1_operand" "")
12254 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12257 (const_string "*")))
12258 (set_attr "mode" "SI")])
12260 (define_insn "*ashlsi3_cmp_zext"
12261 [(set (reg FLAGS_REG)
12263 (ashift:SI (match_operand:SI 1 "register_operand" "0")
12264 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12266 (set (match_operand:DI 0 "register_operand" "=r")
12267 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
12269 && (optimize_function_for_size_p (cfun)
12270 || !TARGET_PARTIAL_FLAG_REG_STALL
12271 || (operands[2] == const1_rtx
12273 || TARGET_DOUBLE_WITH_ADD)))
12274 && ix86_match_ccmode (insn, CCGOCmode)
12275 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12277 switch (get_attr_type (insn))
12280 gcc_assert (operands[2] == const1_rtx);
12281 return "add{l}\t%k0, %k0";
12284 if (REG_P (operands[2]))
12285 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12286 else if (operands[2] == const1_rtx
12287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12288 return "sal{l}\t%k0";
12290 return "sal{l}\t{%2, %k0|%k0, %2}";
12293 [(set (attr "type")
12294 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12296 (match_operand 2 "const1_operand" ""))
12297 (const_string "alu")
12299 (const_string "ishift")))
12300 (set (attr "length_immediate")
12302 (ior (eq_attr "type" "alu")
12303 (and (eq_attr "type" "ishift")
12304 (and (match_operand 2 "const1_operand" "")
12305 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12308 (const_string "*")))
12309 (set_attr "mode" "SI")])
12311 (define_expand "ashlhi3"
12312 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12313 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
12314 (match_operand:QI 2 "nonmemory_operand" "")))]
12315 "TARGET_HIMODE_MATH"
12316 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12318 (define_insn "*ashlhi3_1_lea"
12319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
12320 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
12321 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12322 (clobber (reg:CC FLAGS_REG))]
12323 "!TARGET_PARTIAL_REG_STALL
12324 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12326 switch (get_attr_type (insn))
12331 gcc_assert (operands[2] == const1_rtx);
12332 return "add{w}\t%0, %0";
12335 if (REG_P (operands[2]))
12336 return "sal{w}\t{%b2, %0|%0, %b2}";
12337 else if (operands[2] == const1_rtx
12338 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12339 return "sal{w}\t%0";
12341 return "sal{w}\t{%2, %0|%0, %2}";
12344 [(set (attr "type")
12345 (cond [(eq_attr "alternative" "1")
12346 (const_string "lea")
12347 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12349 (match_operand 0 "register_operand" ""))
12350 (match_operand 2 "const1_operand" ""))
12351 (const_string "alu")
12353 (const_string "ishift")))
12354 (set (attr "length_immediate")
12356 (ior (eq_attr "type" "alu")
12357 (and (eq_attr "type" "ishift")
12358 (and (match_operand 2 "const1_operand" "")
12359 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12362 (const_string "*")))
12363 (set_attr "mode" "HI,SI")])
12365 (define_insn "*ashlhi3_1"
12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "nonmemory_operand" "cI")))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "TARGET_PARTIAL_REG_STALL
12371 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12373 switch (get_attr_type (insn))
12376 gcc_assert (operands[2] == const1_rtx);
12377 return "add{w}\t%0, %0";
12380 if (REG_P (operands[2]))
12381 return "sal{w}\t{%b2, %0|%0, %b2}";
12382 else if (operands[2] == const1_rtx
12383 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12384 return "sal{w}\t%0";
12386 return "sal{w}\t{%2, %0|%0, %2}";
12389 [(set (attr "type")
12390 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12392 (match_operand 0 "register_operand" ""))
12393 (match_operand 2 "const1_operand" ""))
12394 (const_string "alu")
12396 (const_string "ishift")))
12397 (set (attr "length_immediate")
12399 (ior (eq_attr "type" "alu")
12400 (and (eq_attr "type" "ishift")
12401 (and (match_operand 2 "const1_operand" "")
12402 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12405 (const_string "*")))
12406 (set_attr "mode" "HI")])
12408 ;; This pattern can't accept a variable shift count, since shifts by
12409 ;; zero don't affect the flags. We assume that shifts by constant
12410 ;; zero are optimized away.
12411 (define_insn "*ashlhi3_cmp"
12412 [(set (reg FLAGS_REG)
12414 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12417 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12418 (ashift:HI (match_dup 1) (match_dup 2)))]
12419 "(optimize_function_for_size_p (cfun)
12420 || !TARGET_PARTIAL_FLAG_REG_STALL
12421 || (operands[2] == const1_rtx
12423 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12424 && ix86_match_ccmode (insn, CCGOCmode)
12425 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12427 switch (get_attr_type (insn))
12430 gcc_assert (operands[2] == const1_rtx);
12431 return "add{w}\t%0, %0";
12434 if (REG_P (operands[2]))
12435 return "sal{w}\t{%b2, %0|%0, %b2}";
12436 else if (operands[2] == const1_rtx
12437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12438 return "sal{w}\t%0";
12440 return "sal{w}\t{%2, %0|%0, %2}";
12443 [(set (attr "type")
12444 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12446 (match_operand 0 "register_operand" ""))
12447 (match_operand 2 "const1_operand" ""))
12448 (const_string "alu")
12450 (const_string "ishift")))
12451 (set (attr "length_immediate")
12453 (ior (eq_attr "type" "alu")
12454 (and (eq_attr "type" "ishift")
12455 (and (match_operand 2 "const1_operand" "")
12456 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12459 (const_string "*")))
12460 (set_attr "mode" "HI")])
12462 (define_insn "*ashlhi3_cconly"
12463 [(set (reg FLAGS_REG)
12465 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12466 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12468 (clobber (match_scratch:HI 0 "=r"))]
12469 "(optimize_function_for_size_p (cfun)
12470 || !TARGET_PARTIAL_FLAG_REG_STALL
12471 || (operands[2] == const1_rtx
12473 || TARGET_DOUBLE_WITH_ADD)))
12474 && ix86_match_ccmode (insn, CCGOCmode)
12475 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12477 switch (get_attr_type (insn))
12480 gcc_assert (operands[2] == const1_rtx);
12481 return "add{w}\t%0, %0";
12484 if (REG_P (operands[2]))
12485 return "sal{w}\t{%b2, %0|%0, %b2}";
12486 else if (operands[2] == const1_rtx
12487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12488 return "sal{w}\t%0";
12490 return "sal{w}\t{%2, %0|%0, %2}";
12493 [(set (attr "type")
12494 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12496 (match_operand 0 "register_operand" ""))
12497 (match_operand 2 "const1_operand" ""))
12498 (const_string "alu")
12500 (const_string "ishift")))
12501 (set (attr "length_immediate")
12503 (ior (eq_attr "type" "alu")
12504 (and (eq_attr "type" "ishift")
12505 (and (match_operand 2 "const1_operand" "")
12506 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12509 (const_string "*")))
12510 (set_attr "mode" "HI")])
12512 (define_expand "ashlqi3"
12513 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12514 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12515 (match_operand:QI 2 "nonmemory_operand" "")))]
12516 "TARGET_QIMODE_MATH"
12517 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12519 ;; %%% Potential partial reg stall on alternative 2. What to do?
12521 (define_insn "*ashlqi3_1_lea"
12522 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12523 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12524 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12525 (clobber (reg:CC FLAGS_REG))]
12526 "!TARGET_PARTIAL_REG_STALL
12527 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12529 switch (get_attr_type (insn))
12534 gcc_assert (operands[2] == const1_rtx);
12535 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12536 return "add{l}\t%k0, %k0";
12538 return "add{b}\t%0, %0";
12541 if (REG_P (operands[2]))
12543 if (get_attr_mode (insn) == MODE_SI)
12544 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12546 return "sal{b}\t{%b2, %0|%0, %b2}";
12548 else if (operands[2] == const1_rtx
12549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12551 if (get_attr_mode (insn) == MODE_SI)
12552 return "sal{l}\t%0";
12554 return "sal{b}\t%0";
12558 if (get_attr_mode (insn) == MODE_SI)
12559 return "sal{l}\t{%2, %k0|%k0, %2}";
12561 return "sal{b}\t{%2, %0|%0, %2}";
12565 [(set (attr "type")
12566 (cond [(eq_attr "alternative" "2")
12567 (const_string "lea")
12568 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12570 (match_operand 0 "register_operand" ""))
12571 (match_operand 2 "const1_operand" ""))
12572 (const_string "alu")
12574 (const_string "ishift")))
12575 (set (attr "length_immediate")
12577 (ior (eq_attr "type" "alu")
12578 (and (eq_attr "type" "ishift")
12579 (and (match_operand 2 "const1_operand" "")
12580 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12583 (const_string "*")))
12584 (set_attr "mode" "QI,SI,SI")])
12586 (define_insn "*ashlqi3_1"
12587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12588 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12589 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12590 (clobber (reg:CC FLAGS_REG))]
12591 "TARGET_PARTIAL_REG_STALL
12592 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12594 switch (get_attr_type (insn))
12597 gcc_assert (operands[2] == const1_rtx);
12598 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12599 return "add{l}\t%k0, %k0";
12601 return "add{b}\t%0, %0";
12604 if (REG_P (operands[2]))
12606 if (get_attr_mode (insn) == MODE_SI)
12607 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12609 return "sal{b}\t{%b2, %0|%0, %b2}";
12611 else if (operands[2] == const1_rtx
12612 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12614 if (get_attr_mode (insn) == MODE_SI)
12615 return "sal{l}\t%0";
12617 return "sal{b}\t%0";
12621 if (get_attr_mode (insn) == MODE_SI)
12622 return "sal{l}\t{%2, %k0|%k0, %2}";
12624 return "sal{b}\t{%2, %0|%0, %2}";
12628 [(set (attr "type")
12629 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12631 (match_operand 0 "register_operand" ""))
12632 (match_operand 2 "const1_operand" ""))
12633 (const_string "alu")
12635 (const_string "ishift")))
12636 (set (attr "length_immediate")
12638 (ior (eq_attr "type" "alu")
12639 (and (eq_attr "type" "ishift")
12640 (and (match_operand 2 "const1_operand" "")
12641 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12644 (const_string "*")))
12645 (set_attr "mode" "QI,SI")])
12647 ;; This pattern can't accept a variable shift count, since shifts by
12648 ;; zero don't affect the flags. We assume that shifts by constant
12649 ;; zero are optimized away.
12650 (define_insn "*ashlqi3_cmp"
12651 [(set (reg FLAGS_REG)
12653 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12654 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12656 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12657 (ashift:QI (match_dup 1) (match_dup 2)))]
12658 "(optimize_function_for_size_p (cfun)
12659 || !TARGET_PARTIAL_FLAG_REG_STALL
12660 || (operands[2] == const1_rtx
12662 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12663 && ix86_match_ccmode (insn, CCGOCmode)
12664 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12666 switch (get_attr_type (insn))
12669 gcc_assert (operands[2] == const1_rtx);
12670 return "add{b}\t%0, %0";
12673 if (REG_P (operands[2]))
12674 return "sal{b}\t{%b2, %0|%0, %b2}";
12675 else if (operands[2] == const1_rtx
12676 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12677 return "sal{b}\t%0";
12679 return "sal{b}\t{%2, %0|%0, %2}";
12682 [(set (attr "type")
12683 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12685 (match_operand 0 "register_operand" ""))
12686 (match_operand 2 "const1_operand" ""))
12687 (const_string "alu")
12689 (const_string "ishift")))
12690 (set (attr "length_immediate")
12692 (ior (eq_attr "type" "alu")
12693 (and (eq_attr "type" "ishift")
12694 (and (match_operand 2 "const1_operand" "")
12695 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12698 (const_string "*")))
12699 (set_attr "mode" "QI")])
12701 (define_insn "*ashlqi3_cconly"
12702 [(set (reg FLAGS_REG)
12704 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12705 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12707 (clobber (match_scratch:QI 0 "=q"))]
12708 "(optimize_function_for_size_p (cfun)
12709 || !TARGET_PARTIAL_FLAG_REG_STALL
12710 || (operands[2] == const1_rtx
12712 || TARGET_DOUBLE_WITH_ADD)))
12713 && ix86_match_ccmode (insn, CCGOCmode)
12714 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12716 switch (get_attr_type (insn))
12719 gcc_assert (operands[2] == const1_rtx);
12720 return "add{b}\t%0, %0";
12723 if (REG_P (operands[2]))
12724 return "sal{b}\t{%b2, %0|%0, %b2}";
12725 else if (operands[2] == const1_rtx
12726 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12727 return "sal{b}\t%0";
12729 return "sal{b}\t{%2, %0|%0, %2}";
12732 [(set (attr "type")
12733 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12735 (match_operand 0 "register_operand" ""))
12736 (match_operand 2 "const1_operand" ""))
12737 (const_string "alu")
12739 (const_string "ishift")))
12740 (set (attr "length_immediate")
12742 (ior (eq_attr "type" "alu")
12743 (and (eq_attr "type" "ishift")
12744 (and (match_operand 2 "const1_operand" "")
12745 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12748 (const_string "*")))
12749 (set_attr "mode" "QI")])
12751 ;; See comment above `ashldi3' about how this works.
12753 (define_expand "ashrti3"
12754 [(set (match_operand:TI 0 "register_operand" "")
12755 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12756 (match_operand:QI 2 "nonmemory_operand" "")))]
12758 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12760 (define_insn "*ashrti3_1"
12761 [(set (match_operand:TI 0 "register_operand" "=r")
12762 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12763 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12764 (clobber (reg:CC FLAGS_REG))]
12767 [(set_attr "type" "multi")])
12770 [(match_scratch:DI 3 "r")
12771 (parallel [(set (match_operand:TI 0 "register_operand" "")
12772 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12773 (match_operand:QI 2 "nonmemory_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))])
12778 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12781 [(set (match_operand:TI 0 "register_operand" "")
12782 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12783 (match_operand:QI 2 "nonmemory_operand" "")))
12784 (clobber (reg:CC FLAGS_REG))]
12785 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12786 ? epilogue_completed : reload_completed)"
12788 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12790 (define_insn "x86_64_shrd"
12791 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12792 (ior:DI (ashiftrt:DI (match_dup 0)
12793 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12794 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12795 (minus:QI (const_int 64) (match_dup 2)))))
12796 (clobber (reg:CC FLAGS_REG))]
12798 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12799 [(set_attr "type" "ishift")
12800 (set_attr "prefix_0f" "1")
12801 (set_attr "mode" "DI")
12802 (set_attr "athlon_decode" "vector")
12803 (set_attr "amdfam10_decode" "vector")])
12805 (define_expand "ashrdi3"
12806 [(set (match_operand:DI 0 "shiftdi_operand" "")
12807 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12808 (match_operand:QI 2 "nonmemory_operand" "")))]
12810 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12812 (define_expand "x86_64_shift_adj_3"
12813 [(use (match_operand:DI 0 "register_operand" ""))
12814 (use (match_operand:DI 1 "register_operand" ""))
12815 (use (match_operand:QI 2 "register_operand" ""))]
12818 rtx label = gen_label_rtx ();
12821 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12823 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12824 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12825 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12826 gen_rtx_LABEL_REF (VOIDmode, label),
12828 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12829 JUMP_LABEL (tmp) = label;
12831 emit_move_insn (operands[0], operands[1]);
12832 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12834 emit_label (label);
12835 LABEL_NUSES (label) = 1;
12840 (define_insn "ashrdi3_63_rex64"
12841 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12842 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12843 (match_operand:DI 2 "const_int_operand" "i,i")))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && INTVAL (operands[2]) == 63
12846 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12847 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12850 sar{q}\t{%2, %0|%0, %2}"
12851 [(set_attr "type" "imovx,ishift")
12852 (set_attr "prefix_0f" "0,*")
12853 (set_attr "length_immediate" "0,*")
12854 (set_attr "modrm" "0,1")
12855 (set_attr "mode" "DI")])
12857 (define_insn "*ashrdi3_1_one_bit_rex64"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12866 [(set_attr "type" "ishift")
12867 (set_attr "length_immediate" "0")
12868 (set_attr "mode" "DI")])
12870 (define_insn "*ashrdi3_1_rex64"
12871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12872 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12873 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12877 sar{q}\t{%2, %0|%0, %2}
12878 sar{q}\t{%b2, %0|%0, %b2}"
12879 [(set_attr "type" "ishift")
12880 (set_attr "mode" "DI")])
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags. We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12886 [(set (reg FLAGS_REG)
12888 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12889 (match_operand:QI 2 "const1_operand" ""))
12891 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12892 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12898 [(set_attr "type" "ishift")
12899 (set_attr "length_immediate" "0")
12900 (set_attr "mode" "DI")])
12902 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12903 [(set (reg FLAGS_REG)
12905 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906 (match_operand:QI 2 "const1_operand" ""))
12908 (clobber (match_scratch:DI 0 "=r"))]
12910 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12911 && ix86_match_ccmode (insn, CCGOCmode)
12912 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12914 [(set_attr "type" "ishift")
12915 (set_attr "length_immediate" "0")
12916 (set_attr "mode" "DI")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags. We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*ashrdi3_cmp_rex64"
12922 [(set (reg FLAGS_REG)
12924 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12927 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12928 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12930 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12931 && ix86_match_ccmode (insn, CCGOCmode)
12932 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12933 "sar{q}\t{%2, %0|%0, %2}"
12934 [(set_attr "type" "ishift")
12935 (set_attr "mode" "DI")])
12937 (define_insn "*ashrdi3_cconly_rex64"
12938 [(set (reg FLAGS_REG)
12940 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12941 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12943 (clobber (match_scratch:DI 0 "=r"))]
12945 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12946 && ix86_match_ccmode (insn, CCGOCmode)
12947 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12948 "sar{q}\t{%2, %0|%0, %2}"
12949 [(set_attr "type" "ishift")
12950 (set_attr "mode" "DI")])
12952 (define_insn "*ashrdi3_1"
12953 [(set (match_operand:DI 0 "register_operand" "=r")
12954 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12955 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12956 (clobber (reg:CC FLAGS_REG))]
12959 [(set_attr "type" "multi")])
12961 ;; By default we don't ask for a scratch register, because when DImode
12962 ;; values are manipulated, registers are already at a premium. But if
12963 ;; we have one handy, we won't turn it away.
12965 [(match_scratch:SI 3 "r")
12966 (parallel [(set (match_operand:DI 0 "register_operand" "")
12967 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12968 (match_operand:QI 2 "nonmemory_operand" "")))
12969 (clobber (reg:CC FLAGS_REG))])
12971 "!TARGET_64BIT && TARGET_CMOVE"
12973 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12976 [(set (match_operand:DI 0 "register_operand" "")
12977 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12978 (match_operand:QI 2 "nonmemory_operand" "")))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12981 ? epilogue_completed : reload_completed)"
12983 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12985 (define_insn "x86_shrd"
12986 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12987 (ior:SI (ashiftrt:SI (match_dup 0)
12988 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12989 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12990 (minus:QI (const_int 32) (match_dup 2)))))
12991 (clobber (reg:CC FLAGS_REG))]
12993 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12994 [(set_attr "type" "ishift")
12995 (set_attr "prefix_0f" "1")
12996 (set_attr "pent_pair" "np")
12997 (set_attr "mode" "SI")])
12999 (define_expand "x86_shift_adj_3"
13000 [(use (match_operand:SI 0 "register_operand" ""))
13001 (use (match_operand:SI 1 "register_operand" ""))
13002 (use (match_operand:QI 2 "register_operand" ""))]
13005 rtx label = gen_label_rtx ();
13008 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
13010 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13011 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13012 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13013 gen_rtx_LABEL_REF (VOIDmode, label),
13015 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13016 JUMP_LABEL (tmp) = label;
13018 emit_move_insn (operands[0], operands[1]);
13019 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13021 emit_label (label);
13022 LABEL_NUSES (label) = 1;
13027 (define_expand "ashrsi3_31"
13028 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13029 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13030 (match_operand:SI 2 "const_int_operand" "i,i")))
13031 (clobber (reg:CC FLAGS_REG))])]
13034 (define_insn "*ashrsi3_31"
13035 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13036 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13037 (match_operand:SI 2 "const_int_operand" "i,i")))
13038 (clobber (reg:CC FLAGS_REG))]
13039 "INTVAL (operands[2]) == 31
13040 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13041 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13044 sar{l}\t{%2, %0|%0, %2}"
13045 [(set_attr "type" "imovx,ishift")
13046 (set_attr "prefix_0f" "0,*")
13047 (set_attr "length_immediate" "0,*")
13048 (set_attr "modrm" "0,1")
13049 (set_attr "mode" "SI")])
13051 (define_insn "*ashrsi3_31_zext"
13052 [(set (match_operand:DI 0 "register_operand" "=*d,r")
13053 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13054 (match_operand:SI 2 "const_int_operand" "i,i"))))
13055 (clobber (reg:CC FLAGS_REG))]
13056 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13057 && INTVAL (operands[2]) == 31
13058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13061 sar{l}\t{%2, %k0|%k0, %2}"
13062 [(set_attr "type" "imovx,ishift")
13063 (set_attr "prefix_0f" "0,*")
13064 (set_attr "length_immediate" "0,*")
13065 (set_attr "modrm" "0,1")
13066 (set_attr "mode" "SI")])
13068 (define_expand "ashrsi3"
13069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13070 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13071 (match_operand:QI 2 "nonmemory_operand" "")))]
13073 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13075 (define_insn "*ashrsi3_1_one_bit"
13076 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13077 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13078 (match_operand:QI 2 "const1_operand" "")))
13079 (clobber (reg:CC FLAGS_REG))]
13080 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13081 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13083 [(set_attr "type" "ishift")
13084 (set_attr "length_immediate" "0")
13085 (set_attr "mode" "SI")])
13087 (define_insn "*ashrsi3_1_one_bit_zext"
13088 [(set (match_operand:DI 0 "register_operand" "=r")
13089 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13090 (match_operand:QI 2 "const1_operand" ""))))
13091 (clobber (reg:CC FLAGS_REG))]
13093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13094 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13096 [(set_attr "type" "ishift")
13097 (set_attr "length_immediate" "0")
13098 (set_attr "mode" "SI")])
13100 (define_insn "*ashrsi3_1"
13101 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13102 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13103 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13104 (clobber (reg:CC FLAGS_REG))]
13105 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13107 sar{l}\t{%2, %0|%0, %2}
13108 sar{l}\t{%b2, %0|%0, %b2}"
13109 [(set_attr "type" "ishift")
13110 (set_attr "mode" "SI")])
13112 (define_insn "*ashrsi3_1_zext"
13113 [(set (match_operand:DI 0 "register_operand" "=r,r")
13114 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13115 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13116 (clobber (reg:CC FLAGS_REG))]
13117 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13119 sar{l}\t{%2, %k0|%k0, %2}
13120 sar{l}\t{%b2, %k0|%k0, %b2}"
13121 [(set_attr "type" "ishift")
13122 (set_attr "mode" "SI")])
13124 ;; This pattern can't accept a variable shift count, since shifts by
13125 ;; zero don't affect the flags. We assume that shifts by constant
13126 ;; zero are optimized away.
13127 (define_insn "*ashrsi3_one_bit_cmp"
13128 [(set (reg FLAGS_REG)
13130 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13131 (match_operand:QI 2 "const1_operand" ""))
13133 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13134 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13135 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13136 && ix86_match_ccmode (insn, CCGOCmode)
13137 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13139 [(set_attr "type" "ishift")
13140 (set_attr "length_immediate" "0")
13141 (set_attr "mode" "SI")])
13143 (define_insn "*ashrsi3_one_bit_cconly"
13144 [(set (reg FLAGS_REG)
13146 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13147 (match_operand:QI 2 "const1_operand" ""))
13149 (clobber (match_scratch:SI 0 "=r"))]
13150 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13151 && ix86_match_ccmode (insn, CCGOCmode)
13152 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13154 [(set_attr "type" "ishift")
13155 (set_attr "length_immediate" "0")
13156 (set_attr "mode" "SI")])
13158 (define_insn "*ashrsi3_one_bit_cmp_zext"
13159 [(set (reg FLAGS_REG)
13161 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13162 (match_operand:QI 2 "const1_operand" ""))
13164 (set (match_operand:DI 0 "register_operand" "=r")
13165 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13167 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13168 && ix86_match_ccmode (insn, CCmode)
13169 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13171 [(set_attr "type" "ishift")
13172 (set_attr "length_immediate" "0")
13173 (set_attr "mode" "SI")])
13175 ;; This pattern can't accept a variable shift count, since shifts by
13176 ;; zero don't affect the flags. We assume that shifts by constant
13177 ;; zero are optimized away.
13178 (define_insn "*ashrsi3_cmp"
13179 [(set (reg FLAGS_REG)
13181 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13182 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13184 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13185 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13186 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13187 && ix86_match_ccmode (insn, CCGOCmode)
13188 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13189 "sar{l}\t{%2, %0|%0, %2}"
13190 [(set_attr "type" "ishift")
13191 (set_attr "mode" "SI")])
13193 (define_insn "*ashrsi3_cconly"
13194 [(set (reg FLAGS_REG)
13196 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13197 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13199 (clobber (match_scratch:SI 0 "=r"))]
13200 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13201 && ix86_match_ccmode (insn, CCGOCmode)
13202 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13203 "sar{l}\t{%2, %0|%0, %2}"
13204 [(set_attr "type" "ishift")
13205 (set_attr "mode" "SI")])
13207 (define_insn "*ashrsi3_cmp_zext"
13208 [(set (reg FLAGS_REG)
13210 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13213 (set (match_operand:DI 0 "register_operand" "=r")
13214 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13216 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13217 && ix86_match_ccmode (insn, CCGOCmode)
13218 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13219 "sar{l}\t{%2, %k0|%k0, %2}"
13220 [(set_attr "type" "ishift")
13221 (set_attr "mode" "SI")])
13223 (define_expand "ashrhi3"
13224 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13225 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13226 (match_operand:QI 2 "nonmemory_operand" "")))]
13227 "TARGET_HIMODE_MATH"
13228 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13230 (define_insn "*ashrhi3_1_one_bit"
13231 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13232 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13233 (match_operand:QI 2 "const1_operand" "")))
13234 (clobber (reg:CC FLAGS_REG))]
13235 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13236 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13238 [(set_attr "type" "ishift")
13239 (set_attr "length_immediate" "0")
13240 (set_attr "mode" "HI")])
13242 (define_insn "*ashrhi3_1"
13243 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13244 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13245 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13246 (clobber (reg:CC FLAGS_REG))]
13247 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13249 sar{w}\t{%2, %0|%0, %2}
13250 sar{w}\t{%b2, %0|%0, %b2}"
13251 [(set_attr "type" "ishift")
13252 (set_attr "mode" "HI")])
13254 ;; This pattern can't accept a variable shift count, since shifts by
13255 ;; zero don't affect the flags. We assume that shifts by constant
13256 ;; zero are optimized away.
13257 (define_insn "*ashrhi3_one_bit_cmp"
13258 [(set (reg FLAGS_REG)
13260 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13261 (match_operand:QI 2 "const1_operand" ""))
13263 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13264 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13265 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13266 && ix86_match_ccmode (insn, CCGOCmode)
13267 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13269 [(set_attr "type" "ishift")
13270 (set_attr "length_immediate" "0")
13271 (set_attr "mode" "HI")])
13273 (define_insn "*ashrhi3_one_bit_cconly"
13274 [(set (reg FLAGS_REG)
13276 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13277 (match_operand:QI 2 "const1_operand" ""))
13279 (clobber (match_scratch:HI 0 "=r"))]
13280 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13281 && ix86_match_ccmode (insn, CCGOCmode)
13282 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13284 [(set_attr "type" "ishift")
13285 (set_attr "length_immediate" "0")
13286 (set_attr "mode" "HI")])
13288 ;; This pattern can't accept a variable shift count, since shifts by
13289 ;; zero don't affect the flags. We assume that shifts by constant
13290 ;; zero are optimized away.
13291 (define_insn "*ashrhi3_cmp"
13292 [(set (reg FLAGS_REG)
13294 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13295 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13297 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13298 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13299 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13300 && ix86_match_ccmode (insn, CCGOCmode)
13301 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13302 "sar{w}\t{%2, %0|%0, %2}"
13303 [(set_attr "type" "ishift")
13304 (set_attr "mode" "HI")])
13306 (define_insn "*ashrhi3_cconly"
13307 [(set (reg FLAGS_REG)
13309 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13310 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13312 (clobber (match_scratch:HI 0 "=r"))]
13313 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13314 && ix86_match_ccmode (insn, CCGOCmode)
13315 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13316 "sar{w}\t{%2, %0|%0, %2}"
13317 [(set_attr "type" "ishift")
13318 (set_attr "mode" "HI")])
13320 (define_expand "ashrqi3"
13321 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13322 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13323 (match_operand:QI 2 "nonmemory_operand" "")))]
13324 "TARGET_QIMODE_MATH"
13325 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13327 (define_insn "*ashrqi3_1_one_bit"
13328 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13329 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330 (match_operand:QI 2 "const1_operand" "")))
13331 (clobber (reg:CC FLAGS_REG))]
13332 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13335 [(set_attr "type" "ishift")
13336 (set_attr "length_immediate" "0")
13337 (set_attr "mode" "QI")])
13339 (define_insn "*ashrqi3_1_one_bit_slp"
13340 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13341 (ashiftrt:QI (match_dup 0)
13342 (match_operand:QI 1 "const1_operand" "")))
13343 (clobber (reg:CC FLAGS_REG))]
13344 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13346 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13348 [(set_attr "type" "ishift1")
13349 (set_attr "length_immediate" "0")
13350 (set_attr "mode" "QI")])
13352 (define_insn "*ashrqi3_1"
13353 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13354 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13355 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13356 (clobber (reg:CC FLAGS_REG))]
13357 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13359 sar{b}\t{%2, %0|%0, %2}
13360 sar{b}\t{%b2, %0|%0, %b2}"
13361 [(set_attr "type" "ishift")
13362 (set_attr "mode" "QI")])
13364 (define_insn "*ashrqi3_1_slp"
13365 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13366 (ashiftrt:QI (match_dup 0)
13367 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13368 (clobber (reg:CC FLAGS_REG))]
13369 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13370 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13372 sar{b}\t{%1, %0|%0, %1}
13373 sar{b}\t{%b1, %0|%0, %b1}"
13374 [(set_attr "type" "ishift1")
13375 (set_attr "mode" "QI")])
13377 ;; This pattern can't accept a variable shift count, since shifts by
13378 ;; zero don't affect the flags. We assume that shifts by constant
13379 ;; zero are optimized away.
13380 (define_insn "*ashrqi3_one_bit_cmp"
13381 [(set (reg FLAGS_REG)
13383 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13384 (match_operand:QI 2 "const1_operand" "I"))
13386 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13387 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13388 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13389 && ix86_match_ccmode (insn, CCGOCmode)
13390 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13392 [(set_attr "type" "ishift")
13393 (set_attr "length_immediate" "0")
13394 (set_attr "mode" "QI")])
13396 (define_insn "*ashrqi3_one_bit_cconly"
13397 [(set (reg FLAGS_REG)
13399 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13400 (match_operand:QI 2 "const1_operand" ""))
13402 (clobber (match_scratch:QI 0 "=q"))]
13403 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13404 && ix86_match_ccmode (insn, CCGOCmode)
13405 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13407 [(set_attr "type" "ishift")
13408 (set_attr "length_immediate" "0")
13409 (set_attr "mode" "QI")])
13411 ;; This pattern can't accept a variable shift count, since shifts by
13412 ;; zero don't affect the flags. We assume that shifts by constant
13413 ;; zero are optimized away.
13414 (define_insn "*ashrqi3_cmp"
13415 [(set (reg FLAGS_REG)
13417 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13418 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13421 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13422 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13423 && ix86_match_ccmode (insn, CCGOCmode)
13424 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13425 "sar{b}\t{%2, %0|%0, %2}"
13426 [(set_attr "type" "ishift")
13427 (set_attr "mode" "QI")])
13429 (define_insn "*ashrqi3_cconly"
13430 [(set (reg FLAGS_REG)
13432 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13433 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13435 (clobber (match_scratch:QI 0 "=q"))]
13436 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13437 && ix86_match_ccmode (insn, CCGOCmode)
13438 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13439 "sar{b}\t{%2, %0|%0, %2}"
13440 [(set_attr "type" "ishift")
13441 (set_attr "mode" "QI")])
13444 ;; Logical shift instructions
13446 ;; See comment above `ashldi3' about how this works.
13448 (define_expand "lshrti3"
13449 [(set (match_operand:TI 0 "register_operand" "")
13450 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13451 (match_operand:QI 2 "nonmemory_operand" "")))]
13453 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13455 ;; This pattern must be defined before *lshrti3_1 to prevent
13456 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13458 (define_insn "*avx_lshrti3"
13459 [(set (match_operand:TI 0 "register_operand" "=x")
13460 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13461 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13464 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13465 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13467 [(set_attr "type" "sseishft")
13468 (set_attr "prefix" "vex")
13469 (set_attr "length_immediate" "1")
13470 (set_attr "mode" "TI")])
13472 (define_insn "sse2_lshrti3"
13473 [(set (match_operand:TI 0 "register_operand" "=x")
13474 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13475 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13478 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13479 return "psrldq\t{%2, %0|%0, %2}";
13481 [(set_attr "type" "sseishft")
13482 (set_attr "prefix_data16" "1")
13483 (set_attr "length_immediate" "1")
13484 (set_attr "mode" "TI")])
13486 (define_insn "*lshrti3_1"
13487 [(set (match_operand:TI 0 "register_operand" "=r")
13488 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13489 (match_operand:QI 2 "nonmemory_operand" "Oc")))
13490 (clobber (reg:CC FLAGS_REG))]
13493 [(set_attr "type" "multi")])
13496 [(match_scratch:DI 3 "r")
13497 (parallel [(set (match_operand:TI 0 "register_operand" "")
13498 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13499 (match_operand:QI 2 "nonmemory_operand" "")))
13500 (clobber (reg:CC FLAGS_REG))])
13504 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13507 [(set (match_operand:TI 0 "register_operand" "")
13508 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13509 (match_operand:QI 2 "nonmemory_operand" "")))
13510 (clobber (reg:CC FLAGS_REG))]
13511 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13512 ? epilogue_completed : reload_completed)"
13514 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13516 (define_expand "lshrdi3"
13517 [(set (match_operand:DI 0 "shiftdi_operand" "")
13518 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13519 (match_operand:QI 2 "nonmemory_operand" "")))]
13521 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13523 (define_insn "*lshrdi3_1_one_bit_rex64"
13524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13525 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13526 (match_operand:QI 2 "const1_operand" "")))
13527 (clobber (reg:CC FLAGS_REG))]
13529 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13530 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13532 [(set_attr "type" "ishift")
13533 (set_attr "length_immediate" "0")
13534 (set_attr "mode" "DI")])
13536 (define_insn "*lshrdi3_1_rex64"
13537 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13538 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13539 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13540 (clobber (reg:CC FLAGS_REG))]
13541 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13543 shr{q}\t{%2, %0|%0, %2}
13544 shr{q}\t{%b2, %0|%0, %b2}"
13545 [(set_attr "type" "ishift")
13546 (set_attr "mode" "DI")])
13548 ;; This pattern can't accept a variable shift count, since shifts by
13549 ;; zero don't affect the flags. We assume that shifts by constant
13550 ;; zero are optimized away.
13551 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13552 [(set (reg FLAGS_REG)
13554 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13555 (match_operand:QI 2 "const1_operand" ""))
13557 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13558 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13560 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13561 && ix86_match_ccmode (insn, CCGOCmode)
13562 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13564 [(set_attr "type" "ishift")
13565 (set_attr "length_immediate" "0")
13566 (set_attr "mode" "DI")])
13568 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13569 [(set (reg FLAGS_REG)
13571 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13572 (match_operand:QI 2 "const1_operand" ""))
13574 (clobber (match_scratch:DI 0 "=r"))]
13576 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13577 && ix86_match_ccmode (insn, CCGOCmode)
13578 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13580 [(set_attr "type" "ishift")
13581 (set_attr "length_immediate" "0")
13582 (set_attr "mode" "DI")])
13584 ;; This pattern can't accept a variable shift count, since shifts by
13585 ;; zero don't affect the flags. We assume that shifts by constant
13586 ;; zero are optimized away.
13587 (define_insn "*lshrdi3_cmp_rex64"
13588 [(set (reg FLAGS_REG)
13590 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13591 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13593 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13594 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13596 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13597 && ix86_match_ccmode (insn, CCGOCmode)
13598 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13599 "shr{q}\t{%2, %0|%0, %2}"
13600 [(set_attr "type" "ishift")
13601 (set_attr "mode" "DI")])
13603 (define_insn "*lshrdi3_cconly_rex64"
13604 [(set (reg FLAGS_REG)
13606 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13607 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13609 (clobber (match_scratch:DI 0 "=r"))]
13611 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13612 && ix86_match_ccmode (insn, CCGOCmode)
13613 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13614 "shr{q}\t{%2, %0|%0, %2}"
13615 [(set_attr "type" "ishift")
13616 (set_attr "mode" "DI")])
13618 (define_insn "*lshrdi3_1"
13619 [(set (match_operand:DI 0 "register_operand" "=r")
13620 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13621 (match_operand:QI 2 "nonmemory_operand" "Jc")))
13622 (clobber (reg:CC FLAGS_REG))]
13625 [(set_attr "type" "multi")])
13627 ;; By default we don't ask for a scratch register, because when DImode
13628 ;; values are manipulated, registers are already at a premium. But if
13629 ;; we have one handy, we won't turn it away.
13631 [(match_scratch:SI 3 "r")
13632 (parallel [(set (match_operand:DI 0 "register_operand" "")
13633 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13634 (match_operand:QI 2 "nonmemory_operand" "")))
13635 (clobber (reg:CC FLAGS_REG))])
13637 "!TARGET_64BIT && TARGET_CMOVE"
13639 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13642 [(set (match_operand:DI 0 "register_operand" "")
13643 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13644 (match_operand:QI 2 "nonmemory_operand" "")))
13645 (clobber (reg:CC FLAGS_REG))]
13646 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13647 ? epilogue_completed : reload_completed)"
13649 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13651 (define_expand "lshrsi3"
13652 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13653 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13654 (match_operand:QI 2 "nonmemory_operand" "")))]
13656 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13658 (define_insn "*lshrsi3_1_one_bit"
13659 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13660 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13661 (match_operand:QI 2 "const1_operand" "")))
13662 (clobber (reg:CC FLAGS_REG))]
13663 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13664 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13666 [(set_attr "type" "ishift")
13667 (set_attr "length_immediate" "0")
13668 (set_attr "mode" "SI")])
13670 (define_insn "*lshrsi3_1_one_bit_zext"
13671 [(set (match_operand:DI 0 "register_operand" "=r")
13672 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13673 (match_operand:QI 2 "const1_operand" "")))
13674 (clobber (reg:CC FLAGS_REG))]
13676 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13679 [(set_attr "type" "ishift")
13680 (set_attr "length_immediate" "0")
13681 (set_attr "mode" "SI")])
13683 (define_insn "*lshrsi3_1"
13684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13685 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13686 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13690 shr{l}\t{%2, %0|%0, %2}
13691 shr{l}\t{%b2, %0|%0, %b2}"
13692 [(set_attr "type" "ishift")
13693 (set_attr "mode" "SI")])
13695 (define_insn "*lshrsi3_1_zext"
13696 [(set (match_operand:DI 0 "register_operand" "=r,r")
13698 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13699 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13700 (clobber (reg:CC FLAGS_REG))]
13701 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13703 shr{l}\t{%2, %k0|%k0, %2}
13704 shr{l}\t{%b2, %k0|%k0, %b2}"
13705 [(set_attr "type" "ishift")
13706 (set_attr "mode" "SI")])
13708 ;; This pattern can't accept a variable shift count, since shifts by
13709 ;; zero don't affect the flags. We assume that shifts by constant
13710 ;; zero are optimized away.
13711 (define_insn "*lshrsi3_one_bit_cmp"
13712 [(set (reg FLAGS_REG)
13714 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13715 (match_operand:QI 2 "const1_operand" ""))
13717 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13718 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13719 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720 && ix86_match_ccmode (insn, CCGOCmode)
13721 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13723 [(set_attr "type" "ishift")
13724 (set_attr "length_immediate" "0")
13725 (set_attr "mode" "SI")])
13727 (define_insn "*lshrsi3_one_bit_cconly"
13728 [(set (reg FLAGS_REG)
13730 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13731 (match_operand:QI 2 "const1_operand" ""))
13733 (clobber (match_scratch:SI 0 "=r"))]
13734 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13735 && ix86_match_ccmode (insn, CCGOCmode)
13736 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13738 [(set_attr "type" "ishift")
13739 (set_attr "length_immediate" "0")
13740 (set_attr "mode" "SI")])
13742 (define_insn "*lshrsi3_cmp_one_bit_zext"
13743 [(set (reg FLAGS_REG)
13745 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13746 (match_operand:QI 2 "const1_operand" ""))
13748 (set (match_operand:DI 0 "register_operand" "=r")
13749 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13751 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13752 && ix86_match_ccmode (insn, CCGOCmode)
13753 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13755 [(set_attr "type" "ishift")
13756 (set_attr "length_immediate" "0")
13757 (set_attr "mode" "SI")])
13759 ;; This pattern can't accept a variable shift count, since shifts by
13760 ;; zero don't affect the flags. We assume that shifts by constant
13761 ;; zero are optimized away.
13762 (define_insn "*lshrsi3_cmp"
13763 [(set (reg FLAGS_REG)
13765 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13766 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13768 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13769 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13770 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13771 && ix86_match_ccmode (insn, CCGOCmode)
13772 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13773 "shr{l}\t{%2, %0|%0, %2}"
13774 [(set_attr "type" "ishift")
13775 (set_attr "mode" "SI")])
13777 (define_insn "*lshrsi3_cconly"
13778 [(set (reg FLAGS_REG)
13780 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13781 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13783 (clobber (match_scratch:SI 0 "=r"))]
13784 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13785 && ix86_match_ccmode (insn, CCGOCmode)
13786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13787 "shr{l}\t{%2, %0|%0, %2}"
13788 [(set_attr "type" "ishift")
13789 (set_attr "mode" "SI")])
13791 (define_insn "*lshrsi3_cmp_zext"
13792 [(set (reg FLAGS_REG)
13794 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13795 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13797 (set (match_operand:DI 0 "register_operand" "=r")
13798 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13800 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13801 && ix86_match_ccmode (insn, CCGOCmode)
13802 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13803 "shr{l}\t{%2, %k0|%k0, %2}"
13804 [(set_attr "type" "ishift")
13805 (set_attr "mode" "SI")])
13807 (define_expand "lshrhi3"
13808 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13809 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13810 (match_operand:QI 2 "nonmemory_operand" "")))]
13811 "TARGET_HIMODE_MATH"
13812 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13814 (define_insn "*lshrhi3_1_one_bit"
13815 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13816 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13817 (match_operand:QI 2 "const1_operand" "")))
13818 (clobber (reg:CC FLAGS_REG))]
13819 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13820 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13822 [(set_attr "type" "ishift")
13823 (set_attr "length_immediate" "0")
13824 (set_attr "mode" "HI")])
13826 (define_insn "*lshrhi3_1"
13827 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13828 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13829 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13830 (clobber (reg:CC FLAGS_REG))]
13831 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13833 shr{w}\t{%2, %0|%0, %2}
13834 shr{w}\t{%b2, %0|%0, %b2}"
13835 [(set_attr "type" "ishift")
13836 (set_attr "mode" "HI")])
13838 ;; This pattern can't accept a variable shift count, since shifts by
13839 ;; zero don't affect the flags. We assume that shifts by constant
13840 ;; zero are optimized away.
13841 (define_insn "*lshrhi3_one_bit_cmp"
13842 [(set (reg FLAGS_REG)
13844 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13845 (match_operand:QI 2 "const1_operand" ""))
13847 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13848 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13849 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13850 && ix86_match_ccmode (insn, CCGOCmode)
13851 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13853 [(set_attr "type" "ishift")
13854 (set_attr "length_immediate" "0")
13855 (set_attr "mode" "HI")])
13857 (define_insn "*lshrhi3_one_bit_cconly"
13858 [(set (reg FLAGS_REG)
13860 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13861 (match_operand:QI 2 "const1_operand" ""))
13863 (clobber (match_scratch:HI 0 "=r"))]
13864 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13865 && ix86_match_ccmode (insn, CCGOCmode)
13866 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13868 [(set_attr "type" "ishift")
13869 (set_attr "length_immediate" "0")
13870 (set_attr "mode" "HI")])
13872 ;; This pattern can't accept a variable shift count, since shifts by
13873 ;; zero don't affect the flags. We assume that shifts by constant
13874 ;; zero are optimized away.
13875 (define_insn "*lshrhi3_cmp"
13876 [(set (reg FLAGS_REG)
13878 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13879 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13881 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13882 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13883 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13884 && ix86_match_ccmode (insn, CCGOCmode)
13885 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13886 "shr{w}\t{%2, %0|%0, %2}"
13887 [(set_attr "type" "ishift")
13888 (set_attr "mode" "HI")])
13890 (define_insn "*lshrhi3_cconly"
13891 [(set (reg FLAGS_REG)
13893 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13894 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13896 (clobber (match_scratch:HI 0 "=r"))]
13897 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13898 && ix86_match_ccmode (insn, CCGOCmode)
13899 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13900 "shr{w}\t{%2, %0|%0, %2}"
13901 [(set_attr "type" "ishift")
13902 (set_attr "mode" "HI")])
13904 (define_expand "lshrqi3"
13905 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13906 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13907 (match_operand:QI 2 "nonmemory_operand" "")))]
13908 "TARGET_QIMODE_MATH"
13909 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13911 (define_insn "*lshrqi3_1_one_bit"
13912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13913 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13914 (match_operand:QI 2 "const1_operand" "")))
13915 (clobber (reg:CC FLAGS_REG))]
13916 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13917 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13919 [(set_attr "type" "ishift")
13920 (set_attr "length_immediate" "0")
13921 (set_attr "mode" "QI")])
13923 (define_insn "*lshrqi3_1_one_bit_slp"
13924 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13925 (lshiftrt:QI (match_dup 0)
13926 (match_operand:QI 1 "const1_operand" "")))
13927 (clobber (reg:CC FLAGS_REG))]
13928 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13931 [(set_attr "type" "ishift1")
13932 (set_attr "length_immediate" "0")
13933 (set_attr "mode" "QI")])
13935 (define_insn "*lshrqi3_1"
13936 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13937 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13938 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13939 (clobber (reg:CC FLAGS_REG))]
13940 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13942 shr{b}\t{%2, %0|%0, %2}
13943 shr{b}\t{%b2, %0|%0, %b2}"
13944 [(set_attr "type" "ishift")
13945 (set_attr "mode" "QI")])
13947 (define_insn "*lshrqi3_1_slp"
13948 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13949 (lshiftrt:QI (match_dup 0)
13950 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13951 (clobber (reg:CC FLAGS_REG))]
13952 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13953 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13955 shr{b}\t{%1, %0|%0, %1}
13956 shr{b}\t{%b1, %0|%0, %b1}"
13957 [(set_attr "type" "ishift1")
13958 (set_attr "mode" "QI")])
13960 ;; This pattern can't accept a variable shift count, since shifts by
13961 ;; zero don't affect the flags. We assume that shifts by constant
13962 ;; zero are optimized away.
13963 (define_insn "*lshrqi2_one_bit_cmp"
13964 [(set (reg FLAGS_REG)
13966 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13967 (match_operand:QI 2 "const1_operand" ""))
13969 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13970 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13971 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13972 && ix86_match_ccmode (insn, CCGOCmode)
13973 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13975 [(set_attr "type" "ishift")
13976 (set_attr "length_immediate" "0")
13977 (set_attr "mode" "QI")])
13979 (define_insn "*lshrqi2_one_bit_cconly"
13980 [(set (reg FLAGS_REG)
13982 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13983 (match_operand:QI 2 "const1_operand" ""))
13985 (clobber (match_scratch:QI 0 "=q"))]
13986 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13987 && ix86_match_ccmode (insn, CCGOCmode)
13988 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13990 [(set_attr "type" "ishift")
13991 (set_attr "length_immediate" "0")
13992 (set_attr "mode" "QI")])
13994 ;; This pattern can't accept a variable shift count, since shifts by
13995 ;; zero don't affect the flags. We assume that shifts by constant
13996 ;; zero are optimized away.
13997 (define_insn "*lshrqi2_cmp"
13998 [(set (reg FLAGS_REG)
14000 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14001 (match_operand:QI 2 "const_1_to_31_operand" "I"))
14003 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14004 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
14005 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14006 && ix86_match_ccmode (insn, CCGOCmode)
14007 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14008 "shr{b}\t{%2, %0|%0, %2}"
14009 [(set_attr "type" "ishift")
14010 (set_attr "mode" "QI")])
14012 (define_insn "*lshrqi2_cconly"
14013 [(set (reg FLAGS_REG)
14015 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14016 (match_operand:QI 2 "const_1_to_31_operand" "I"))
14018 (clobber (match_scratch:QI 0 "=q"))]
14019 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14020 && ix86_match_ccmode (insn, CCGOCmode)
14021 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14022 "shr{b}\t{%2, %0|%0, %2}"
14023 [(set_attr "type" "ishift")
14024 (set_attr "mode" "QI")])
14026 ;; Rotate instructions
14028 (define_expand "rotldi3"
14029 [(set (match_operand:DI 0 "shiftdi_operand" "")
14030 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14031 (match_operand:QI 2 "nonmemory_operand" "")))]
14036 ix86_expand_binary_operator (ROTATE, DImode, operands);
14039 if (!const_1_to_31_operand (operands[2], VOIDmode))
14041 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14045 ;; Implement rotation using two double-precision shift instructions
14046 ;; and a scratch register.
14047 (define_insn_and_split "ix86_rotldi3"
14048 [(set (match_operand:DI 0 "register_operand" "=r")
14049 (rotate:DI (match_operand:DI 1 "register_operand" "0")
14050 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14051 (clobber (reg:CC FLAGS_REG))
14052 (clobber (match_scratch:SI 3 "=&r"))]
14055 "&& reload_completed"
14056 [(set (match_dup 3) (match_dup 4))
14058 [(set (match_dup 4)
14059 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14060 (lshiftrt:SI (match_dup 5)
14061 (minus:QI (const_int 32) (match_dup 2)))))
14062 (clobber (reg:CC FLAGS_REG))])
14064 [(set (match_dup 5)
14065 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14066 (lshiftrt:SI (match_dup 3)
14067 (minus:QI (const_int 32) (match_dup 2)))))
14068 (clobber (reg:CC FLAGS_REG))])]
14069 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14071 (define_insn "*rotlsi3_1_one_bit_rex64"
14072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14073 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14074 (match_operand:QI 2 "const1_operand" "")))
14075 (clobber (reg:CC FLAGS_REG))]
14077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14078 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14080 [(set_attr "type" "rotate")
14081 (set_attr "length_immediate" "0")
14082 (set_attr "mode" "DI")])
14084 (define_insn "*rotldi3_1_rex64"
14085 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14086 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14087 (match_operand:QI 2 "nonmemory_operand" "e,c")))
14088 (clobber (reg:CC FLAGS_REG))]
14089 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14091 rol{q}\t{%2, %0|%0, %2}
14092 rol{q}\t{%b2, %0|%0, %b2}"
14093 [(set_attr "type" "rotate")
14094 (set_attr "mode" "DI")])
14096 (define_expand "rotlsi3"
14097 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14098 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
14099 (match_operand:QI 2 "nonmemory_operand" "")))]
14101 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14103 (define_insn "*rotlsi3_1_one_bit"
14104 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14105 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14106 (match_operand:QI 2 "const1_operand" "")))
14107 (clobber (reg:CC FLAGS_REG))]
14108 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14109 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14111 [(set_attr "type" "rotate")
14112 (set_attr "length_immediate" "0")
14113 (set_attr "mode" "SI")])
14115 (define_insn "*rotlsi3_1_one_bit_zext"
14116 [(set (match_operand:DI 0 "register_operand" "=r")
14118 (rotate:SI (match_operand:SI 1 "register_operand" "0")
14119 (match_operand:QI 2 "const1_operand" ""))))
14120 (clobber (reg:CC FLAGS_REG))]
14122 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14123 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14125 [(set_attr "type" "rotate")
14126 (set_attr "length_immediate" "0")
14127 (set_attr "mode" "SI")])
14129 (define_insn "*rotlsi3_1"
14130 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14131 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14132 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14133 (clobber (reg:CC FLAGS_REG))]
14134 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
14136 rol{l}\t{%2, %0|%0, %2}
14137 rol{l}\t{%b2, %0|%0, %b2}"
14138 [(set_attr "type" "rotate")
14139 (set_attr "mode" "SI")])
14141 (define_insn "*rotlsi3_1_zext"
14142 [(set (match_operand:DI 0 "register_operand" "=r,r")
14144 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14145 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14146 (clobber (reg:CC FLAGS_REG))]
14147 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14149 rol{l}\t{%2, %k0|%k0, %2}
14150 rol{l}\t{%b2, %k0|%k0, %b2}"
14151 [(set_attr "type" "rotate")
14152 (set_attr "mode" "SI")])
14154 (define_expand "rotlhi3"
14155 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14156 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
14157 (match_operand:QI 2 "nonmemory_operand" "")))]
14158 "TARGET_HIMODE_MATH"
14159 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14161 (define_insn "*rotlhi3_1_one_bit"
14162 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14163 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14164 (match_operand:QI 2 "const1_operand" "")))
14165 (clobber (reg:CC FLAGS_REG))]
14166 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14167 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
14169 [(set_attr "type" "rotate")
14170 (set_attr "length_immediate" "0")
14171 (set_attr "mode" "HI")])
14173 (define_insn "*rotlhi3_1"
14174 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14175 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14176 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14177 (clobber (reg:CC FLAGS_REG))]
14178 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
14180 rol{w}\t{%2, %0|%0, %2}
14181 rol{w}\t{%b2, %0|%0, %b2}"
14182 [(set_attr "type" "rotate")
14183 (set_attr "mode" "HI")])
14186 [(set (match_operand:HI 0 "register_operand" "")
14187 (rotate:HI (match_dup 0) (const_int 8)))
14188 (clobber (reg:CC FLAGS_REG))]
14190 [(parallel [(set (strict_low_part (match_dup 0))
14191 (bswap:HI (match_dup 0)))
14192 (clobber (reg:CC FLAGS_REG))])]
14195 (define_expand "rotlqi3"
14196 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14197 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
14198 (match_operand:QI 2 "nonmemory_operand" "")))]
14199 "TARGET_QIMODE_MATH"
14200 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14202 (define_insn "*rotlqi3_1_one_bit_slp"
14203 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14204 (rotate:QI (match_dup 0)
14205 (match_operand:QI 1 "const1_operand" "")))
14206 (clobber (reg:CC FLAGS_REG))]
14207 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14208 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14210 [(set_attr "type" "rotate1")
14211 (set_attr "length_immediate" "0")
14212 (set_attr "mode" "QI")])
14214 (define_insn "*rotlqi3_1_one_bit"
14215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14216 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14217 (match_operand:QI 2 "const1_operand" "")))
14218 (clobber (reg:CC FLAGS_REG))]
14219 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14220 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
14222 [(set_attr "type" "rotate")
14223 (set_attr "length_immediate" "0")
14224 (set_attr "mode" "QI")])
14226 (define_insn "*rotlqi3_1_slp"
14227 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14228 (rotate:QI (match_dup 0)
14229 (match_operand:QI 1 "nonmemory_operand" "I,c")))
14230 (clobber (reg:CC FLAGS_REG))]
14231 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14232 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14234 rol{b}\t{%1, %0|%0, %1}
14235 rol{b}\t{%b1, %0|%0, %b1}"
14236 [(set_attr "type" "rotate1")
14237 (set_attr "mode" "QI")])
14239 (define_insn "*rotlqi3_1"
14240 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14241 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14242 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14243 (clobber (reg:CC FLAGS_REG))]
14244 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
14246 rol{b}\t{%2, %0|%0, %2}
14247 rol{b}\t{%b2, %0|%0, %b2}"
14248 [(set_attr "type" "rotate")
14249 (set_attr "mode" "QI")])
14251 (define_expand "rotrdi3"
14252 [(set (match_operand:DI 0 "shiftdi_operand" "")
14253 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14254 (match_operand:QI 2 "nonmemory_operand" "")))]
14259 ix86_expand_binary_operator (ROTATERT, DImode, operands);
14262 if (!const_1_to_31_operand (operands[2], VOIDmode))
14264 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14268 ;; Implement rotation using two double-precision shift instructions
14269 ;; and a scratch register.
14270 (define_insn_and_split "ix86_rotrdi3"
14271 [(set (match_operand:DI 0 "register_operand" "=r")
14272 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14273 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14274 (clobber (reg:CC FLAGS_REG))
14275 (clobber (match_scratch:SI 3 "=&r"))]
14278 "&& reload_completed"
14279 [(set (match_dup 3) (match_dup 4))
14281 [(set (match_dup 4)
14282 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14283 (ashift:SI (match_dup 5)
14284 (minus:QI (const_int 32) (match_dup 2)))))
14285 (clobber (reg:CC FLAGS_REG))])
14287 [(set (match_dup 5)
14288 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14289 (ashift:SI (match_dup 3)
14290 (minus:QI (const_int 32) (match_dup 2)))))
14291 (clobber (reg:CC FLAGS_REG))])]
14292 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14294 (define_insn "*rotrdi3_1_one_bit_rex64"
14295 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14296 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14297 (match_operand:QI 2 "const1_operand" "")))
14298 (clobber (reg:CC FLAGS_REG))]
14300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14301 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14303 [(set_attr "type" "rotate")
14304 (set_attr "length_immediate" "0")
14305 (set_attr "mode" "DI")])
14307 (define_insn "*rotrdi3_1_rex64"
14308 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14309 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14310 (match_operand:QI 2 "nonmemory_operand" "J,c")))
14311 (clobber (reg:CC FLAGS_REG))]
14312 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14314 ror{q}\t{%2, %0|%0, %2}
14315 ror{q}\t{%b2, %0|%0, %b2}"
14316 [(set_attr "type" "rotate")
14317 (set_attr "mode" "DI")])
14319 (define_expand "rotrsi3"
14320 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14321 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
14322 (match_operand:QI 2 "nonmemory_operand" "")))]
14324 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14326 (define_insn "*rotrsi3_1_one_bit"
14327 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14328 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14329 (match_operand:QI 2 "const1_operand" "")))
14330 (clobber (reg:CC FLAGS_REG))]
14331 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14332 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14334 [(set_attr "type" "rotate")
14335 (set_attr "length_immediate" "0")
14336 (set_attr "mode" "SI")])
14338 (define_insn "*rotrsi3_1_one_bit_zext"
14339 [(set (match_operand:DI 0 "register_operand" "=r")
14341 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
14342 (match_operand:QI 2 "const1_operand" ""))))
14343 (clobber (reg:CC FLAGS_REG))]
14345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14346 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14348 [(set_attr "type" "rotate")
14349 (set_attr "length_immediate" "0")
14350 (set_attr "mode" "SI")])
14352 (define_insn "*rotrsi3_1"
14353 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14354 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14355 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14356 (clobber (reg:CC FLAGS_REG))]
14357 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14359 ror{l}\t{%2, %0|%0, %2}
14360 ror{l}\t{%b2, %0|%0, %b2}"
14361 [(set_attr "type" "rotate")
14362 (set_attr "mode" "SI")])
14364 (define_insn "*rotrsi3_1_zext"
14365 [(set (match_operand:DI 0 "register_operand" "=r,r")
14367 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14368 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14369 (clobber (reg:CC FLAGS_REG))]
14370 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14372 ror{l}\t{%2, %k0|%k0, %2}
14373 ror{l}\t{%b2, %k0|%k0, %b2}"
14374 [(set_attr "type" "rotate")
14375 (set_attr "mode" "SI")])
14377 (define_expand "rotrhi3"
14378 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14379 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14380 (match_operand:QI 2 "nonmemory_operand" "")))]
14381 "TARGET_HIMODE_MATH"
14382 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14384 (define_insn "*rotrhi3_one_bit"
14385 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14386 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14387 (match_operand:QI 2 "const1_operand" "")))
14388 (clobber (reg:CC FLAGS_REG))]
14389 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14390 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14392 [(set_attr "type" "rotate")
14393 (set_attr "length_immediate" "0")
14394 (set_attr "mode" "HI")])
14396 (define_insn "*rotrhi3_1"
14397 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14398 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14399 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14400 (clobber (reg:CC FLAGS_REG))]
14401 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14403 ror{w}\t{%2, %0|%0, %2}
14404 ror{w}\t{%b2, %0|%0, %b2}"
14405 [(set_attr "type" "rotate")
14406 (set_attr "mode" "HI")])
14409 [(set (match_operand:HI 0 "register_operand" "")
14410 (rotatert:HI (match_dup 0) (const_int 8)))
14411 (clobber (reg:CC FLAGS_REG))]
14413 [(parallel [(set (strict_low_part (match_dup 0))
14414 (bswap:HI (match_dup 0)))
14415 (clobber (reg:CC FLAGS_REG))])]
14418 (define_expand "rotrqi3"
14419 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14420 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14421 (match_operand:QI 2 "nonmemory_operand" "")))]
14422 "TARGET_QIMODE_MATH"
14423 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14425 (define_insn "*rotrqi3_1_one_bit"
14426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14427 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14428 (match_operand:QI 2 "const1_operand" "")))
14429 (clobber (reg:CC FLAGS_REG))]
14430 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14431 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14433 [(set_attr "type" "rotate")
14434 (set_attr "length_immediate" "0")
14435 (set_attr "mode" "QI")])
14437 (define_insn "*rotrqi3_1_one_bit_slp"
14438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14439 (rotatert:QI (match_dup 0)
14440 (match_operand:QI 1 "const1_operand" "")))
14441 (clobber (reg:CC FLAGS_REG))]
14442 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14443 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14445 [(set_attr "type" "rotate1")
14446 (set_attr "length_immediate" "0")
14447 (set_attr "mode" "QI")])
14449 (define_insn "*rotrqi3_1"
14450 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14451 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14452 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14453 (clobber (reg:CC FLAGS_REG))]
14454 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14456 ror{b}\t{%2, %0|%0, %2}
14457 ror{b}\t{%b2, %0|%0, %b2}"
14458 [(set_attr "type" "rotate")
14459 (set_attr "mode" "QI")])
14461 (define_insn "*rotrqi3_1_slp"
14462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14463 (rotatert:QI (match_dup 0)
14464 (match_operand:QI 1 "nonmemory_operand" "I,c")))
14465 (clobber (reg:CC FLAGS_REG))]
14466 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14467 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14469 ror{b}\t{%1, %0|%0, %1}
14470 ror{b}\t{%b1, %0|%0, %b1}"
14471 [(set_attr "type" "rotate1")
14472 (set_attr "mode" "QI")])
14474 ;; Bit set / bit test instructions
14476 (define_expand "extv"
14477 [(set (match_operand:SI 0 "register_operand" "")
14478 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14479 (match_operand:SI 2 "const8_operand" "")
14480 (match_operand:SI 3 "const8_operand" "")))]
14483 /* Handle extractions from %ah et al. */
14484 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14487 /* From mips.md: extract_bit_field doesn't verify that our source
14488 matches the predicate, so check it again here. */
14489 if (! ext_register_operand (operands[1], VOIDmode))
14493 (define_expand "extzv"
14494 [(set (match_operand:SI 0 "register_operand" "")
14495 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14496 (match_operand:SI 2 "const8_operand" "")
14497 (match_operand:SI 3 "const8_operand" "")))]
14500 /* Handle extractions from %ah et al. */
14501 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14504 /* From mips.md: extract_bit_field doesn't verify that our source
14505 matches the predicate, so check it again here. */
14506 if (! ext_register_operand (operands[1], VOIDmode))
14510 (define_expand "insv"
14511 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14512 (match_operand 1 "const8_operand" "")
14513 (match_operand 2 "const8_operand" ""))
14514 (match_operand 3 "register_operand" ""))]
14517 /* Handle insertions to %ah et al. */
14518 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14521 /* From mips.md: insert_bit_field doesn't verify that our source
14522 matches the predicate, so check it again here. */
14523 if (! ext_register_operand (operands[0], VOIDmode))
14527 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14529 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14534 ;; %%% bts, btr, btc, bt.
14535 ;; In general these instructions are *slow* when applied to memory,
14536 ;; since they enforce atomic operation. When applied to registers,
14537 ;; it depends on the cpu implementation. They're never faster than
14538 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14539 ;; no point. But in 64-bit, we can't hold the relevant immediates
14540 ;; within the instruction itself, so operating on bits in the high
14541 ;; 32-bits of a register becomes easier.
14543 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
14544 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14545 ;; negdf respectively, so they can never be disabled entirely.
14547 (define_insn "*btsq"
14548 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14550 (match_operand:DI 1 "const_0_to_63_operand" ""))
14552 (clobber (reg:CC FLAGS_REG))]
14553 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14554 "bts{q}\t{%1, %0|%0, %1}"
14555 [(set_attr "type" "alu1")
14556 (set_attr "prefix_0f" "1")
14557 (set_attr "mode" "DI")])
14559 (define_insn "*btrq"
14560 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14562 (match_operand:DI 1 "const_0_to_63_operand" ""))
14564 (clobber (reg:CC FLAGS_REG))]
14565 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14566 "btr{q}\t{%1, %0|%0, %1}"
14567 [(set_attr "type" "alu1")
14568 (set_attr "prefix_0f" "1")
14569 (set_attr "mode" "DI")])
14571 (define_insn "*btcq"
14572 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14574 (match_operand:DI 1 "const_0_to_63_operand" ""))
14575 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14576 (clobber (reg:CC FLAGS_REG))]
14577 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14578 "btc{q}\t{%1, %0|%0, %1}"
14579 [(set_attr "type" "alu1")
14580 (set_attr "prefix_0f" "1")
14581 (set_attr "mode" "DI")])
14583 ;; Allow Nocona to avoid these instructions if a register is available.
14586 [(match_scratch:DI 2 "r")
14587 (parallel [(set (zero_extract:DI
14588 (match_operand:DI 0 "register_operand" "")
14590 (match_operand:DI 1 "const_0_to_63_operand" ""))
14592 (clobber (reg:CC FLAGS_REG))])]
14593 "TARGET_64BIT && !TARGET_USE_BT"
14596 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14599 if (HOST_BITS_PER_WIDE_INT >= 64)
14600 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14601 else if (i < HOST_BITS_PER_WIDE_INT)
14602 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14604 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14606 op1 = immed_double_const (lo, hi, DImode);
14609 emit_move_insn (operands[2], op1);
14613 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14618 [(match_scratch:DI 2 "r")
14619 (parallel [(set (zero_extract:DI
14620 (match_operand:DI 0 "register_operand" "")
14622 (match_operand:DI 1 "const_0_to_63_operand" ""))
14624 (clobber (reg:CC FLAGS_REG))])]
14625 "TARGET_64BIT && !TARGET_USE_BT"
14628 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14631 if (HOST_BITS_PER_WIDE_INT >= 64)
14632 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14633 else if (i < HOST_BITS_PER_WIDE_INT)
14634 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14636 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14638 op1 = immed_double_const (~lo, ~hi, DImode);
14641 emit_move_insn (operands[2], op1);
14645 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14650 [(match_scratch:DI 2 "r")
14651 (parallel [(set (zero_extract:DI
14652 (match_operand:DI 0 "register_operand" "")
14654 (match_operand:DI 1 "const_0_to_63_operand" ""))
14655 (not:DI (zero_extract:DI
14656 (match_dup 0) (const_int 1) (match_dup 1))))
14657 (clobber (reg:CC FLAGS_REG))])]
14658 "TARGET_64BIT && !TARGET_USE_BT"
14661 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14664 if (HOST_BITS_PER_WIDE_INT >= 64)
14665 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14666 else if (i < HOST_BITS_PER_WIDE_INT)
14667 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14669 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14671 op1 = immed_double_const (lo, hi, DImode);
14674 emit_move_insn (operands[2], op1);
14678 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14682 (define_insn "*btdi_rex64"
14683 [(set (reg:CCC FLAGS_REG)
14686 (match_operand:DI 0 "register_operand" "r")
14688 (match_operand:DI 1 "nonmemory_operand" "rN"))
14690 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14691 "bt{q}\t{%1, %0|%0, %1}"
14692 [(set_attr "type" "alu1")
14693 (set_attr "prefix_0f" "1")
14694 (set_attr "mode" "DI")])
14696 (define_insn "*btsi"
14697 [(set (reg:CCC FLAGS_REG)
14700 (match_operand:SI 0 "register_operand" "r")
14702 (match_operand:SI 1 "nonmemory_operand" "rN"))
14704 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14705 "bt{l}\t{%1, %0|%0, %1}"
14706 [(set_attr "type" "alu1")
14707 (set_attr "prefix_0f" "1")
14708 (set_attr "mode" "SI")])
14710 ;; Store-flag instructions.
14712 ;; For all sCOND expanders, also expand the compare or test insn that
14713 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14715 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14716 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14717 ;; way, which can later delete the movzx if only QImode is needed.
14719 (define_insn "*setcc_1"
14720 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14721 (match_operator:QI 1 "ix86_comparison_operator"
14722 [(reg FLAGS_REG) (const_int 0)]))]
14725 [(set_attr "type" "setcc")
14726 (set_attr "mode" "QI")])
14728 (define_insn "*setcc_2"
14729 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14730 (match_operator:QI 1 "ix86_comparison_operator"
14731 [(reg FLAGS_REG) (const_int 0)]))]
14734 [(set_attr "type" "setcc")
14735 (set_attr "mode" "QI")])
14737 ;; In general it is not safe to assume too much about CCmode registers,
14738 ;; so simplify-rtx stops when it sees a second one. Under certain
14739 ;; conditions this is safe on x86, so help combine not create
14746 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14747 (ne:QI (match_operator 1 "ix86_comparison_operator"
14748 [(reg FLAGS_REG) (const_int 0)])
14751 [(set (match_dup 0) (match_dup 1))]
14753 PUT_MODE (operands[1], QImode);
14757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14758 (ne:QI (match_operator 1 "ix86_comparison_operator"
14759 [(reg FLAGS_REG) (const_int 0)])
14762 [(set (match_dup 0) (match_dup 1))]
14764 PUT_MODE (operands[1], QImode);
14768 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14769 (eq:QI (match_operator 1 "ix86_comparison_operator"
14770 [(reg FLAGS_REG) (const_int 0)])
14773 [(set (match_dup 0) (match_dup 1))]
14775 rtx new_op1 = copy_rtx (operands[1]);
14776 operands[1] = new_op1;
14777 PUT_MODE (new_op1, QImode);
14778 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14779 GET_MODE (XEXP (new_op1, 0))));
14781 /* Make sure that (a) the CCmode we have for the flags is strong
14782 enough for the reversed compare or (b) we have a valid FP compare. */
14783 if (! ix86_comparison_operator (new_op1, VOIDmode))
14788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14789 (eq:QI (match_operator 1 "ix86_comparison_operator"
14790 [(reg FLAGS_REG) (const_int 0)])
14793 [(set (match_dup 0) (match_dup 1))]
14795 rtx new_op1 = copy_rtx (operands[1]);
14796 operands[1] = new_op1;
14797 PUT_MODE (new_op1, QImode);
14798 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14799 GET_MODE (XEXP (new_op1, 0))));
14801 /* Make sure that (a) the CCmode we have for the flags is strong
14802 enough for the reversed compare or (b) we have a valid FP compare. */
14803 if (! ix86_comparison_operator (new_op1, VOIDmode))
14807 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14808 ;; subsequent logical operations are used to imitate conditional moves.
14809 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14812 (define_insn "*avx_setcc<mode>"
14813 [(set (match_operand:MODEF 0 "register_operand" "=x")
14814 (match_operator:MODEF 1 "avx_comparison_float_operator"
14815 [(match_operand:MODEF 2 "register_operand" "x")
14816 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14818 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14819 [(set_attr "type" "ssecmp")
14820 (set_attr "prefix" "vex")
14821 (set_attr "length_immediate" "1")
14822 (set_attr "mode" "<MODE>")])
14824 (define_insn "*sse_setcc<mode>"
14825 [(set (match_operand:MODEF 0 "register_operand" "=x")
14826 (match_operator:MODEF 1 "sse_comparison_operator"
14827 [(match_operand:MODEF 2 "register_operand" "0")
14828 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14829 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14830 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14831 [(set_attr "type" "ssecmp")
14832 (set_attr "length_immediate" "1")
14833 (set_attr "mode" "<MODE>")])
14835 (define_insn "*sse5_setcc<mode>"
14836 [(set (match_operand:MODEF 0 "register_operand" "=x")
14837 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14838 [(match_operand:MODEF 2 "register_operand" "x")
14839 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14841 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14842 [(set_attr "type" "sse4arg")
14843 (set_attr "length_immediate" "1")
14844 (set_attr "mode" "<MODE>")])
14847 ;; Basic conditional jump instructions.
14848 ;; We ignore the overflow flag for signed branch instructions.
14850 (define_insn "*jcc_1"
14852 (if_then_else (match_operator 1 "ix86_comparison_operator"
14853 [(reg FLAGS_REG) (const_int 0)])
14854 (label_ref (match_operand 0 "" ""))
14858 [(set_attr "type" "ibr")
14859 (set_attr "modrm" "0")
14860 (set (attr "length")
14861 (if_then_else (and (ge (minus (match_dup 0) (pc))
14863 (lt (minus (match_dup 0) (pc))
14868 (define_insn "*jcc_2"
14870 (if_then_else (match_operator 1 "ix86_comparison_operator"
14871 [(reg FLAGS_REG) (const_int 0)])
14873 (label_ref (match_operand 0 "" ""))))]
14876 [(set_attr "type" "ibr")
14877 (set_attr "modrm" "0")
14878 (set (attr "length")
14879 (if_then_else (and (ge (minus (match_dup 0) (pc))
14881 (lt (minus (match_dup 0) (pc))
14886 ;; In general it is not safe to assume too much about CCmode registers,
14887 ;; so simplify-rtx stops when it sees a second one. Under certain
14888 ;; conditions this is safe on x86, so help combine not create
14896 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14897 [(reg FLAGS_REG) (const_int 0)])
14899 (label_ref (match_operand 1 "" ""))
14903 (if_then_else (match_dup 0)
14904 (label_ref (match_dup 1))
14907 PUT_MODE (operands[0], VOIDmode);
14912 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14913 [(reg FLAGS_REG) (const_int 0)])
14915 (label_ref (match_operand 1 "" ""))
14919 (if_then_else (match_dup 0)
14920 (label_ref (match_dup 1))
14923 rtx new_op0 = copy_rtx (operands[0]);
14924 operands[0] = new_op0;
14925 PUT_MODE (new_op0, VOIDmode);
14926 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14927 GET_MODE (XEXP (new_op0, 0))));
14929 /* Make sure that (a) the CCmode we have for the flags is strong
14930 enough for the reversed compare or (b) we have a valid FP compare. */
14931 if (! ix86_comparison_operator (new_op0, VOIDmode))
14935 ;; zero_extend in SImode is correct, since this is what combine pass
14936 ;; generates from shift insn with QImode operand. Actually, the mode of
14937 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14938 ;; appropriate modulo of the bit offset value.
14940 (define_insn_and_split "*jcc_btdi_rex64"
14942 (if_then_else (match_operator 0 "bt_comparison_operator"
14944 (match_operand:DI 1 "register_operand" "r")
14947 (match_operand:QI 2 "register_operand" "r")))
14949 (label_ref (match_operand 3 "" ""))
14951 (clobber (reg:CC FLAGS_REG))]
14952 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14955 [(set (reg:CCC FLAGS_REG)
14963 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14964 (label_ref (match_dup 3))
14967 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14969 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14972 ;; avoid useless masking of bit offset operand
14973 (define_insn_and_split "*jcc_btdi_mask_rex64"
14975 (if_then_else (match_operator 0 "bt_comparison_operator"
14977 (match_operand:DI 1 "register_operand" "r")
14980 (match_operand:SI 2 "register_operand" "r")
14981 (match_operand:SI 3 "const_int_operand" "n")))])
14982 (label_ref (match_operand 4 "" ""))
14984 (clobber (reg:CC FLAGS_REG))]
14985 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14986 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14989 [(set (reg:CCC FLAGS_REG)
14997 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14998 (label_ref (match_dup 4))
15001 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
15003 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15006 (define_insn_and_split "*jcc_btsi"
15008 (if_then_else (match_operator 0 "bt_comparison_operator"
15010 (match_operand:SI 1 "register_operand" "r")
15013 (match_operand:QI 2 "register_operand" "r")))
15015 (label_ref (match_operand 3 "" ""))
15017 (clobber (reg:CC FLAGS_REG))]
15018 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15021 [(set (reg:CCC FLAGS_REG)
15029 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15030 (label_ref (match_dup 3))
15033 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15035 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15038 ;; avoid useless masking of bit offset operand
15039 (define_insn_and_split "*jcc_btsi_mask"
15041 (if_then_else (match_operator 0 "bt_comparison_operator"
15043 (match_operand:SI 1 "register_operand" "r")
15046 (match_operand:SI 2 "register_operand" "r")
15047 (match_operand:SI 3 "const_int_operand" "n")))])
15048 (label_ref (match_operand 4 "" ""))
15050 (clobber (reg:CC FLAGS_REG))]
15051 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15052 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15055 [(set (reg:CCC FLAGS_REG)
15063 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15064 (label_ref (match_dup 4))
15066 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15068 (define_insn_and_split "*jcc_btsi_1"
15070 (if_then_else (match_operator 0 "bt_comparison_operator"
15073 (match_operand:SI 1 "register_operand" "r")
15074 (match_operand:QI 2 "register_operand" "r"))
15077 (label_ref (match_operand 3 "" ""))
15079 (clobber (reg:CC FLAGS_REG))]
15080 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15083 [(set (reg:CCC FLAGS_REG)
15091 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15092 (label_ref (match_dup 3))
15095 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15097 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15100 ;; avoid useless masking of bit offset operand
15101 (define_insn_and_split "*jcc_btsi_mask_1"
15104 (match_operator 0 "bt_comparison_operator"
15107 (match_operand:SI 1 "register_operand" "r")
15110 (match_operand:SI 2 "register_operand" "r")
15111 (match_operand:SI 3 "const_int_operand" "n")) 0))
15114 (label_ref (match_operand 4 "" ""))
15116 (clobber (reg:CC FLAGS_REG))]
15117 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15118 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15121 [(set (reg:CCC FLAGS_REG)
15129 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15130 (label_ref (match_dup 4))
15132 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15134 ;; Define combination compare-and-branch fp compare instructions to help
15137 (define_insn "*fp_jcc_3_387"
15139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15140 [(match_operand 1 "register_operand" "f")
15141 (match_operand 2 "nonimmediate_operand" "fm")])
15142 (label_ref (match_operand 3 "" ""))
15144 (clobber (reg:CCFP FPSR_REG))
15145 (clobber (reg:CCFP FLAGS_REG))
15146 (clobber (match_scratch:HI 4 "=a"))]
15148 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15149 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15150 && SELECT_CC_MODE (GET_CODE (operands[0]),
15151 operands[1], operands[2]) == CCFPmode
15155 (define_insn "*fp_jcc_4_387"
15157 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15158 [(match_operand 1 "register_operand" "f")
15159 (match_operand 2 "nonimmediate_operand" "fm")])
15161 (label_ref (match_operand 3 "" ""))))
15162 (clobber (reg:CCFP FPSR_REG))
15163 (clobber (reg:CCFP FLAGS_REG))
15164 (clobber (match_scratch:HI 4 "=a"))]
15166 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15167 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15168 && SELECT_CC_MODE (GET_CODE (operands[0]),
15169 operands[1], operands[2]) == CCFPmode
15173 (define_insn "*fp_jcc_5_387"
15175 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15176 [(match_operand 1 "register_operand" "f")
15177 (match_operand 2 "register_operand" "f")])
15178 (label_ref (match_operand 3 "" ""))
15180 (clobber (reg:CCFP FPSR_REG))
15181 (clobber (reg:CCFP FLAGS_REG))
15182 (clobber (match_scratch:HI 4 "=a"))]
15183 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15184 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15188 (define_insn "*fp_jcc_6_387"
15190 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15191 [(match_operand 1 "register_operand" "f")
15192 (match_operand 2 "register_operand" "f")])
15194 (label_ref (match_operand 3 "" ""))))
15195 (clobber (reg:CCFP FPSR_REG))
15196 (clobber (reg:CCFP FLAGS_REG))
15197 (clobber (match_scratch:HI 4 "=a"))]
15198 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15199 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15203 (define_insn "*fp_jcc_7_387"
15205 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15206 [(match_operand 1 "register_operand" "f")
15207 (match_operand 2 "const0_operand" "")])
15208 (label_ref (match_operand 3 "" ""))
15210 (clobber (reg:CCFP FPSR_REG))
15211 (clobber (reg:CCFP FLAGS_REG))
15212 (clobber (match_scratch:HI 4 "=a"))]
15213 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15214 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15215 && SELECT_CC_MODE (GET_CODE (operands[0]),
15216 operands[1], operands[2]) == CCFPmode
15220 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
15221 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15222 ;; with a precedence over other operators and is always put in the first
15223 ;; place. Swap condition and operands to match ficom instruction.
15225 (define_insn "*fp_jcc_8<mode>_387"
15227 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15228 [(match_operator 1 "float_operator"
15229 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
15230 (match_operand 3 "register_operand" "f,f")])
15231 (label_ref (match_operand 4 "" ""))
15233 (clobber (reg:CCFP FPSR_REG))
15234 (clobber (reg:CCFP FLAGS_REG))
15235 (clobber (match_scratch:HI 5 "=a,a"))]
15236 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
15237 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
15238 && GET_MODE (operands[1]) == GET_MODE (operands[3])
15239 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15245 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15246 [(match_operand 1 "register_operand" "")
15247 (match_operand 2 "nonimmediate_operand" "")])
15248 (match_operand 3 "" "")
15249 (match_operand 4 "" "")))
15250 (clobber (reg:CCFP FPSR_REG))
15251 (clobber (reg:CCFP FLAGS_REG))]
15255 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15256 operands[3], operands[4], NULL_RTX, NULL_RTX);
15262 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15263 [(match_operand 1 "register_operand" "")
15264 (match_operand 2 "general_operand" "")])
15265 (match_operand 3 "" "")
15266 (match_operand 4 "" "")))
15267 (clobber (reg:CCFP FPSR_REG))
15268 (clobber (reg:CCFP FLAGS_REG))
15269 (clobber (match_scratch:HI 5 "=a"))]
15273 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15274 operands[3], operands[4], operands[5], NULL_RTX);
15280 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15281 [(match_operator 1 "float_operator"
15282 [(match_operand:X87MODEI12 2 "memory_operand" "")])
15283 (match_operand 3 "register_operand" "")])
15284 (match_operand 4 "" "")
15285 (match_operand 5 "" "")))
15286 (clobber (reg:CCFP FPSR_REG))
15287 (clobber (reg:CCFP FLAGS_REG))
15288 (clobber (match_scratch:HI 6 "=a"))]
15292 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15293 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15294 operands[3], operands[7],
15295 operands[4], operands[5], operands[6], NULL_RTX);
15299 ;; %%% Kill this when reload knows how to do it.
15302 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15303 [(match_operator 1 "float_operator"
15304 [(match_operand:X87MODEI12 2 "register_operand" "")])
15305 (match_operand 3 "register_operand" "")])
15306 (match_operand 4 "" "")
15307 (match_operand 5 "" "")))
15308 (clobber (reg:CCFP FPSR_REG))
15309 (clobber (reg:CCFP FLAGS_REG))
15310 (clobber (match_scratch:HI 6 "=a"))]
15314 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15315 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15316 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15317 operands[3], operands[7],
15318 operands[4], operands[5], operands[6], operands[2]);
15322 ;; Unconditional and other jump instructions
15324 (define_insn "jump"
15326 (label_ref (match_operand 0 "" "")))]
15329 [(set_attr "type" "ibr")
15330 (set (attr "length")
15331 (if_then_else (and (ge (minus (match_dup 0) (pc))
15333 (lt (minus (match_dup 0) (pc))
15337 (set_attr "modrm" "0")])
15339 (define_expand "indirect_jump"
15340 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15344 (define_insn "*indirect_jump"
15345 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15348 [(set_attr "type" "ibr")
15349 (set_attr "length_immediate" "0")])
15351 (define_expand "tablejump"
15352 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15353 (use (label_ref (match_operand 1 "" "")))])]
15356 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15357 relative. Convert the relative address to an absolute address. */
15361 enum rtx_code code;
15363 /* We can't use @GOTOFF for text labels on VxWorks;
15364 see gotoff_operand. */
15365 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15369 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15371 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15375 op1 = pic_offset_table_rtx;
15380 op0 = pic_offset_table_rtx;
15384 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15389 (define_insn "*tablejump_1"
15390 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15391 (use (label_ref (match_operand 1 "" "")))]
15394 [(set_attr "type" "ibr")
15395 (set_attr "length_immediate" "0")])
15397 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15400 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15401 (set (match_operand:QI 1 "register_operand" "")
15402 (match_operator:QI 2 "ix86_comparison_operator"
15403 [(reg FLAGS_REG) (const_int 0)]))
15404 (set (match_operand 3 "q_regs_operand" "")
15405 (zero_extend (match_dup 1)))]
15406 "(peep2_reg_dead_p (3, operands[1])
15407 || operands_match_p (operands[1], operands[3]))
15408 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15409 [(set (match_dup 4) (match_dup 0))
15410 (set (strict_low_part (match_dup 5))
15413 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15414 operands[5] = gen_lowpart (QImode, operands[3]);
15415 ix86_expand_clear (operands[3]);
15418 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15421 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15422 (set (match_operand:QI 1 "register_operand" "")
15423 (match_operator:QI 2 "ix86_comparison_operator"
15424 [(reg FLAGS_REG) (const_int 0)]))
15425 (parallel [(set (match_operand 3 "q_regs_operand" "")
15426 (zero_extend (match_dup 1)))
15427 (clobber (reg:CC FLAGS_REG))])]
15428 "(peep2_reg_dead_p (3, operands[1])
15429 || operands_match_p (operands[1], operands[3]))
15430 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15431 [(set (match_dup 4) (match_dup 0))
15432 (set (strict_low_part (match_dup 5))
15435 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15436 operands[5] = gen_lowpart (QImode, operands[3]);
15437 ix86_expand_clear (operands[3]);
15440 ;; Call instructions.
15442 ;; The predicates normally associated with named expanders are not properly
15443 ;; checked for calls. This is a bug in the generic code, but it isn't that
15444 ;; easy to fix. Ignore it for now and be prepared to fix things up.
15446 ;; Call subroutine returning no value.
15448 (define_expand "call_pop"
15449 [(parallel [(call (match_operand:QI 0 "" "")
15450 (match_operand:SI 1 "" ""))
15451 (set (reg:SI SP_REG)
15452 (plus:SI (reg:SI SP_REG)
15453 (match_operand:SI 3 "" "")))])]
15456 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15460 (define_insn "*call_pop_0"
15461 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15462 (match_operand:SI 1 "" ""))
15463 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15464 (match_operand:SI 2 "immediate_operand" "")))]
15467 if (SIBLING_CALL_P (insn))
15470 return "call\t%P0";
15472 [(set_attr "type" "call")])
15474 (define_insn "*call_pop_1"
15475 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15476 (match_operand:SI 1 "" ""))
15477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15478 (match_operand:SI 2 "immediate_operand" "i")))]
15481 if (constant_call_address_operand (operands[0], Pmode))
15483 if (SIBLING_CALL_P (insn))
15486 return "call\t%P0";
15488 if (SIBLING_CALL_P (insn))
15491 return "call\t%A0";
15493 [(set_attr "type" "call")])
15495 (define_expand "call"
15496 [(call (match_operand:QI 0 "" "")
15497 (match_operand 1 "" ""))
15498 (use (match_operand 2 "" ""))]
15501 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15505 (define_expand "sibcall"
15506 [(call (match_operand:QI 0 "" "")
15507 (match_operand 1 "" ""))
15508 (use (match_operand 2 "" ""))]
15511 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15515 (define_insn "*call_0"
15516 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15517 (match_operand 1 "" ""))]
15520 if (SIBLING_CALL_P (insn))
15523 return "call\t%P0";
15525 [(set_attr "type" "call")])
15527 (define_insn "*call_1"
15528 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15529 (match_operand 1 "" ""))]
15530 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15532 if (constant_call_address_operand (operands[0], Pmode))
15533 return "call\t%P0";
15534 return "call\t%A0";
15536 [(set_attr "type" "call")])
15538 (define_insn "*sibcall_1"
15539 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15540 (match_operand 1 "" ""))]
15541 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15545 [(set_attr "type" "call")])
15547 (define_insn "*call_1_rex64"
15548 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15549 (match_operand 1 "" ""))]
15550 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15551 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15553 if (constant_call_address_operand (operands[0], Pmode))
15554 return "call\t%P0";
15555 return "call\t%A0";
15557 [(set_attr "type" "call")])
15559 (define_insn "*call_1_rex64_ms_sysv"
15560 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15561 (match_operand 1 "" ""))
15562 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15563 (clobber (reg:TI XMM6_REG))
15564 (clobber (reg:TI XMM7_REG))
15565 (clobber (reg:TI XMM8_REG))
15566 (clobber (reg:TI XMM9_REG))
15567 (clobber (reg:TI XMM10_REG))
15568 (clobber (reg:TI XMM11_REG))
15569 (clobber (reg:TI XMM12_REG))
15570 (clobber (reg:TI XMM13_REG))
15571 (clobber (reg:TI XMM14_REG))
15572 (clobber (reg:TI XMM15_REG))
15573 (clobber (reg:DI SI_REG))
15574 (clobber (reg:DI DI_REG))]
15575 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15577 if (constant_call_address_operand (operands[0], Pmode))
15578 return "call\t%P0";
15579 return "call\t%A0";
15581 [(set_attr "type" "call")])
15583 (define_insn "*call_1_rex64_large"
15584 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15585 (match_operand 1 "" ""))]
15586 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15588 [(set_attr "type" "call")])
15590 (define_insn "*sibcall_1_rex64"
15591 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15592 (match_operand 1 "" ""))]
15593 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15597 [(set_attr "type" "call")])
15599 ;; Call subroutine, returning value in operand 0
15600 (define_expand "call_value_pop"
15601 [(parallel [(set (match_operand 0 "" "")
15602 (call (match_operand:QI 1 "" "")
15603 (match_operand:SI 2 "" "")))
15604 (set (reg:SI SP_REG)
15605 (plus:SI (reg:SI SP_REG)
15606 (match_operand:SI 4 "" "")))])]
15609 ix86_expand_call (operands[0], operands[1], operands[2],
15610 operands[3], operands[4], 0);
15614 (define_expand "call_value"
15615 [(set (match_operand 0 "" "")
15616 (call (match_operand:QI 1 "" "")
15617 (match_operand:SI 2 "" "")))
15618 (use (match_operand:SI 3 "" ""))]
15619 ;; Operand 2 not used on the i386.
15622 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15626 (define_expand "sibcall_value"
15627 [(set (match_operand 0 "" "")
15628 (call (match_operand:QI 1 "" "")
15629 (match_operand:SI 2 "" "")))
15630 (use (match_operand:SI 3 "" ""))]
15631 ;; Operand 2 not used on the i386.
15634 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15638 ;; Call subroutine returning any type.
15640 (define_expand "untyped_call"
15641 [(parallel [(call (match_operand 0 "" "")
15643 (match_operand 1 "" "")
15644 (match_operand 2 "" "")])]
15649 /* In order to give reg-stack an easier job in validating two
15650 coprocessor registers as containing a possible return value,
15651 simply pretend the untyped call returns a complex long double
15654 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15655 and should have the default ABI. */
15657 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15658 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15659 operands[0], const0_rtx,
15660 GEN_INT ((TARGET_64BIT
15661 ? (ix86_abi == SYSV_ABI
15662 ? X86_64_SSE_REGPARM_MAX
15663 : X86_64_MS_SSE_REGPARM_MAX)
15664 : X86_32_SSE_REGPARM_MAX)
15668 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15670 rtx set = XVECEXP (operands[2], 0, i);
15671 emit_move_insn (SET_DEST (set), SET_SRC (set));
15674 /* The optimizer does not know that the call sets the function value
15675 registers we stored in the result block. We avoid problems by
15676 claiming that all hard registers are used and clobbered at this
15678 emit_insn (gen_blockage ());
15683 ;; Prologue and epilogue instructions
15685 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15686 ;; all of memory. This blocks insns from being moved across this point.
15688 (define_insn "blockage"
15689 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15692 [(set_attr "length" "0")])
15694 ;; Do not schedule instructions accessing memory across this point.
15696 (define_expand "memory_blockage"
15697 [(set (match_dup 0)
15698 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15701 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15702 MEM_VOLATILE_P (operands[0]) = 1;
15705 (define_insn "*memory_blockage"
15706 [(set (match_operand:BLK 0 "" "")
15707 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15710 [(set_attr "length" "0")])
15712 ;; As USE insns aren't meaningful after reload, this is used instead
15713 ;; to prevent deleting instructions setting registers for PIC code
15714 (define_insn "prologue_use"
15715 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15718 [(set_attr "length" "0")])
15720 ;; Insn emitted into the body of a function to return from a function.
15721 ;; This is only done if the function's epilogue is known to be simple.
15722 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15724 (define_expand "return"
15726 "ix86_can_use_return_insn_p ()"
15728 if (crtl->args.pops_args)
15730 rtx popc = GEN_INT (crtl->args.pops_args);
15731 emit_jump_insn (gen_return_pop_internal (popc));
15736 (define_insn "return_internal"
15740 [(set_attr "length" "1")
15741 (set_attr "atom_unit" "jeu")
15742 (set_attr "length_immediate" "0")
15743 (set_attr "modrm" "0")])
15745 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15746 ;; instruction Athlon and K8 have.
15748 (define_insn "return_internal_long"
15750 (unspec [(const_int 0)] UNSPEC_REP)]
15753 [(set_attr "length" "2")
15754 (set_attr "atom_unit" "jeu")
15755 (set_attr "length_immediate" "0")
15756 (set_attr "prefix_rep" "1")
15757 (set_attr "modrm" "0")])
15759 (define_insn "return_pop_internal"
15761 (use (match_operand:SI 0 "const_int_operand" ""))]
15764 [(set_attr "length" "3")
15765 (set_attr "atom_unit" "jeu")
15766 (set_attr "length_immediate" "2")
15767 (set_attr "modrm" "0")])
15769 (define_insn "return_indirect_internal"
15771 (use (match_operand:SI 0 "register_operand" "r"))]
15774 [(set_attr "type" "ibr")
15775 (set_attr "length_immediate" "0")])
15781 [(set_attr "length" "1")
15782 (set_attr "length_immediate" "0")
15783 (set_attr "modrm" "0")])
15785 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
15786 ;; branch prediction penalty for the third jump in a 16-byte
15790 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15793 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15794 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15796 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15797 The align insn is used to avoid 3 jump instructions in the row to improve
15798 branch prediction and the benefits hardly outweigh the cost of extra 8
15799 nops on the average inserted by full alignment pseudo operation. */
15803 [(set_attr "length" "16")])
15805 (define_expand "prologue"
15808 "ix86_expand_prologue (); DONE;")
15810 (define_insn "set_got"
15811 [(set (match_operand:SI 0 "register_operand" "=r")
15812 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15813 (clobber (reg:CC FLAGS_REG))]
15815 { return output_set_got (operands[0], NULL_RTX); }
15816 [(set_attr "type" "multi")
15817 (set_attr "length" "12")])
15819 (define_insn "set_got_labelled"
15820 [(set (match_operand:SI 0 "register_operand" "=r")
15821 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15823 (clobber (reg:CC FLAGS_REG))]
15825 { return output_set_got (operands[0], operands[1]); }
15826 [(set_attr "type" "multi")
15827 (set_attr "length" "12")])
15829 (define_insn "set_got_rex64"
15830 [(set (match_operand:DI 0 "register_operand" "=r")
15831 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15833 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15834 [(set_attr "type" "lea")
15835 (set_attr "length_address" "4")
15836 (set_attr "mode" "DI")])
15838 (define_insn "set_rip_rex64"
15839 [(set (match_operand:DI 0 "register_operand" "=r")
15840 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15842 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15843 [(set_attr "type" "lea")
15844 (set_attr "length_address" "4")
15845 (set_attr "mode" "DI")])
15847 (define_insn "set_got_offset_rex64"
15848 [(set (match_operand:DI 0 "register_operand" "=r")
15850 [(label_ref (match_operand 1 "" ""))]
15851 UNSPEC_SET_GOT_OFFSET))]
15853 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15854 [(set_attr "type" "imov")
15855 (set_attr "length_immediate" "0")
15856 (set_attr "length_address" "8")
15857 (set_attr "mode" "DI")])
15859 (define_expand "epilogue"
15862 "ix86_expand_epilogue (1); DONE;")
15864 (define_expand "sibcall_epilogue"
15867 "ix86_expand_epilogue (0); DONE;")
15869 (define_expand "eh_return"
15870 [(use (match_operand 0 "register_operand" ""))]
15873 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15875 /* Tricky bit: we write the address of the handler to which we will
15876 be returning into someone else's stack frame, one word below the
15877 stack address we wish to restore. */
15878 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15879 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15880 tmp = gen_rtx_MEM (Pmode, tmp);
15881 emit_move_insn (tmp, ra);
15883 emit_jump_insn (gen_eh_return_internal ());
15888 (define_insn_and_split "eh_return_internal"
15892 "epilogue_completed"
15894 "ix86_expand_epilogue (2); DONE;")
15896 (define_insn "leave"
15897 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15898 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15899 (clobber (mem:BLK (scratch)))]
15902 [(set_attr "type" "leave")])
15904 (define_insn "leave_rex64"
15905 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15906 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15907 (clobber (mem:BLK (scratch)))]
15910 [(set_attr "type" "leave")])
15912 (define_expand "ffssi2"
15914 [(set (match_operand:SI 0 "register_operand" "")
15915 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15916 (clobber (match_scratch:SI 2 ""))
15917 (clobber (reg:CC FLAGS_REG))])]
15922 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15927 (define_expand "ffs_cmove"
15928 [(set (match_dup 2) (const_int -1))
15929 (parallel [(set (reg:CCZ FLAGS_REG)
15930 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15932 (set (match_operand:SI 0 "register_operand" "")
15933 (ctz:SI (match_dup 1)))])
15934 (set (match_dup 0) (if_then_else:SI
15935 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15938 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15939 (clobber (reg:CC FLAGS_REG))])]
15941 "operands[2] = gen_reg_rtx (SImode);")
15943 (define_insn_and_split "*ffs_no_cmove"
15944 [(set (match_operand:SI 0 "register_operand" "=r")
15945 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15946 (clobber (match_scratch:SI 2 "=&q"))
15947 (clobber (reg:CC FLAGS_REG))]
15950 "&& reload_completed"
15951 [(parallel [(set (reg:CCZ FLAGS_REG)
15952 (compare:CCZ (match_dup 1) (const_int 0)))
15953 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15954 (set (strict_low_part (match_dup 3))
15955 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15956 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15957 (clobber (reg:CC FLAGS_REG))])
15958 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15959 (clobber (reg:CC FLAGS_REG))])
15960 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15961 (clobber (reg:CC FLAGS_REG))])]
15963 operands[3] = gen_lowpart (QImode, operands[2]);
15964 ix86_expand_clear (operands[2]);
15967 (define_insn "*ffssi_1"
15968 [(set (reg:CCZ FLAGS_REG)
15969 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15971 (set (match_operand:SI 0 "register_operand" "=r")
15972 (ctz:SI (match_dup 1)))]
15974 "bsf{l}\t{%1, %0|%0, %1}"
15975 [(set_attr "type" "alu1")
15976 (set_attr "prefix_0f" "1")
15977 (set_attr "mode" "SI")])
15979 (define_expand "ffsdi2"
15980 [(set (match_dup 2) (const_int -1))
15981 (parallel [(set (reg:CCZ FLAGS_REG)
15982 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15984 (set (match_operand:DI 0 "register_operand" "")
15985 (ctz:DI (match_dup 1)))])
15986 (set (match_dup 0) (if_then_else:DI
15987 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15990 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15991 (clobber (reg:CC FLAGS_REG))])]
15993 "operands[2] = gen_reg_rtx (DImode);")
15995 (define_insn "*ffsdi_1"
15996 [(set (reg:CCZ FLAGS_REG)
15997 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15999 (set (match_operand:DI 0 "register_operand" "=r")
16000 (ctz:DI (match_dup 1)))]
16002 "bsf{q}\t{%1, %0|%0, %1}"
16003 [(set_attr "type" "alu1")
16004 (set_attr "prefix_0f" "1")
16005 (set_attr "mode" "DI")])
16007 (define_insn "ctzsi2"
16008 [(set (match_operand:SI 0 "register_operand" "=r")
16009 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16010 (clobber (reg:CC FLAGS_REG))]
16012 "bsf{l}\t{%1, %0|%0, %1}"
16013 [(set_attr "type" "alu1")
16014 (set_attr "prefix_0f" "1")
16015 (set_attr "mode" "SI")])
16017 (define_insn "ctzdi2"
16018 [(set (match_operand:DI 0 "register_operand" "=r")
16019 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16020 (clobber (reg:CC FLAGS_REG))]
16022 "bsf{q}\t{%1, %0|%0, %1}"
16023 [(set_attr "type" "alu1")
16024 (set_attr "prefix_0f" "1")
16025 (set_attr "mode" "DI")])
16027 (define_expand "clzsi2"
16029 [(set (match_operand:SI 0 "register_operand" "")
16030 (minus:SI (const_int 31)
16031 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16032 (clobber (reg:CC FLAGS_REG))])
16034 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16035 (clobber (reg:CC FLAGS_REG))])]
16040 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16045 (define_insn "clzsi2_abm"
16046 [(set (match_operand:SI 0 "register_operand" "=r")
16047 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16048 (clobber (reg:CC FLAGS_REG))]
16050 "lzcnt{l}\t{%1, %0|%0, %1}"
16051 [(set_attr "prefix_rep" "1")
16052 (set_attr "type" "bitmanip")
16053 (set_attr "mode" "SI")])
16056 [(set (match_operand:SI 0 "register_operand" "=r")
16057 (minus:SI (const_int 31)
16058 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16059 (clobber (reg:CC FLAGS_REG))]
16061 "bsr{l}\t{%1, %0|%0, %1}"
16062 [(set_attr "type" "alu1")
16063 (set_attr "prefix_0f" "1")
16064 (set_attr "mode" "SI")])
16066 (define_insn "popcount<mode>2"
16067 [(set (match_operand:SWI248 0 "register_operand" "=r")
16069 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16070 (clobber (reg:CC FLAGS_REG))]
16074 return "popcnt\t{%1, %0|%0, %1}";
16076 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16079 [(set_attr "prefix_rep" "1")
16080 (set_attr "type" "bitmanip")
16081 (set_attr "mode" "<MODE>")])
16083 (define_insn "*popcount<mode>2_cmp"
16084 [(set (reg FLAGS_REG)
16087 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16089 (set (match_operand:SWI248 0 "register_operand" "=r")
16090 (popcount:SWI248 (match_dup 1)))]
16091 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16094 return "popcnt\t{%1, %0|%0, %1}";
16096 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16099 [(set_attr "prefix_rep" "1")
16100 (set_attr "type" "bitmanip")
16101 (set_attr "mode" "<MODE>")])
16103 (define_insn "*popcountsi2_cmp_zext"
16104 [(set (reg FLAGS_REG)
16106 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16108 (set (match_operand:DI 0 "register_operand" "=r")
16109 (zero_extend:DI(popcount:SI (match_dup 1))))]
16110 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16113 return "popcnt\t{%1, %0|%0, %1}";
16115 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16118 [(set_attr "prefix_rep" "1")
16119 (set_attr "type" "bitmanip")
16120 (set_attr "mode" "SI")])
16122 (define_expand "bswapsi2"
16123 [(set (match_operand:SI 0 "register_operand" "")
16124 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16127 if (!(TARGET_BSWAP || TARGET_MOVBE))
16129 rtx x = operands[0];
16131 emit_move_insn (x, operands[1]);
16132 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16133 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16134 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16139 (define_insn "*bswapsi_movbe"
16140 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16141 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16142 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16145 movbe\t{%1, %0|%0, %1}
16146 movbe\t{%1, %0|%0, %1}"
16147 [(set_attr "type" "*,imov,imov")
16148 (set_attr "modrm" "*,1,1")
16149 (set_attr "prefix_0f" "1")
16150 (set_attr "prefix_extra" "*,1,1")
16151 (set_attr "length" "2,*,*")
16152 (set_attr "mode" "SI")])
16154 (define_insn "*bswapsi_1"
16155 [(set (match_operand:SI 0 "register_operand" "=r")
16156 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16159 [(set_attr "prefix_0f" "1")
16160 (set_attr "length" "2")])
16162 (define_insn "*bswaphi_lowpart_1"
16163 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16164 (bswap:HI (match_dup 0)))
16165 (clobber (reg:CC FLAGS_REG))]
16166 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16168 xchg{b}\t{%h0, %b0|%b0, %h0}
16169 rol{w}\t{$8, %0|%0, 8}"
16170 [(set_attr "length" "2,4")
16171 (set_attr "mode" "QI,HI")])
16173 (define_insn "bswaphi_lowpart"
16174 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16175 (bswap:HI (match_dup 0)))
16176 (clobber (reg:CC FLAGS_REG))]
16178 "rol{w}\t{$8, %0|%0, 8}"
16179 [(set_attr "length" "4")
16180 (set_attr "mode" "HI")])
16182 (define_expand "bswapdi2"
16183 [(set (match_operand:DI 0 "register_operand" "")
16184 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16188 (define_insn "*bswapdi_movbe"
16189 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16190 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16191 "TARGET_64BIT && TARGET_MOVBE
16192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16195 movbe\t{%1, %0|%0, %1}
16196 movbe\t{%1, %0|%0, %1}"
16197 [(set_attr "type" "*,imov,imov")
16198 (set_attr "modrm" "*,1,1")
16199 (set_attr "prefix_0f" "1")
16200 (set_attr "prefix_extra" "*,1,1")
16201 (set_attr "length" "3,*,*")
16202 (set_attr "mode" "DI")])
16204 (define_insn "*bswapdi_1"
16205 [(set (match_operand:DI 0 "register_operand" "=r")
16206 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16209 [(set_attr "prefix_0f" "1")
16210 (set_attr "length" "3")])
16212 (define_expand "clzdi2"
16214 [(set (match_operand:DI 0 "register_operand" "")
16215 (minus:DI (const_int 63)
16216 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16217 (clobber (reg:CC FLAGS_REG))])
16219 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16220 (clobber (reg:CC FLAGS_REG))])]
16225 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16230 (define_insn "clzdi2_abm"
16231 [(set (match_operand:DI 0 "register_operand" "=r")
16232 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16233 (clobber (reg:CC FLAGS_REG))]
16234 "TARGET_64BIT && TARGET_ABM"
16235 "lzcnt{q}\t{%1, %0|%0, %1}"
16236 [(set_attr "prefix_rep" "1")
16237 (set_attr "type" "bitmanip")
16238 (set_attr "mode" "DI")])
16240 (define_insn "bsr_rex64"
16241 [(set (match_operand:DI 0 "register_operand" "=r")
16242 (minus:DI (const_int 63)
16243 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16244 (clobber (reg:CC FLAGS_REG))]
16246 "bsr{q}\t{%1, %0|%0, %1}"
16247 [(set_attr "type" "alu1")
16248 (set_attr "prefix_0f" "1")
16249 (set_attr "mode" "DI")])
16251 (define_expand "clzhi2"
16253 [(set (match_operand:HI 0 "register_operand" "")
16254 (minus:HI (const_int 15)
16255 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16256 (clobber (reg:CC FLAGS_REG))])
16258 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16259 (clobber (reg:CC FLAGS_REG))])]
16264 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16269 (define_insn "clzhi2_abm"
16270 [(set (match_operand:HI 0 "register_operand" "=r")
16271 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16272 (clobber (reg:CC FLAGS_REG))]
16274 "lzcnt{w}\t{%1, %0|%0, %1}"
16275 [(set_attr "prefix_rep" "1")
16276 (set_attr "type" "bitmanip")
16277 (set_attr "mode" "HI")])
16279 (define_insn "*bsrhi"
16280 [(set (match_operand:HI 0 "register_operand" "=r")
16281 (minus:HI (const_int 15)
16282 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16283 (clobber (reg:CC FLAGS_REG))]
16285 "bsr{w}\t{%1, %0|%0, %1}"
16286 [(set_attr "type" "alu1")
16287 (set_attr "prefix_0f" "1")
16288 (set_attr "mode" "HI")])
16290 (define_expand "paritydi2"
16291 [(set (match_operand:DI 0 "register_operand" "")
16292 (parity:DI (match_operand:DI 1 "register_operand" "")))]
16295 rtx scratch = gen_reg_rtx (QImode);
16298 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16299 NULL_RTX, operands[1]));
16301 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16302 gen_rtx_REG (CCmode, FLAGS_REG),
16304 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16307 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16310 rtx tmp = gen_reg_rtx (SImode);
16312 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16313 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16318 (define_insn_and_split "paritydi2_cmp"
16319 [(set (reg:CC FLAGS_REG)
16320 (parity:CC (match_operand:DI 3 "register_operand" "0")))
16321 (clobber (match_scratch:DI 0 "=r"))
16322 (clobber (match_scratch:SI 1 "=&r"))
16323 (clobber (match_scratch:HI 2 "=Q"))]
16326 "&& reload_completed"
16328 [(set (match_dup 1)
16329 (xor:SI (match_dup 1) (match_dup 4)))
16330 (clobber (reg:CC FLAGS_REG))])
16332 [(set (reg:CC FLAGS_REG)
16333 (parity:CC (match_dup 1)))
16334 (clobber (match_dup 1))
16335 (clobber (match_dup 2))])]
16337 operands[4] = gen_lowpart (SImode, operands[3]);
16341 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16342 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16345 operands[1] = gen_highpart (SImode, operands[3]);
16348 (define_expand "paritysi2"
16349 [(set (match_operand:SI 0 "register_operand" "")
16350 (parity:SI (match_operand:SI 1 "register_operand" "")))]
16353 rtx scratch = gen_reg_rtx (QImode);
16356 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16358 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16359 gen_rtx_REG (CCmode, FLAGS_REG),
16361 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16363 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16367 (define_insn_and_split "paritysi2_cmp"
16368 [(set (reg:CC FLAGS_REG)
16369 (parity:CC (match_operand:SI 2 "register_operand" "0")))
16370 (clobber (match_scratch:SI 0 "=r"))
16371 (clobber (match_scratch:HI 1 "=&Q"))]
16374 "&& reload_completed"
16376 [(set (match_dup 1)
16377 (xor:HI (match_dup 1) (match_dup 3)))
16378 (clobber (reg:CC FLAGS_REG))])
16380 [(set (reg:CC FLAGS_REG)
16381 (parity:CC (match_dup 1)))
16382 (clobber (match_dup 1))])]
16384 operands[3] = gen_lowpart (HImode, operands[2]);
16386 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16387 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16390 (define_insn "*parityhi2_cmp"
16391 [(set (reg:CC FLAGS_REG)
16392 (parity:CC (match_operand:HI 1 "register_operand" "0")))
16393 (clobber (match_scratch:HI 0 "=Q"))]
16395 "xor{b}\t{%h0, %b0|%b0, %h0}"
16396 [(set_attr "length" "2")
16397 (set_attr "mode" "HI")])
16399 (define_insn "*parityqi2_cmp"
16400 [(set (reg:CC FLAGS_REG)
16401 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16404 [(set_attr "length" "2")
16405 (set_attr "mode" "QI")])
16407 ;; Thread-local storage patterns for ELF.
16409 ;; Note that these code sequences must appear exactly as shown
16410 ;; in order to allow linker relaxation.
16412 (define_insn "*tls_global_dynamic_32_gnu"
16413 [(set (match_operand:SI 0 "register_operand" "=a")
16414 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16415 (match_operand:SI 2 "tls_symbolic_operand" "")
16416 (match_operand:SI 3 "call_insn_operand" "")]
16418 (clobber (match_scratch:SI 4 "=d"))
16419 (clobber (match_scratch:SI 5 "=c"))
16420 (clobber (reg:CC FLAGS_REG))]
16421 "!TARGET_64BIT && TARGET_GNU_TLS"
16422 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16423 [(set_attr "type" "multi")
16424 (set_attr "length" "12")])
16426 (define_insn "*tls_global_dynamic_32_sun"
16427 [(set (match_operand:SI 0 "register_operand" "=a")
16428 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16429 (match_operand:SI 2 "tls_symbolic_operand" "")
16430 (match_operand:SI 3 "call_insn_operand" "")]
16432 (clobber (match_scratch:SI 4 "=d"))
16433 (clobber (match_scratch:SI 5 "=c"))
16434 (clobber (reg:CC FLAGS_REG))]
16435 "!TARGET_64BIT && TARGET_SUN_TLS"
16436 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16437 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16438 [(set_attr "type" "multi")
16439 (set_attr "length" "14")])
16441 (define_expand "tls_global_dynamic_32"
16442 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16445 (match_operand:SI 1 "tls_symbolic_operand" "")
16448 (clobber (match_scratch:SI 4 ""))
16449 (clobber (match_scratch:SI 5 ""))
16450 (clobber (reg:CC FLAGS_REG))])]
16454 operands[2] = pic_offset_table_rtx;
16457 operands[2] = gen_reg_rtx (Pmode);
16458 emit_insn (gen_set_got (operands[2]));
16460 if (TARGET_GNU2_TLS)
16462 emit_insn (gen_tls_dynamic_gnu2_32
16463 (operands[0], operands[1], operands[2]));
16466 operands[3] = ix86_tls_get_addr ();
16469 (define_insn "*tls_global_dynamic_64"
16470 [(set (match_operand:DI 0 "register_operand" "=a")
16471 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16472 (match_operand:DI 3 "" "")))
16473 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16476 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16477 [(set_attr "type" "multi")
16478 (set_attr "length" "16")])
16480 (define_expand "tls_global_dynamic_64"
16481 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16482 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16483 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16487 if (TARGET_GNU2_TLS)
16489 emit_insn (gen_tls_dynamic_gnu2_64
16490 (operands[0], operands[1]));
16493 operands[2] = ix86_tls_get_addr ();
16496 (define_insn "*tls_local_dynamic_base_32_gnu"
16497 [(set (match_operand:SI 0 "register_operand" "=a")
16498 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16499 (match_operand:SI 2 "call_insn_operand" "")]
16500 UNSPEC_TLS_LD_BASE))
16501 (clobber (match_scratch:SI 3 "=d"))
16502 (clobber (match_scratch:SI 4 "=c"))
16503 (clobber (reg:CC FLAGS_REG))]
16504 "!TARGET_64BIT && TARGET_GNU_TLS"
16505 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16506 [(set_attr "type" "multi")
16507 (set_attr "length" "11")])
16509 (define_insn "*tls_local_dynamic_base_32_sun"
16510 [(set (match_operand:SI 0 "register_operand" "=a")
16511 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16512 (match_operand:SI 2 "call_insn_operand" "")]
16513 UNSPEC_TLS_LD_BASE))
16514 (clobber (match_scratch:SI 3 "=d"))
16515 (clobber (match_scratch:SI 4 "=c"))
16516 (clobber (reg:CC FLAGS_REG))]
16517 "!TARGET_64BIT && TARGET_SUN_TLS"
16518 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16519 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16520 [(set_attr "type" "multi")
16521 (set_attr "length" "13")])
16523 (define_expand "tls_local_dynamic_base_32"
16524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16525 (unspec:SI [(match_dup 1) (match_dup 2)]
16526 UNSPEC_TLS_LD_BASE))
16527 (clobber (match_scratch:SI 3 ""))
16528 (clobber (match_scratch:SI 4 ""))
16529 (clobber (reg:CC FLAGS_REG))])]
16533 operands[1] = pic_offset_table_rtx;
16536 operands[1] = gen_reg_rtx (Pmode);
16537 emit_insn (gen_set_got (operands[1]));
16539 if (TARGET_GNU2_TLS)
16541 emit_insn (gen_tls_dynamic_gnu2_32
16542 (operands[0], ix86_tls_module_base (), operands[1]));
16545 operands[2] = ix86_tls_get_addr ();
16548 (define_insn "*tls_local_dynamic_base_64"
16549 [(set (match_operand:DI 0 "register_operand" "=a")
16550 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16551 (match_operand:DI 2 "" "")))
16552 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16554 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16555 [(set_attr "type" "multi")
16556 (set_attr "length" "12")])
16558 (define_expand "tls_local_dynamic_base_64"
16559 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16560 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16561 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16564 if (TARGET_GNU2_TLS)
16566 emit_insn (gen_tls_dynamic_gnu2_64
16567 (operands[0], ix86_tls_module_base ()));
16570 operands[1] = ix86_tls_get_addr ();
16573 ;; Local dynamic of a single variable is a lose. Show combine how
16574 ;; to convert that back to global dynamic.
16576 (define_insn_and_split "*tls_local_dynamic_32_once"
16577 [(set (match_operand:SI 0 "register_operand" "=a")
16578 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16579 (match_operand:SI 2 "call_insn_operand" "")]
16580 UNSPEC_TLS_LD_BASE)
16581 (const:SI (unspec:SI
16582 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16584 (clobber (match_scratch:SI 4 "=d"))
16585 (clobber (match_scratch:SI 5 "=c"))
16586 (clobber (reg:CC FLAGS_REG))]
16590 [(parallel [(set (match_dup 0)
16591 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16593 (clobber (match_dup 4))
16594 (clobber (match_dup 5))
16595 (clobber (reg:CC FLAGS_REG))])]
16598 ;; Load and add the thread base pointer from %gs:0.
16600 (define_insn "*load_tp_si"
16601 [(set (match_operand:SI 0 "register_operand" "=r")
16602 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16604 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16605 [(set_attr "type" "imov")
16606 (set_attr "modrm" "0")
16607 (set_attr "length" "7")
16608 (set_attr "memory" "load")
16609 (set_attr "imm_disp" "false")])
16611 (define_insn "*add_tp_si"
16612 [(set (match_operand:SI 0 "register_operand" "=r")
16613 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16614 (match_operand:SI 1 "register_operand" "0")))
16615 (clobber (reg:CC FLAGS_REG))]
16617 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16618 [(set_attr "type" "alu")
16619 (set_attr "modrm" "0")
16620 (set_attr "length" "7")
16621 (set_attr "memory" "load")
16622 (set_attr "imm_disp" "false")])
16624 (define_insn "*load_tp_di"
16625 [(set (match_operand:DI 0 "register_operand" "=r")
16626 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16628 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16629 [(set_attr "type" "imov")
16630 (set_attr "modrm" "0")
16631 (set_attr "length" "7")
16632 (set_attr "memory" "load")
16633 (set_attr "imm_disp" "false")])
16635 (define_insn "*add_tp_di"
16636 [(set (match_operand:DI 0 "register_operand" "=r")
16637 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16638 (match_operand:DI 1 "register_operand" "0")))
16639 (clobber (reg:CC FLAGS_REG))]
16641 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16642 [(set_attr "type" "alu")
16643 (set_attr "modrm" "0")
16644 (set_attr "length" "7")
16645 (set_attr "memory" "load")
16646 (set_attr "imm_disp" "false")])
16648 ;; GNU2 TLS patterns can be split.
16650 (define_expand "tls_dynamic_gnu2_32"
16651 [(set (match_dup 3)
16652 (plus:SI (match_operand:SI 2 "register_operand" "")
16654 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16657 [(set (match_operand:SI 0 "register_operand" "")
16658 (unspec:SI [(match_dup 1) (match_dup 3)
16659 (match_dup 2) (reg:SI SP_REG)]
16661 (clobber (reg:CC FLAGS_REG))])]
16662 "!TARGET_64BIT && TARGET_GNU2_TLS"
16664 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16665 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16668 (define_insn "*tls_dynamic_lea_32"
16669 [(set (match_operand:SI 0 "register_operand" "=r")
16670 (plus:SI (match_operand:SI 1 "register_operand" "b")
16672 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16673 UNSPEC_TLSDESC))))]
16674 "!TARGET_64BIT && TARGET_GNU2_TLS"
16675 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16676 [(set_attr "type" "lea")
16677 (set_attr "mode" "SI")
16678 (set_attr "length" "6")
16679 (set_attr "length_address" "4")])
16681 (define_insn "*tls_dynamic_call_32"
16682 [(set (match_operand:SI 0 "register_operand" "=a")
16683 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16684 (match_operand:SI 2 "register_operand" "0")
16685 ;; we have to make sure %ebx still points to the GOT
16686 (match_operand:SI 3 "register_operand" "b")
16689 (clobber (reg:CC FLAGS_REG))]
16690 "!TARGET_64BIT && TARGET_GNU2_TLS"
16691 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16692 [(set_attr "type" "call")
16693 (set_attr "length" "2")
16694 (set_attr "length_address" "0")])
16696 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16697 [(set (match_operand:SI 0 "register_operand" "=&a")
16699 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16700 (match_operand:SI 4 "" "")
16701 (match_operand:SI 2 "register_operand" "b")
16704 (const:SI (unspec:SI
16705 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16707 (clobber (reg:CC FLAGS_REG))]
16708 "!TARGET_64BIT && TARGET_GNU2_TLS"
16711 [(set (match_dup 0) (match_dup 5))]
16713 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16714 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16717 (define_expand "tls_dynamic_gnu2_64"
16718 [(set (match_dup 2)
16719 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16722 [(set (match_operand:DI 0 "register_operand" "")
16723 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16725 (clobber (reg:CC FLAGS_REG))])]
16726 "TARGET_64BIT && TARGET_GNU2_TLS"
16728 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16729 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16732 (define_insn "*tls_dynamic_lea_64"
16733 [(set (match_operand:DI 0 "register_operand" "=r")
16734 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16736 "TARGET_64BIT && TARGET_GNU2_TLS"
16737 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16738 [(set_attr "type" "lea")
16739 (set_attr "mode" "DI")
16740 (set_attr "length" "7")
16741 (set_attr "length_address" "4")])
16743 (define_insn "*tls_dynamic_call_64"
16744 [(set (match_operand:DI 0 "register_operand" "=a")
16745 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16746 (match_operand:DI 2 "register_operand" "0")
16749 (clobber (reg:CC FLAGS_REG))]
16750 "TARGET_64BIT && TARGET_GNU2_TLS"
16751 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16752 [(set_attr "type" "call")
16753 (set_attr "length" "2")
16754 (set_attr "length_address" "0")])
16756 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16757 [(set (match_operand:DI 0 "register_operand" "=&a")
16759 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16760 (match_operand:DI 3 "" "")
16763 (const:DI (unspec:DI
16764 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16766 (clobber (reg:CC FLAGS_REG))]
16767 "TARGET_64BIT && TARGET_GNU2_TLS"
16770 [(set (match_dup 0) (match_dup 4))]
16772 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16773 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16778 ;; These patterns match the binary 387 instructions for addM3, subM3,
16779 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16780 ;; SFmode. The first is the normal insn, the second the same insn but
16781 ;; with one operand a conversion, and the third the same insn but with
16782 ;; the other operand a conversion. The conversion may be SFmode or
16783 ;; SImode if the target mode DFmode, but only SImode if the target mode
16786 ;; Gcc is slightly more smart about handling normal two address instructions
16787 ;; so use special patterns for add and mull.
16789 (define_insn "*fop_<mode>_comm_mixed_avx"
16790 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16791 (match_operator:MODEF 3 "binary_fp_operator"
16792 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16793 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16794 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16795 && COMMUTATIVE_ARITH_P (operands[3])
16796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16797 "* return output_387_binary_op (insn, operands);"
16798 [(set (attr "type")
16799 (if_then_else (eq_attr "alternative" "1")
16800 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16801 (const_string "ssemul")
16802 (const_string "sseadd"))
16803 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16804 (const_string "fmul")
16805 (const_string "fop"))))
16806 (set_attr "prefix" "orig,maybe_vex")
16807 (set_attr "mode" "<MODE>")])
16809 (define_insn "*fop_<mode>_comm_mixed"
16810 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16811 (match_operator:MODEF 3 "binary_fp_operator"
16812 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16813 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16814 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16815 && COMMUTATIVE_ARITH_P (operands[3])
16816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16817 "* return output_387_binary_op (insn, operands);"
16818 [(set (attr "type")
16819 (if_then_else (eq_attr "alternative" "1")
16820 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16821 (const_string "ssemul")
16822 (const_string "sseadd"))
16823 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16824 (const_string "fmul")
16825 (const_string "fop"))))
16826 (set_attr "mode" "<MODE>")])
16828 (define_insn "*fop_<mode>_comm_avx"
16829 [(set (match_operand:MODEF 0 "register_operand" "=x")
16830 (match_operator:MODEF 3 "binary_fp_operator"
16831 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16832 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16833 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834 && COMMUTATIVE_ARITH_P (operands[3])
16835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16836 "* return output_387_binary_op (insn, operands);"
16837 [(set (attr "type")
16838 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16839 (const_string "ssemul")
16840 (const_string "sseadd")))
16841 (set_attr "prefix" "vex")
16842 (set_attr "mode" "<MODE>")])
16844 (define_insn "*fop_<mode>_comm_sse"
16845 [(set (match_operand:MODEF 0 "register_operand" "=x")
16846 (match_operator:MODEF 3 "binary_fp_operator"
16847 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16848 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16849 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16850 && COMMUTATIVE_ARITH_P (operands[3])
16851 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16852 "* return output_387_binary_op (insn, operands);"
16853 [(set (attr "type")
16854 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16855 (const_string "ssemul")
16856 (const_string "sseadd")))
16857 (set_attr "mode" "<MODE>")])
16859 (define_insn "*fop_<mode>_comm_i387"
16860 [(set (match_operand:MODEF 0 "register_operand" "=f")
16861 (match_operator:MODEF 3 "binary_fp_operator"
16862 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16863 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16864 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16865 && COMMUTATIVE_ARITH_P (operands[3])
16866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16867 "* return output_387_binary_op (insn, operands);"
16868 [(set (attr "type")
16869 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16870 (const_string "fmul")
16871 (const_string "fop")))
16872 (set_attr "mode" "<MODE>")])
16874 (define_insn "*fop_<mode>_1_mixed_avx"
16875 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16876 (match_operator:MODEF 3 "binary_fp_operator"
16877 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16878 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16879 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16880 && !COMMUTATIVE_ARITH_P (operands[3])
16881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16882 "* return output_387_binary_op (insn, operands);"
16883 [(set (attr "type")
16884 (cond [(and (eq_attr "alternative" "2")
16885 (match_operand:MODEF 3 "mult_operator" ""))
16886 (const_string "ssemul")
16887 (and (eq_attr "alternative" "2")
16888 (match_operand:MODEF 3 "div_operator" ""))
16889 (const_string "ssediv")
16890 (eq_attr "alternative" "2")
16891 (const_string "sseadd")
16892 (match_operand:MODEF 3 "mult_operator" "")
16893 (const_string "fmul")
16894 (match_operand:MODEF 3 "div_operator" "")
16895 (const_string "fdiv")
16897 (const_string "fop")))
16898 (set_attr "prefix" "orig,orig,maybe_vex")
16899 (set_attr "mode" "<MODE>")])
16901 (define_insn "*fop_<mode>_1_mixed"
16902 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16903 (match_operator:MODEF 3 "binary_fp_operator"
16904 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16905 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16906 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16907 && !COMMUTATIVE_ARITH_P (operands[3])
16908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16909 "* return output_387_binary_op (insn, operands);"
16910 [(set (attr "type")
16911 (cond [(and (eq_attr "alternative" "2")
16912 (match_operand:MODEF 3 "mult_operator" ""))
16913 (const_string "ssemul")
16914 (and (eq_attr "alternative" "2")
16915 (match_operand:MODEF 3 "div_operator" ""))
16916 (const_string "ssediv")
16917 (eq_attr "alternative" "2")
16918 (const_string "sseadd")
16919 (match_operand:MODEF 3 "mult_operator" "")
16920 (const_string "fmul")
16921 (match_operand:MODEF 3 "div_operator" "")
16922 (const_string "fdiv")
16924 (const_string "fop")))
16925 (set_attr "mode" "<MODE>")])
16927 (define_insn "*rcpsf2_sse"
16928 [(set (match_operand:SF 0 "register_operand" "=x")
16929 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16932 "%vrcpss\t{%1, %d0|%d0, %1}"
16933 [(set_attr "type" "sse")
16934 (set_attr "atom_sse_attr" "rcp")
16935 (set_attr "prefix" "maybe_vex")
16936 (set_attr "mode" "SF")])
16938 (define_insn "*fop_<mode>_1_avx"
16939 [(set (match_operand:MODEF 0 "register_operand" "=x")
16940 (match_operator:MODEF 3 "binary_fp_operator"
16941 [(match_operand:MODEF 1 "register_operand" "x")
16942 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16943 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16944 && !COMMUTATIVE_ARITH_P (operands[3])"
16945 "* return output_387_binary_op (insn, operands);"
16946 [(set (attr "type")
16947 (cond [(match_operand:MODEF 3 "mult_operator" "")
16948 (const_string "ssemul")
16949 (match_operand:MODEF 3 "div_operator" "")
16950 (const_string "ssediv")
16952 (const_string "sseadd")))
16953 (set_attr "prefix" "vex")
16954 (set_attr "mode" "<MODE>")])
16956 (define_insn "*fop_<mode>_1_sse"
16957 [(set (match_operand:MODEF 0 "register_operand" "=x")
16958 (match_operator:MODEF 3 "binary_fp_operator"
16959 [(match_operand:MODEF 1 "register_operand" "0")
16960 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16961 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16962 && !COMMUTATIVE_ARITH_P (operands[3])"
16963 "* return output_387_binary_op (insn, operands);"
16964 [(set (attr "type")
16965 (cond [(match_operand:MODEF 3 "mult_operator" "")
16966 (const_string "ssemul")
16967 (match_operand:MODEF 3 "div_operator" "")
16968 (const_string "ssediv")
16970 (const_string "sseadd")))
16971 (set_attr "mode" "<MODE>")])
16973 ;; This pattern is not fully shadowed by the pattern above.
16974 (define_insn "*fop_<mode>_1_i387"
16975 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16976 (match_operator:MODEF 3 "binary_fp_operator"
16977 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16978 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16979 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16980 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16981 && !COMMUTATIVE_ARITH_P (operands[3])
16982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983 "* return output_387_binary_op (insn, operands);"
16984 [(set (attr "type")
16985 (cond [(match_operand:MODEF 3 "mult_operator" "")
16986 (const_string "fmul")
16987 (match_operand:MODEF 3 "div_operator" "")
16988 (const_string "fdiv")
16990 (const_string "fop")))
16991 (set_attr "mode" "<MODE>")])
16993 ;; ??? Add SSE splitters for these!
16994 (define_insn "*fop_<MODEF:mode>_2_i387"
16995 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16996 (match_operator:MODEF 3 "binary_fp_operator"
16998 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16999 (match_operand:MODEF 2 "register_operand" "0,0")]))]
17000 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17001 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17002 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17003 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17004 [(set (attr "type")
17005 (cond [(match_operand:MODEF 3 "mult_operator" "")
17006 (const_string "fmul")
17007 (match_operand:MODEF 3 "div_operator" "")
17008 (const_string "fdiv")
17010 (const_string "fop")))
17011 (set_attr "fp_int_src" "true")
17012 (set_attr "mode" "<X87MODEI12:MODE>")])
17014 (define_insn "*fop_<MODEF:mode>_3_i387"
17015 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17016 (match_operator:MODEF 3 "binary_fp_operator"
17017 [(match_operand:MODEF 1 "register_operand" "0,0")
17019 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17020 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17021 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17022 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17023 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17024 [(set (attr "type")
17025 (cond [(match_operand:MODEF 3 "mult_operator" "")
17026 (const_string "fmul")
17027 (match_operand:MODEF 3 "div_operator" "")
17028 (const_string "fdiv")
17030 (const_string "fop")))
17031 (set_attr "fp_int_src" "true")
17032 (set_attr "mode" "<MODE>")])
17034 (define_insn "*fop_df_4_i387"
17035 [(set (match_operand:DF 0 "register_operand" "=f,f")
17036 (match_operator:DF 3 "binary_fp_operator"
17038 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17039 (match_operand:DF 2 "register_operand" "0,f")]))]
17040 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17041 && !(TARGET_SSE2 && TARGET_SSE_MATH)
17042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17043 "* return output_387_binary_op (insn, operands);"
17044 [(set (attr "type")
17045 (cond [(match_operand:DF 3 "mult_operator" "")
17046 (const_string "fmul")
17047 (match_operand:DF 3 "div_operator" "")
17048 (const_string "fdiv")
17050 (const_string "fop")))
17051 (set_attr "mode" "SF")])
17053 (define_insn "*fop_df_5_i387"
17054 [(set (match_operand:DF 0 "register_operand" "=f,f")
17055 (match_operator:DF 3 "binary_fp_operator"
17056 [(match_operand:DF 1 "register_operand" "0,f")
17058 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17059 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17060 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17061 "* return output_387_binary_op (insn, operands);"
17062 [(set (attr "type")
17063 (cond [(match_operand:DF 3 "mult_operator" "")
17064 (const_string "fmul")
17065 (match_operand:DF 3 "div_operator" "")
17066 (const_string "fdiv")
17068 (const_string "fop")))
17069 (set_attr "mode" "SF")])
17071 (define_insn "*fop_df_6_i387"
17072 [(set (match_operand:DF 0 "register_operand" "=f,f")
17073 (match_operator:DF 3 "binary_fp_operator"
17075 (match_operand:SF 1 "register_operand" "0,f"))
17077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17078 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17079 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17080 "* return output_387_binary_op (insn, operands);"
17081 [(set (attr "type")
17082 (cond [(match_operand:DF 3 "mult_operator" "")
17083 (const_string "fmul")
17084 (match_operand:DF 3 "div_operator" "")
17085 (const_string "fdiv")
17087 (const_string "fop")))
17088 (set_attr "mode" "SF")])
17090 (define_insn "*fop_xf_comm_i387"
17091 [(set (match_operand:XF 0 "register_operand" "=f")
17092 (match_operator:XF 3 "binary_fp_operator"
17093 [(match_operand:XF 1 "register_operand" "%0")
17094 (match_operand:XF 2 "register_operand" "f")]))]
17096 && COMMUTATIVE_ARITH_P (operands[3])"
17097 "* return output_387_binary_op (insn, operands);"
17098 [(set (attr "type")
17099 (if_then_else (match_operand:XF 3 "mult_operator" "")
17100 (const_string "fmul")
17101 (const_string "fop")))
17102 (set_attr "mode" "XF")])
17104 (define_insn "*fop_xf_1_i387"
17105 [(set (match_operand:XF 0 "register_operand" "=f,f")
17106 (match_operator:XF 3 "binary_fp_operator"
17107 [(match_operand:XF 1 "register_operand" "0,f")
17108 (match_operand:XF 2 "register_operand" "f,0")]))]
17110 && !COMMUTATIVE_ARITH_P (operands[3])"
17111 "* return output_387_binary_op (insn, operands);"
17112 [(set (attr "type")
17113 (cond [(match_operand:XF 3 "mult_operator" "")
17114 (const_string "fmul")
17115 (match_operand:XF 3 "div_operator" "")
17116 (const_string "fdiv")
17118 (const_string "fop")))
17119 (set_attr "mode" "XF")])
17121 (define_insn "*fop_xf_2_i387"
17122 [(set (match_operand:XF 0 "register_operand" "=f,f")
17123 (match_operator:XF 3 "binary_fp_operator"
17125 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17126 (match_operand:XF 2 "register_operand" "0,0")]))]
17127 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17128 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17129 [(set (attr "type")
17130 (cond [(match_operand:XF 3 "mult_operator" "")
17131 (const_string "fmul")
17132 (match_operand:XF 3 "div_operator" "")
17133 (const_string "fdiv")
17135 (const_string "fop")))
17136 (set_attr "fp_int_src" "true")
17137 (set_attr "mode" "<MODE>")])
17139 (define_insn "*fop_xf_3_i387"
17140 [(set (match_operand:XF 0 "register_operand" "=f,f")
17141 (match_operator:XF 3 "binary_fp_operator"
17142 [(match_operand:XF 1 "register_operand" "0,0")
17144 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17145 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17146 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17147 [(set (attr "type")
17148 (cond [(match_operand:XF 3 "mult_operator" "")
17149 (const_string "fmul")
17150 (match_operand:XF 3 "div_operator" "")
17151 (const_string "fdiv")
17153 (const_string "fop")))
17154 (set_attr "fp_int_src" "true")
17155 (set_attr "mode" "<MODE>")])
17157 (define_insn "*fop_xf_4_i387"
17158 [(set (match_operand:XF 0 "register_operand" "=f,f")
17159 (match_operator:XF 3 "binary_fp_operator"
17161 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17162 (match_operand:XF 2 "register_operand" "0,f")]))]
17164 "* return output_387_binary_op (insn, operands);"
17165 [(set (attr "type")
17166 (cond [(match_operand:XF 3 "mult_operator" "")
17167 (const_string "fmul")
17168 (match_operand:XF 3 "div_operator" "")
17169 (const_string "fdiv")
17171 (const_string "fop")))
17172 (set_attr "mode" "<MODE>")])
17174 (define_insn "*fop_xf_5_i387"
17175 [(set (match_operand:XF 0 "register_operand" "=f,f")
17176 (match_operator:XF 3 "binary_fp_operator"
17177 [(match_operand:XF 1 "register_operand" "0,f")
17179 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17181 "* return output_387_binary_op (insn, operands);"
17182 [(set (attr "type")
17183 (cond [(match_operand:XF 3 "mult_operator" "")
17184 (const_string "fmul")
17185 (match_operand:XF 3 "div_operator" "")
17186 (const_string "fdiv")
17188 (const_string "fop")))
17189 (set_attr "mode" "<MODE>")])
17191 (define_insn "*fop_xf_6_i387"
17192 [(set (match_operand:XF 0 "register_operand" "=f,f")
17193 (match_operator:XF 3 "binary_fp_operator"
17195 (match_operand:MODEF 1 "register_operand" "0,f"))
17197 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17199 "* return output_387_binary_op (insn, operands);"
17200 [(set (attr "type")
17201 (cond [(match_operand:XF 3 "mult_operator" "")
17202 (const_string "fmul")
17203 (match_operand:XF 3 "div_operator" "")
17204 (const_string "fdiv")
17206 (const_string "fop")))
17207 (set_attr "mode" "<MODE>")])
17210 [(set (match_operand 0 "register_operand" "")
17211 (match_operator 3 "binary_fp_operator"
17212 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17213 (match_operand 2 "register_operand" "")]))]
17215 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17216 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17219 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17220 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17221 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17222 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17223 GET_MODE (operands[3]),
17226 ix86_free_from_memory (GET_MODE (operands[1]));
17231 [(set (match_operand 0 "register_operand" "")
17232 (match_operator 3 "binary_fp_operator"
17233 [(match_operand 1 "register_operand" "")
17234 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17236 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17237 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17240 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17241 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17242 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17243 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17244 GET_MODE (operands[3]),
17247 ix86_free_from_memory (GET_MODE (operands[2]));
17251 ;; FPU special functions.
17253 ;; This pattern implements a no-op XFmode truncation for
17254 ;; all fancy i386 XFmode math functions.
17256 (define_insn "truncxf<mode>2_i387_noop_unspec"
17257 [(set (match_operand:MODEF 0 "register_operand" "=f")
17258 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17259 UNSPEC_TRUNC_NOOP))]
17260 "TARGET_USE_FANCY_MATH_387"
17261 "* return output_387_reg_move (insn, operands);"
17262 [(set_attr "type" "fmov")
17263 (set_attr "mode" "<MODE>")])
17265 (define_insn "sqrtxf2"
17266 [(set (match_operand:XF 0 "register_operand" "=f")
17267 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17268 "TARGET_USE_FANCY_MATH_387"
17270 [(set_attr "type" "fpspc")
17271 (set_attr "mode" "XF")
17272 (set_attr "athlon_decode" "direct")
17273 (set_attr "amdfam10_decode" "direct")])
17275 (define_insn "sqrt_extend<mode>xf2_i387"
17276 [(set (match_operand:XF 0 "register_operand" "=f")
17279 (match_operand:MODEF 1 "register_operand" "0"))))]
17280 "TARGET_USE_FANCY_MATH_387"
17282 [(set_attr "type" "fpspc")
17283 (set_attr "mode" "XF")
17284 (set_attr "athlon_decode" "direct")
17285 (set_attr "amdfam10_decode" "direct")])
17287 (define_insn "*rsqrtsf2_sse"
17288 [(set (match_operand:SF 0 "register_operand" "=x")
17289 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17292 "%vrsqrtss\t{%1, %d0|%d0, %1}"
17293 [(set_attr "type" "sse")
17294 (set_attr "atom_sse_attr" "rcp")
17295 (set_attr "prefix" "maybe_vex")
17296 (set_attr "mode" "SF")])
17298 (define_expand "rsqrtsf2"
17299 [(set (match_operand:SF 0 "register_operand" "")
17300 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17304 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17308 (define_insn "*sqrt<mode>2_sse"
17309 [(set (match_operand:MODEF 0 "register_operand" "=x")
17311 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17312 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17313 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17314 [(set_attr "type" "sse")
17315 (set_attr "atom_sse_attr" "sqrt")
17316 (set_attr "prefix" "maybe_vex")
17317 (set_attr "mode" "<MODE>")
17318 (set_attr "athlon_decode" "*")
17319 (set_attr "amdfam10_decode" "*")])
17321 (define_expand "sqrt<mode>2"
17322 [(set (match_operand:MODEF 0 "register_operand" "")
17324 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17325 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17326 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17328 if (<MODE>mode == SFmode
17329 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17330 && flag_finite_math_only && !flag_trapping_math
17331 && flag_unsafe_math_optimizations)
17333 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17337 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17339 rtx op0 = gen_reg_rtx (XFmode);
17340 rtx op1 = force_reg (<MODE>mode, operands[1]);
17342 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17343 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17348 (define_insn "fpremxf4_i387"
17349 [(set (match_operand:XF 0 "register_operand" "=f")
17350 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17351 (match_operand:XF 3 "register_operand" "1")]
17353 (set (match_operand:XF 1 "register_operand" "=u")
17354 (unspec:XF [(match_dup 2) (match_dup 3)]
17356 (set (reg:CCFP FPSR_REG)
17357 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17359 "TARGET_USE_FANCY_MATH_387"
17361 [(set_attr "type" "fpspc")
17362 (set_attr "mode" "XF")])
17364 (define_expand "fmodxf3"
17365 [(use (match_operand:XF 0 "register_operand" ""))
17366 (use (match_operand:XF 1 "general_operand" ""))
17367 (use (match_operand:XF 2 "general_operand" ""))]
17368 "TARGET_USE_FANCY_MATH_387"
17370 rtx label = gen_label_rtx ();
17372 rtx op1 = gen_reg_rtx (XFmode);
17373 rtx op2 = gen_reg_rtx (XFmode);
17375 emit_move_insn (op2, operands[2]);
17376 emit_move_insn (op1, operands[1]);
17378 emit_label (label);
17379 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17380 ix86_emit_fp_unordered_jump (label);
17381 LABEL_NUSES (label) = 1;
17383 emit_move_insn (operands[0], op1);
17387 (define_expand "fmod<mode>3"
17388 [(use (match_operand:MODEF 0 "register_operand" ""))
17389 (use (match_operand:MODEF 1 "general_operand" ""))
17390 (use (match_operand:MODEF 2 "general_operand" ""))]
17391 "TARGET_USE_FANCY_MATH_387"
17393 rtx label = gen_label_rtx ();
17395 rtx op1 = gen_reg_rtx (XFmode);
17396 rtx op2 = gen_reg_rtx (XFmode);
17398 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17399 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17401 emit_label (label);
17402 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17403 ix86_emit_fp_unordered_jump (label);
17404 LABEL_NUSES (label) = 1;
17406 /* Truncate the result properly for strict SSE math. */
17407 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17408 && !TARGET_MIX_SSE_I387)
17409 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17411 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17416 (define_insn "fprem1xf4_i387"
17417 [(set (match_operand:XF 0 "register_operand" "=f")
17418 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17419 (match_operand:XF 3 "register_operand" "1")]
17421 (set (match_operand:XF 1 "register_operand" "=u")
17422 (unspec:XF [(match_dup 2) (match_dup 3)]
17424 (set (reg:CCFP FPSR_REG)
17425 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17427 "TARGET_USE_FANCY_MATH_387"
17429 [(set_attr "type" "fpspc")
17430 (set_attr "mode" "XF")])
17432 (define_expand "remainderxf3"
17433 [(use (match_operand:XF 0 "register_operand" ""))
17434 (use (match_operand:XF 1 "general_operand" ""))
17435 (use (match_operand:XF 2 "general_operand" ""))]
17436 "TARGET_USE_FANCY_MATH_387"
17438 rtx label = gen_label_rtx ();
17440 rtx op1 = gen_reg_rtx (XFmode);
17441 rtx op2 = gen_reg_rtx (XFmode);
17443 emit_move_insn (op2, operands[2]);
17444 emit_move_insn (op1, operands[1]);
17446 emit_label (label);
17447 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17448 ix86_emit_fp_unordered_jump (label);
17449 LABEL_NUSES (label) = 1;
17451 emit_move_insn (operands[0], op1);
17455 (define_expand "remainder<mode>3"
17456 [(use (match_operand:MODEF 0 "register_operand" ""))
17457 (use (match_operand:MODEF 1 "general_operand" ""))
17458 (use (match_operand:MODEF 2 "general_operand" ""))]
17459 "TARGET_USE_FANCY_MATH_387"
17461 rtx label = gen_label_rtx ();
17463 rtx op1 = gen_reg_rtx (XFmode);
17464 rtx op2 = gen_reg_rtx (XFmode);
17466 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17469 emit_label (label);
17471 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17472 ix86_emit_fp_unordered_jump (label);
17473 LABEL_NUSES (label) = 1;
17475 /* Truncate the result properly for strict SSE math. */
17476 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17477 && !TARGET_MIX_SSE_I387)
17478 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17480 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17485 (define_insn "*sinxf2_i387"
17486 [(set (match_operand:XF 0 "register_operand" "=f")
17487 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17488 "TARGET_USE_FANCY_MATH_387
17489 && flag_unsafe_math_optimizations"
17491 [(set_attr "type" "fpspc")
17492 (set_attr "mode" "XF")])
17494 (define_insn "*sin_extend<mode>xf2_i387"
17495 [(set (match_operand:XF 0 "register_operand" "=f")
17496 (unspec:XF [(float_extend:XF
17497 (match_operand:MODEF 1 "register_operand" "0"))]
17499 "TARGET_USE_FANCY_MATH_387
17500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501 || TARGET_MIX_SSE_I387)
17502 && flag_unsafe_math_optimizations"
17504 [(set_attr "type" "fpspc")
17505 (set_attr "mode" "XF")])
17507 (define_insn "*cosxf2_i387"
17508 [(set (match_operand:XF 0 "register_operand" "=f")
17509 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17510 "TARGET_USE_FANCY_MATH_387
17511 && flag_unsafe_math_optimizations"
17513 [(set_attr "type" "fpspc")
17514 (set_attr "mode" "XF")])
17516 (define_insn "*cos_extend<mode>xf2_i387"
17517 [(set (match_operand:XF 0 "register_operand" "=f")
17518 (unspec:XF [(float_extend:XF
17519 (match_operand:MODEF 1 "register_operand" "0"))]
17521 "TARGET_USE_FANCY_MATH_387
17522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523 || TARGET_MIX_SSE_I387)
17524 && flag_unsafe_math_optimizations"
17526 [(set_attr "type" "fpspc")
17527 (set_attr "mode" "XF")])
17529 ;; When sincos pattern is defined, sin and cos builtin functions will be
17530 ;; expanded to sincos pattern with one of its outputs left unused.
17531 ;; CSE pass will figure out if two sincos patterns can be combined,
17532 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17533 ;; depending on the unused output.
17535 (define_insn "sincosxf3"
17536 [(set (match_operand:XF 0 "register_operand" "=f")
17537 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17538 UNSPEC_SINCOS_COS))
17539 (set (match_operand:XF 1 "register_operand" "=u")
17540 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17541 "TARGET_USE_FANCY_MATH_387
17542 && flag_unsafe_math_optimizations"
17544 [(set_attr "type" "fpspc")
17545 (set_attr "mode" "XF")])
17548 [(set (match_operand:XF 0 "register_operand" "")
17549 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17550 UNSPEC_SINCOS_COS))
17551 (set (match_operand:XF 1 "register_operand" "")
17552 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17553 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17554 && !(reload_completed || reload_in_progress)"
17555 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17559 [(set (match_operand:XF 0 "register_operand" "")
17560 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17561 UNSPEC_SINCOS_COS))
17562 (set (match_operand:XF 1 "register_operand" "")
17563 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17564 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17565 && !(reload_completed || reload_in_progress)"
17566 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17569 (define_insn "sincos_extend<mode>xf3_i387"
17570 [(set (match_operand:XF 0 "register_operand" "=f")
17571 (unspec:XF [(float_extend:XF
17572 (match_operand:MODEF 2 "register_operand" "0"))]
17573 UNSPEC_SINCOS_COS))
17574 (set (match_operand:XF 1 "register_operand" "=u")
17575 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17576 "TARGET_USE_FANCY_MATH_387
17577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17578 || TARGET_MIX_SSE_I387)
17579 && flag_unsafe_math_optimizations"
17581 [(set_attr "type" "fpspc")
17582 (set_attr "mode" "XF")])
17585 [(set (match_operand:XF 0 "register_operand" "")
17586 (unspec:XF [(float_extend:XF
17587 (match_operand:MODEF 2 "register_operand" ""))]
17588 UNSPEC_SINCOS_COS))
17589 (set (match_operand:XF 1 "register_operand" "")
17590 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17591 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17592 && !(reload_completed || reload_in_progress)"
17593 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17597 [(set (match_operand:XF 0 "register_operand" "")
17598 (unspec:XF [(float_extend:XF
17599 (match_operand:MODEF 2 "register_operand" ""))]
17600 UNSPEC_SINCOS_COS))
17601 (set (match_operand:XF 1 "register_operand" "")
17602 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17603 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17604 && !(reload_completed || reload_in_progress)"
17605 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17608 (define_expand "sincos<mode>3"
17609 [(use (match_operand:MODEF 0 "register_operand" ""))
17610 (use (match_operand:MODEF 1 "register_operand" ""))
17611 (use (match_operand:MODEF 2 "register_operand" ""))]
17612 "TARGET_USE_FANCY_MATH_387
17613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614 || TARGET_MIX_SSE_I387)
17615 && flag_unsafe_math_optimizations"
17617 rtx op0 = gen_reg_rtx (XFmode);
17618 rtx op1 = gen_reg_rtx (XFmode);
17620 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17626 (define_insn "fptanxf4_i387"
17627 [(set (match_operand:XF 0 "register_operand" "=f")
17628 (match_operand:XF 3 "const_double_operand" "F"))
17629 (set (match_operand:XF 1 "register_operand" "=u")
17630 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17632 "TARGET_USE_FANCY_MATH_387
17633 && flag_unsafe_math_optimizations
17634 && standard_80387_constant_p (operands[3]) == 2"
17636 [(set_attr "type" "fpspc")
17637 (set_attr "mode" "XF")])
17639 (define_insn "fptan_extend<mode>xf4_i387"
17640 [(set (match_operand:MODEF 0 "register_operand" "=f")
17641 (match_operand:MODEF 3 "const_double_operand" "F"))
17642 (set (match_operand:XF 1 "register_operand" "=u")
17643 (unspec:XF [(float_extend:XF
17644 (match_operand:MODEF 2 "register_operand" "0"))]
17646 "TARGET_USE_FANCY_MATH_387
17647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17648 || TARGET_MIX_SSE_I387)
17649 && flag_unsafe_math_optimizations
17650 && standard_80387_constant_p (operands[3]) == 2"
17652 [(set_attr "type" "fpspc")
17653 (set_attr "mode" "XF")])
17655 (define_expand "tanxf2"
17656 [(use (match_operand:XF 0 "register_operand" ""))
17657 (use (match_operand:XF 1 "register_operand" ""))]
17658 "TARGET_USE_FANCY_MATH_387
17659 && flag_unsafe_math_optimizations"
17661 rtx one = gen_reg_rtx (XFmode);
17662 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17664 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17668 (define_expand "tan<mode>2"
17669 [(use (match_operand:MODEF 0 "register_operand" ""))
17670 (use (match_operand:MODEF 1 "register_operand" ""))]
17671 "TARGET_USE_FANCY_MATH_387
17672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17673 || TARGET_MIX_SSE_I387)
17674 && flag_unsafe_math_optimizations"
17676 rtx op0 = gen_reg_rtx (XFmode);
17678 rtx one = gen_reg_rtx (<MODE>mode);
17679 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17681 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17682 operands[1], op2));
17683 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17687 (define_insn "*fpatanxf3_i387"
17688 [(set (match_operand:XF 0 "register_operand" "=f")
17689 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17690 (match_operand:XF 2 "register_operand" "u")]
17692 (clobber (match_scratch:XF 3 "=2"))]
17693 "TARGET_USE_FANCY_MATH_387
17694 && flag_unsafe_math_optimizations"
17696 [(set_attr "type" "fpspc")
17697 (set_attr "mode" "XF")])
17699 (define_insn "fpatan_extend<mode>xf3_i387"
17700 [(set (match_operand:XF 0 "register_operand" "=f")
17701 (unspec:XF [(float_extend:XF
17702 (match_operand:MODEF 1 "register_operand" "0"))
17704 (match_operand:MODEF 2 "register_operand" "u"))]
17706 (clobber (match_scratch:XF 3 "=2"))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17709 || TARGET_MIX_SSE_I387)
17710 && flag_unsafe_math_optimizations"
17712 [(set_attr "type" "fpspc")
17713 (set_attr "mode" "XF")])
17715 (define_expand "atan2xf3"
17716 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17717 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17718 (match_operand:XF 1 "register_operand" "")]
17720 (clobber (match_scratch:XF 3 ""))])]
17721 "TARGET_USE_FANCY_MATH_387
17722 && flag_unsafe_math_optimizations"
17725 (define_expand "atan2<mode>3"
17726 [(use (match_operand:MODEF 0 "register_operand" ""))
17727 (use (match_operand:MODEF 1 "register_operand" ""))
17728 (use (match_operand:MODEF 2 "register_operand" ""))]
17729 "TARGET_USE_FANCY_MATH_387
17730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17731 || TARGET_MIX_SSE_I387)
17732 && flag_unsafe_math_optimizations"
17734 rtx op0 = gen_reg_rtx (XFmode);
17736 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17737 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17741 (define_expand "atanxf2"
17742 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17743 (unspec:XF [(match_dup 2)
17744 (match_operand:XF 1 "register_operand" "")]
17746 (clobber (match_scratch:XF 3 ""))])]
17747 "TARGET_USE_FANCY_MATH_387
17748 && flag_unsafe_math_optimizations"
17750 operands[2] = gen_reg_rtx (XFmode);
17751 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17754 (define_expand "atan<mode>2"
17755 [(use (match_operand:MODEF 0 "register_operand" ""))
17756 (use (match_operand:MODEF 1 "register_operand" ""))]
17757 "TARGET_USE_FANCY_MATH_387
17758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17759 || TARGET_MIX_SSE_I387)
17760 && flag_unsafe_math_optimizations"
17762 rtx op0 = gen_reg_rtx (XFmode);
17764 rtx op2 = gen_reg_rtx (<MODE>mode);
17765 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17767 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17768 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17772 (define_expand "asinxf2"
17773 [(set (match_dup 2)
17774 (mult:XF (match_operand:XF 1 "register_operand" "")
17776 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17777 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17778 (parallel [(set (match_operand:XF 0 "register_operand" "")
17779 (unspec:XF [(match_dup 5) (match_dup 1)]
17781 (clobber (match_scratch:XF 6 ""))])]
17782 "TARGET_USE_FANCY_MATH_387
17783 && flag_unsafe_math_optimizations"
17787 if (optimize_insn_for_size_p ())
17790 for (i = 2; i < 6; i++)
17791 operands[i] = gen_reg_rtx (XFmode);
17793 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17796 (define_expand "asin<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"
17804 rtx op0 = gen_reg_rtx (XFmode);
17805 rtx op1 = gen_reg_rtx (XFmode);
17807 if (optimize_insn_for_size_p ())
17810 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811 emit_insn (gen_asinxf2 (op0, op1));
17812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17816 (define_expand "acosxf2"
17817 [(set (match_dup 2)
17818 (mult:XF (match_operand:XF 1 "register_operand" "")
17820 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17821 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17822 (parallel [(set (match_operand:XF 0 "register_operand" "")
17823 (unspec:XF [(match_dup 1) (match_dup 5)]
17825 (clobber (match_scratch:XF 6 ""))])]
17826 "TARGET_USE_FANCY_MATH_387
17827 && flag_unsafe_math_optimizations"
17831 if (optimize_insn_for_size_p ())
17834 for (i = 2; i < 6; i++)
17835 operands[i] = gen_reg_rtx (XFmode);
17837 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17840 (define_expand "acos<mode>2"
17841 [(use (match_operand:MODEF 0 "register_operand" ""))
17842 (use (match_operand:MODEF 1 "general_operand" ""))]
17843 "TARGET_USE_FANCY_MATH_387
17844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17845 || TARGET_MIX_SSE_I387)
17846 && flag_unsafe_math_optimizations"
17848 rtx op0 = gen_reg_rtx (XFmode);
17849 rtx op1 = gen_reg_rtx (XFmode);
17851 if (optimize_insn_for_size_p ())
17854 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17855 emit_insn (gen_acosxf2 (op0, op1));
17856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17860 (define_insn "fyl2xxf3_i387"
17861 [(set (match_operand:XF 0 "register_operand" "=f")
17862 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17863 (match_operand:XF 2 "register_operand" "u")]
17865 (clobber (match_scratch:XF 3 "=2"))]
17866 "TARGET_USE_FANCY_MATH_387
17867 && flag_unsafe_math_optimizations"
17869 [(set_attr "type" "fpspc")
17870 (set_attr "mode" "XF")])
17872 (define_insn "fyl2x_extend<mode>xf3_i387"
17873 [(set (match_operand:XF 0 "register_operand" "=f")
17874 (unspec:XF [(float_extend:XF
17875 (match_operand:MODEF 1 "register_operand" "0"))
17876 (match_operand:XF 2 "register_operand" "u")]
17878 (clobber (match_scratch:XF 3 "=2"))]
17879 "TARGET_USE_FANCY_MATH_387
17880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17881 || TARGET_MIX_SSE_I387)
17882 && flag_unsafe_math_optimizations"
17884 [(set_attr "type" "fpspc")
17885 (set_attr "mode" "XF")])
17887 (define_expand "logxf2"
17888 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17889 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17890 (match_dup 2)] UNSPEC_FYL2X))
17891 (clobber (match_scratch:XF 3 ""))])]
17892 "TARGET_USE_FANCY_MATH_387
17893 && flag_unsafe_math_optimizations"
17895 operands[2] = gen_reg_rtx (XFmode);
17896 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17899 (define_expand "log<mode>2"
17900 [(use (match_operand:MODEF 0 "register_operand" ""))
17901 (use (match_operand:MODEF 1 "register_operand" ""))]
17902 "TARGET_USE_FANCY_MATH_387
17903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17904 || TARGET_MIX_SSE_I387)
17905 && flag_unsafe_math_optimizations"
17907 rtx op0 = gen_reg_rtx (XFmode);
17909 rtx op2 = gen_reg_rtx (XFmode);
17910 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17912 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17917 (define_expand "log10xf2"
17918 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17919 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17920 (match_dup 2)] UNSPEC_FYL2X))
17921 (clobber (match_scratch:XF 3 ""))])]
17922 "TARGET_USE_FANCY_MATH_387
17923 && flag_unsafe_math_optimizations"
17925 operands[2] = gen_reg_rtx (XFmode);
17926 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17929 (define_expand "log10<mode>2"
17930 [(use (match_operand:MODEF 0 "register_operand" ""))
17931 (use (match_operand:MODEF 1 "register_operand" ""))]
17932 "TARGET_USE_FANCY_MATH_387
17933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17934 || TARGET_MIX_SSE_I387)
17935 && flag_unsafe_math_optimizations"
17937 rtx op0 = gen_reg_rtx (XFmode);
17939 rtx op2 = gen_reg_rtx (XFmode);
17940 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17942 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17947 (define_expand "log2xf2"
17948 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17949 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17950 (match_dup 2)] UNSPEC_FYL2X))
17951 (clobber (match_scratch:XF 3 ""))])]
17952 "TARGET_USE_FANCY_MATH_387
17953 && flag_unsafe_math_optimizations"
17955 operands[2] = gen_reg_rtx (XFmode);
17956 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17959 (define_expand "log2<mode>2"
17960 [(use (match_operand:MODEF 0 "register_operand" ""))
17961 (use (match_operand:MODEF 1 "register_operand" ""))]
17962 "TARGET_USE_FANCY_MATH_387
17963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964 || TARGET_MIX_SSE_I387)
17965 && flag_unsafe_math_optimizations"
17967 rtx op0 = gen_reg_rtx (XFmode);
17969 rtx op2 = gen_reg_rtx (XFmode);
17970 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17972 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17977 (define_insn "fyl2xp1xf3_i387"
17978 [(set (match_operand:XF 0 "register_operand" "=f")
17979 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17980 (match_operand:XF 2 "register_operand" "u")]
17982 (clobber (match_scratch:XF 3 "=2"))]
17983 "TARGET_USE_FANCY_MATH_387
17984 && flag_unsafe_math_optimizations"
17986 [(set_attr "type" "fpspc")
17987 (set_attr "mode" "XF")])
17989 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17990 [(set (match_operand:XF 0 "register_operand" "=f")
17991 (unspec:XF [(float_extend:XF
17992 (match_operand:MODEF 1 "register_operand" "0"))
17993 (match_operand:XF 2 "register_operand" "u")]
17995 (clobber (match_scratch:XF 3 "=2"))]
17996 "TARGET_USE_FANCY_MATH_387
17997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17998 || TARGET_MIX_SSE_I387)
17999 && flag_unsafe_math_optimizations"
18001 [(set_attr "type" "fpspc")
18002 (set_attr "mode" "XF")])
18004 (define_expand "log1pxf2"
18005 [(use (match_operand:XF 0 "register_operand" ""))
18006 (use (match_operand:XF 1 "register_operand" ""))]
18007 "TARGET_USE_FANCY_MATH_387
18008 && flag_unsafe_math_optimizations"
18010 if (optimize_insn_for_size_p ())
18013 ix86_emit_i387_log1p (operands[0], operands[1]);
18017 (define_expand "log1p<mode>2"
18018 [(use (match_operand:MODEF 0 "register_operand" ""))
18019 (use (match_operand:MODEF 1 "register_operand" ""))]
18020 "TARGET_USE_FANCY_MATH_387
18021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18022 || TARGET_MIX_SSE_I387)
18023 && flag_unsafe_math_optimizations"
18027 if (optimize_insn_for_size_p ())
18030 op0 = gen_reg_rtx (XFmode);
18032 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18034 ix86_emit_i387_log1p (op0, operands[1]);
18035 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18039 (define_insn "fxtractxf3_i387"
18040 [(set (match_operand:XF 0 "register_operand" "=f")
18041 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18042 UNSPEC_XTRACT_FRACT))
18043 (set (match_operand:XF 1 "register_operand" "=u")
18044 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && flag_unsafe_math_optimizations"
18048 [(set_attr "type" "fpspc")
18049 (set_attr "mode" "XF")])
18051 (define_insn "fxtract_extend<mode>xf3_i387"
18052 [(set (match_operand:XF 0 "register_operand" "=f")
18053 (unspec:XF [(float_extend:XF
18054 (match_operand:MODEF 2 "register_operand" "0"))]
18055 UNSPEC_XTRACT_FRACT))
18056 (set (match_operand:XF 1 "register_operand" "=u")
18057 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18058 "TARGET_USE_FANCY_MATH_387
18059 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18060 || TARGET_MIX_SSE_I387)
18061 && flag_unsafe_math_optimizations"
18063 [(set_attr "type" "fpspc")
18064 (set_attr "mode" "XF")])
18066 (define_expand "logbxf2"
18067 [(parallel [(set (match_dup 2)
18068 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18069 UNSPEC_XTRACT_FRACT))
18070 (set (match_operand:XF 0 "register_operand" "")
18071 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18072 "TARGET_USE_FANCY_MATH_387
18073 && flag_unsafe_math_optimizations"
18075 operands[2] = gen_reg_rtx (XFmode);
18078 (define_expand "logb<mode>2"
18079 [(use (match_operand:MODEF 0 "register_operand" ""))
18080 (use (match_operand:MODEF 1 "register_operand" ""))]
18081 "TARGET_USE_FANCY_MATH_387
18082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18083 || TARGET_MIX_SSE_I387)
18084 && flag_unsafe_math_optimizations"
18086 rtx op0 = gen_reg_rtx (XFmode);
18087 rtx op1 = gen_reg_rtx (XFmode);
18089 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18090 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18094 (define_expand "ilogbxf2"
18095 [(use (match_operand:SI 0 "register_operand" ""))
18096 (use (match_operand:XF 1 "register_operand" ""))]
18097 "TARGET_USE_FANCY_MATH_387
18098 && flag_unsafe_math_optimizations"
18102 if (optimize_insn_for_size_p ())
18105 op0 = gen_reg_rtx (XFmode);
18106 op1 = gen_reg_rtx (XFmode);
18108 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18109 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18113 (define_expand "ilogb<mode>2"
18114 [(use (match_operand:SI 0 "register_operand" ""))
18115 (use (match_operand:MODEF 1 "register_operand" ""))]
18116 "TARGET_USE_FANCY_MATH_387
18117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18118 || TARGET_MIX_SSE_I387)
18119 && flag_unsafe_math_optimizations"
18123 if (optimize_insn_for_size_p ())
18126 op0 = gen_reg_rtx (XFmode);
18127 op1 = gen_reg_rtx (XFmode);
18129 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18130 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18134 (define_insn "*f2xm1xf2_i387"
18135 [(set (match_operand:XF 0 "register_operand" "=f")
18136 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18138 "TARGET_USE_FANCY_MATH_387
18139 && flag_unsafe_math_optimizations"
18141 [(set_attr "type" "fpspc")
18142 (set_attr "mode" "XF")])
18144 (define_insn "*fscalexf4_i387"
18145 [(set (match_operand:XF 0 "register_operand" "=f")
18146 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18147 (match_operand:XF 3 "register_operand" "1")]
18148 UNSPEC_FSCALE_FRACT))
18149 (set (match_operand:XF 1 "register_operand" "=u")
18150 (unspec:XF [(match_dup 2) (match_dup 3)]
18151 UNSPEC_FSCALE_EXP))]
18152 "TARGET_USE_FANCY_MATH_387
18153 && flag_unsafe_math_optimizations"
18155 [(set_attr "type" "fpspc")
18156 (set_attr "mode" "XF")])
18158 (define_expand "expNcorexf3"
18159 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18160 (match_operand:XF 2 "register_operand" "")))
18161 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18162 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18163 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18164 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18165 (parallel [(set (match_operand:XF 0 "register_operand" "")
18166 (unspec:XF [(match_dup 8) (match_dup 4)]
18167 UNSPEC_FSCALE_FRACT))
18169 (unspec:XF [(match_dup 8) (match_dup 4)]
18170 UNSPEC_FSCALE_EXP))])]
18171 "TARGET_USE_FANCY_MATH_387
18172 && flag_unsafe_math_optimizations"
18176 if (optimize_insn_for_size_p ())
18179 for (i = 3; i < 10; i++)
18180 operands[i] = gen_reg_rtx (XFmode);
18182 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
18185 (define_expand "expxf2"
18186 [(use (match_operand:XF 0 "register_operand" ""))
18187 (use (match_operand:XF 1 "register_operand" ""))]
18188 "TARGET_USE_FANCY_MATH_387
18189 && flag_unsafe_math_optimizations"
18193 if (optimize_insn_for_size_p ())
18196 op2 = gen_reg_rtx (XFmode);
18197 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18199 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18203 (define_expand "exp<mode>2"
18204 [(use (match_operand:MODEF 0 "register_operand" ""))
18205 (use (match_operand:MODEF 1 "general_operand" ""))]
18206 "TARGET_USE_FANCY_MATH_387
18207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18208 || TARGET_MIX_SSE_I387)
18209 && flag_unsafe_math_optimizations"
18213 if (optimize_insn_for_size_p ())
18216 op0 = gen_reg_rtx (XFmode);
18217 op1 = gen_reg_rtx (XFmode);
18219 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18220 emit_insn (gen_expxf2 (op0, op1));
18221 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18225 (define_expand "exp10xf2"
18226 [(use (match_operand:XF 0 "register_operand" ""))
18227 (use (match_operand:XF 1 "register_operand" ""))]
18228 "TARGET_USE_FANCY_MATH_387
18229 && flag_unsafe_math_optimizations"
18233 if (optimize_insn_for_size_p ())
18236 op2 = gen_reg_rtx (XFmode);
18237 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18239 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18243 (define_expand "exp10<mode>2"
18244 [(use (match_operand:MODEF 0 "register_operand" ""))
18245 (use (match_operand:MODEF 1 "general_operand" ""))]
18246 "TARGET_USE_FANCY_MATH_387
18247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18248 || TARGET_MIX_SSE_I387)
18249 && flag_unsafe_math_optimizations"
18253 if (optimize_insn_for_size_p ())
18256 op0 = gen_reg_rtx (XFmode);
18257 op1 = gen_reg_rtx (XFmode);
18259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18260 emit_insn (gen_exp10xf2 (op0, op1));
18261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18265 (define_expand "exp2xf2"
18266 [(use (match_operand:XF 0 "register_operand" ""))
18267 (use (match_operand:XF 1 "register_operand" ""))]
18268 "TARGET_USE_FANCY_MATH_387
18269 && flag_unsafe_math_optimizations"
18273 if (optimize_insn_for_size_p ())
18276 op2 = gen_reg_rtx (XFmode);
18277 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
18279 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18283 (define_expand "exp2<mode>2"
18284 [(use (match_operand:MODEF 0 "register_operand" ""))
18285 (use (match_operand:MODEF 1 "general_operand" ""))]
18286 "TARGET_USE_FANCY_MATH_387
18287 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18288 || TARGET_MIX_SSE_I387)
18289 && flag_unsafe_math_optimizations"
18293 if (optimize_insn_for_size_p ())
18296 op0 = gen_reg_rtx (XFmode);
18297 op1 = gen_reg_rtx (XFmode);
18299 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18300 emit_insn (gen_exp2xf2 (op0, op1));
18301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18305 (define_expand "expm1xf2"
18306 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18308 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18309 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18310 (set (match_dup 9) (float_extend:XF (match_dup 13)))
18311 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18312 (parallel [(set (match_dup 7)
18313 (unspec:XF [(match_dup 6) (match_dup 4)]
18314 UNSPEC_FSCALE_FRACT))
18316 (unspec:XF [(match_dup 6) (match_dup 4)]
18317 UNSPEC_FSCALE_EXP))])
18318 (parallel [(set (match_dup 10)
18319 (unspec:XF [(match_dup 9) (match_dup 8)]
18320 UNSPEC_FSCALE_FRACT))
18321 (set (match_dup 11)
18322 (unspec:XF [(match_dup 9) (match_dup 8)]
18323 UNSPEC_FSCALE_EXP))])
18324 (set (match_dup 12) (minus:XF (match_dup 10)
18325 (float_extend:XF (match_dup 13))))
18326 (set (match_operand:XF 0 "register_operand" "")
18327 (plus:XF (match_dup 12) (match_dup 7)))]
18328 "TARGET_USE_FANCY_MATH_387
18329 && flag_unsafe_math_optimizations"
18333 if (optimize_insn_for_size_p ())
18336 for (i = 2; i < 13; i++)
18337 operands[i] = gen_reg_rtx (XFmode);
18340 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18342 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18345 (define_expand "expm1<mode>2"
18346 [(use (match_operand:MODEF 0 "register_operand" ""))
18347 (use (match_operand:MODEF 1 "general_operand" ""))]
18348 "TARGET_USE_FANCY_MATH_387
18349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18350 || TARGET_MIX_SSE_I387)
18351 && flag_unsafe_math_optimizations"
18355 if (optimize_insn_for_size_p ())
18358 op0 = gen_reg_rtx (XFmode);
18359 op1 = gen_reg_rtx (XFmode);
18361 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18362 emit_insn (gen_expm1xf2 (op0, op1));
18363 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18367 (define_expand "ldexpxf3"
18368 [(set (match_dup 3)
18369 (float:XF (match_operand:SI 2 "register_operand" "")))
18370 (parallel [(set (match_operand:XF 0 " register_operand" "")
18371 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18373 UNSPEC_FSCALE_FRACT))
18375 (unspec:XF [(match_dup 1) (match_dup 3)]
18376 UNSPEC_FSCALE_EXP))])]
18377 "TARGET_USE_FANCY_MATH_387
18378 && flag_unsafe_math_optimizations"
18380 if (optimize_insn_for_size_p ())
18383 operands[3] = gen_reg_rtx (XFmode);
18384 operands[4] = gen_reg_rtx (XFmode);
18387 (define_expand "ldexp<mode>3"
18388 [(use (match_operand:MODEF 0 "register_operand" ""))
18389 (use (match_operand:MODEF 1 "general_operand" ""))
18390 (use (match_operand:SI 2 "register_operand" ""))]
18391 "TARGET_USE_FANCY_MATH_387
18392 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18393 || TARGET_MIX_SSE_I387)
18394 && flag_unsafe_math_optimizations"
18398 if (optimize_insn_for_size_p ())
18401 op0 = gen_reg_rtx (XFmode);
18402 op1 = gen_reg_rtx (XFmode);
18404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18405 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18406 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18410 (define_expand "scalbxf3"
18411 [(parallel [(set (match_operand:XF 0 " register_operand" "")
18412 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18413 (match_operand:XF 2 "register_operand" "")]
18414 UNSPEC_FSCALE_FRACT))
18416 (unspec:XF [(match_dup 1) (match_dup 2)]
18417 UNSPEC_FSCALE_EXP))])]
18418 "TARGET_USE_FANCY_MATH_387
18419 && flag_unsafe_math_optimizations"
18421 if (optimize_insn_for_size_p ())
18424 operands[3] = gen_reg_rtx (XFmode);
18427 (define_expand "scalb<mode>3"
18428 [(use (match_operand:MODEF 0 "register_operand" ""))
18429 (use (match_operand:MODEF 1 "general_operand" ""))
18430 (use (match_operand:MODEF 2 "general_operand" ""))]
18431 "TARGET_USE_FANCY_MATH_387
18432 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18433 || TARGET_MIX_SSE_I387)
18434 && flag_unsafe_math_optimizations"
18438 if (optimize_insn_for_size_p ())
18441 op0 = gen_reg_rtx (XFmode);
18442 op1 = gen_reg_rtx (XFmode);
18443 op2 = gen_reg_rtx (XFmode);
18445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18446 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18447 emit_insn (gen_scalbxf3 (op0, op1, op2));
18448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18452 (define_expand "significandxf2"
18453 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18454 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18455 UNSPEC_XTRACT_FRACT))
18457 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18458 "TARGET_USE_FANCY_MATH_387
18459 && flag_unsafe_math_optimizations"
18461 operands[2] = gen_reg_rtx (XFmode);
18464 (define_expand "significand<mode>2"
18465 [(use (match_operand:MODEF 0 "register_operand" ""))
18466 (use (match_operand:MODEF 1 "register_operand" ""))]
18467 "TARGET_USE_FANCY_MATH_387
18468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18469 || TARGET_MIX_SSE_I387)
18470 && flag_unsafe_math_optimizations"
18472 rtx op0 = gen_reg_rtx (XFmode);
18473 rtx op1 = gen_reg_rtx (XFmode);
18475 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18481 (define_insn "sse4_1_round<mode>2"
18482 [(set (match_operand:MODEF 0 "register_operand" "=x")
18483 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18484 (match_operand:SI 2 "const_0_to_15_operand" "n")]
18487 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18488 [(set_attr "type" "ssecvt")
18489 (set_attr "prefix_extra" "1")
18490 (set_attr "prefix" "maybe_vex")
18491 (set_attr "mode" "<MODE>")])
18493 (define_insn "rintxf2"
18494 [(set (match_operand:XF 0 "register_operand" "=f")
18495 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18497 "TARGET_USE_FANCY_MATH_387
18498 && flag_unsafe_math_optimizations"
18500 [(set_attr "type" "fpspc")
18501 (set_attr "mode" "XF")])
18503 (define_expand "rint<mode>2"
18504 [(use (match_operand:MODEF 0 "register_operand" ""))
18505 (use (match_operand:MODEF 1 "register_operand" ""))]
18506 "(TARGET_USE_FANCY_MATH_387
18507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18508 || TARGET_MIX_SSE_I387)
18509 && flag_unsafe_math_optimizations)
18510 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18511 && !flag_trapping_math)"
18513 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18514 && !flag_trapping_math)
18516 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18519 emit_insn (gen_sse4_1_round<mode>2
18520 (operands[0], operands[1], GEN_INT (0x04)));
18522 ix86_expand_rint (operand0, operand1);
18526 rtx op0 = gen_reg_rtx (XFmode);
18527 rtx op1 = gen_reg_rtx (XFmode);
18529 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18530 emit_insn (gen_rintxf2 (op0, op1));
18532 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18537 (define_expand "round<mode>2"
18538 [(match_operand:MODEF 0 "register_operand" "")
18539 (match_operand:MODEF 1 "nonimmediate_operand" "")]
18540 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18541 && !flag_trapping_math && !flag_rounding_math"
18543 if (optimize_insn_for_size_p ())
18545 if (TARGET_64BIT || (<MODE>mode != DFmode))
18546 ix86_expand_round (operand0, operand1);
18548 ix86_expand_rounddf_32 (operand0, operand1);
18552 (define_insn_and_split "*fistdi2_1"
18553 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18554 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18556 "TARGET_USE_FANCY_MATH_387
18557 && can_create_pseudo_p ()"
18562 if (memory_operand (operands[0], VOIDmode))
18563 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18566 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18567 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18572 [(set_attr "type" "fpspc")
18573 (set_attr "mode" "DI")])
18575 (define_insn "fistdi2"
18576 [(set (match_operand:DI 0 "memory_operand" "=m")
18577 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18579 (clobber (match_scratch:XF 2 "=&1f"))]
18580 "TARGET_USE_FANCY_MATH_387"
18581 "* return output_fix_trunc (insn, operands, 0);"
18582 [(set_attr "type" "fpspc")
18583 (set_attr "mode" "DI")])
18585 (define_insn "fistdi2_with_temp"
18586 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18587 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18589 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18590 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18591 "TARGET_USE_FANCY_MATH_387"
18593 [(set_attr "type" "fpspc")
18594 (set_attr "mode" "DI")])
18597 [(set (match_operand:DI 0 "register_operand" "")
18598 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18600 (clobber (match_operand:DI 2 "memory_operand" ""))
18601 (clobber (match_scratch 3 ""))]
18603 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18604 (clobber (match_dup 3))])
18605 (set (match_dup 0) (match_dup 2))]
18609 [(set (match_operand:DI 0 "memory_operand" "")
18610 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18612 (clobber (match_operand:DI 2 "memory_operand" ""))
18613 (clobber (match_scratch 3 ""))]
18615 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18616 (clobber (match_dup 3))])]
18619 (define_insn_and_split "*fist<mode>2_1"
18620 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18621 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18623 "TARGET_USE_FANCY_MATH_387
18624 && can_create_pseudo_p ()"
18629 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18630 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18634 [(set_attr "type" "fpspc")
18635 (set_attr "mode" "<MODE>")])
18637 (define_insn "fist<mode>2"
18638 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18639 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18641 "TARGET_USE_FANCY_MATH_387"
18642 "* return output_fix_trunc (insn, operands, 0);"
18643 [(set_attr "type" "fpspc")
18644 (set_attr "mode" "<MODE>")])
18646 (define_insn "fist<mode>2_with_temp"
18647 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18648 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18650 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18651 "TARGET_USE_FANCY_MATH_387"
18653 [(set_attr "type" "fpspc")
18654 (set_attr "mode" "<MODE>")])
18657 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18658 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18660 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18662 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18663 (set (match_dup 0) (match_dup 2))]
18667 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18668 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18670 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18672 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18675 (define_expand "lrintxf<mode>2"
18676 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18677 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18679 "TARGET_USE_FANCY_MATH_387"
18682 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18683 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18684 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18685 UNSPEC_FIX_NOTRUNC))]
18686 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18687 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18690 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18691 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18692 (match_operand:MODEF 1 "register_operand" "")]
18693 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18694 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18695 && !flag_trapping_math && !flag_rounding_math"
18697 if (optimize_insn_for_size_p ())
18699 ix86_expand_lround (operand0, operand1);
18703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18704 (define_insn_and_split "frndintxf2_floor"
18705 [(set (match_operand:XF 0 "register_operand" "")
18706 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18707 UNSPEC_FRNDINT_FLOOR))
18708 (clobber (reg:CC FLAGS_REG))]
18709 "TARGET_USE_FANCY_MATH_387
18710 && flag_unsafe_math_optimizations
18711 && can_create_pseudo_p ()"
18716 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18718 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18719 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18721 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18722 operands[2], operands[3]));
18725 [(set_attr "type" "frndint")
18726 (set_attr "i387_cw" "floor")
18727 (set_attr "mode" "XF")])
18729 (define_insn "frndintxf2_floor_i387"
18730 [(set (match_operand:XF 0 "register_operand" "=f")
18731 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18732 UNSPEC_FRNDINT_FLOOR))
18733 (use (match_operand:HI 2 "memory_operand" "m"))
18734 (use (match_operand:HI 3 "memory_operand" "m"))]
18735 "TARGET_USE_FANCY_MATH_387
18736 && flag_unsafe_math_optimizations"
18737 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18738 [(set_attr "type" "frndint")
18739 (set_attr "i387_cw" "floor")
18740 (set_attr "mode" "XF")])
18742 (define_expand "floorxf2"
18743 [(use (match_operand:XF 0 "register_operand" ""))
18744 (use (match_operand:XF 1 "register_operand" ""))]
18745 "TARGET_USE_FANCY_MATH_387
18746 && flag_unsafe_math_optimizations"
18748 if (optimize_insn_for_size_p ())
18750 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18754 (define_expand "floor<mode>2"
18755 [(use (match_operand:MODEF 0 "register_operand" ""))
18756 (use (match_operand:MODEF 1 "register_operand" ""))]
18757 "(TARGET_USE_FANCY_MATH_387
18758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759 || TARGET_MIX_SSE_I387)
18760 && flag_unsafe_math_optimizations)
18761 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18762 && !flag_trapping_math)"
18764 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18765 && !flag_trapping_math
18766 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18768 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18771 emit_insn (gen_sse4_1_round<mode>2
18772 (operands[0], operands[1], GEN_INT (0x01)));
18773 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18774 ix86_expand_floorceil (operand0, operand1, true);
18776 ix86_expand_floorceildf_32 (operand0, operand1, true);
18782 if (optimize_insn_for_size_p ())
18785 op0 = gen_reg_rtx (XFmode);
18786 op1 = gen_reg_rtx (XFmode);
18787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18788 emit_insn (gen_frndintxf2_floor (op0, op1));
18790 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18795 (define_insn_and_split "*fist<mode>2_floor_1"
18796 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18797 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18798 UNSPEC_FIST_FLOOR))
18799 (clobber (reg:CC FLAGS_REG))]
18800 "TARGET_USE_FANCY_MATH_387
18801 && flag_unsafe_math_optimizations
18802 && can_create_pseudo_p ()"
18807 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18809 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18810 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18811 if (memory_operand (operands[0], VOIDmode))
18812 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18813 operands[2], operands[3]));
18816 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18817 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18818 operands[2], operands[3],
18823 [(set_attr "type" "fistp")
18824 (set_attr "i387_cw" "floor")
18825 (set_attr "mode" "<MODE>")])
18827 (define_insn "fistdi2_floor"
18828 [(set (match_operand:DI 0 "memory_operand" "=m")
18829 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18830 UNSPEC_FIST_FLOOR))
18831 (use (match_operand:HI 2 "memory_operand" "m"))
18832 (use (match_operand:HI 3 "memory_operand" "m"))
18833 (clobber (match_scratch:XF 4 "=&1f"))]
18834 "TARGET_USE_FANCY_MATH_387
18835 && flag_unsafe_math_optimizations"
18836 "* return output_fix_trunc (insn, operands, 0);"
18837 [(set_attr "type" "fistp")
18838 (set_attr "i387_cw" "floor")
18839 (set_attr "mode" "DI")])
18841 (define_insn "fistdi2_floor_with_temp"
18842 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18843 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18844 UNSPEC_FIST_FLOOR))
18845 (use (match_operand:HI 2 "memory_operand" "m,m"))
18846 (use (match_operand:HI 3 "memory_operand" "m,m"))
18847 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18848 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18849 "TARGET_USE_FANCY_MATH_387
18850 && flag_unsafe_math_optimizations"
18852 [(set_attr "type" "fistp")
18853 (set_attr "i387_cw" "floor")
18854 (set_attr "mode" "DI")])
18857 [(set (match_operand:DI 0 "register_operand" "")
18858 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18859 UNSPEC_FIST_FLOOR))
18860 (use (match_operand:HI 2 "memory_operand" ""))
18861 (use (match_operand:HI 3 "memory_operand" ""))
18862 (clobber (match_operand:DI 4 "memory_operand" ""))
18863 (clobber (match_scratch 5 ""))]
18865 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18866 (use (match_dup 2))
18867 (use (match_dup 3))
18868 (clobber (match_dup 5))])
18869 (set (match_dup 0) (match_dup 4))]
18873 [(set (match_operand:DI 0 "memory_operand" "")
18874 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18875 UNSPEC_FIST_FLOOR))
18876 (use (match_operand:HI 2 "memory_operand" ""))
18877 (use (match_operand:HI 3 "memory_operand" ""))
18878 (clobber (match_operand:DI 4 "memory_operand" ""))
18879 (clobber (match_scratch 5 ""))]
18881 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18882 (use (match_dup 2))
18883 (use (match_dup 3))
18884 (clobber (match_dup 5))])]
18887 (define_insn "fist<mode>2_floor"
18888 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18889 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18890 UNSPEC_FIST_FLOOR))
18891 (use (match_operand:HI 2 "memory_operand" "m"))
18892 (use (match_operand:HI 3 "memory_operand" "m"))]
18893 "TARGET_USE_FANCY_MATH_387
18894 && flag_unsafe_math_optimizations"
18895 "* return output_fix_trunc (insn, operands, 0);"
18896 [(set_attr "type" "fistp")
18897 (set_attr "i387_cw" "floor")
18898 (set_attr "mode" "<MODE>")])
18900 (define_insn "fist<mode>2_floor_with_temp"
18901 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18902 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18903 UNSPEC_FIST_FLOOR))
18904 (use (match_operand:HI 2 "memory_operand" "m,m"))
18905 (use (match_operand:HI 3 "memory_operand" "m,m"))
18906 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18907 "TARGET_USE_FANCY_MATH_387
18908 && flag_unsafe_math_optimizations"
18910 [(set_attr "type" "fistp")
18911 (set_attr "i387_cw" "floor")
18912 (set_attr "mode" "<MODE>")])
18915 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18916 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18917 UNSPEC_FIST_FLOOR))
18918 (use (match_operand:HI 2 "memory_operand" ""))
18919 (use (match_operand:HI 3 "memory_operand" ""))
18920 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18922 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18923 UNSPEC_FIST_FLOOR))
18924 (use (match_dup 2))
18925 (use (match_dup 3))])
18926 (set (match_dup 0) (match_dup 4))]
18930 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18931 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18932 UNSPEC_FIST_FLOOR))
18933 (use (match_operand:HI 2 "memory_operand" ""))
18934 (use (match_operand:HI 3 "memory_operand" ""))
18935 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18937 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18938 UNSPEC_FIST_FLOOR))
18939 (use (match_dup 2))
18940 (use (match_dup 3))])]
18943 (define_expand "lfloorxf<mode>2"
18944 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18945 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18946 UNSPEC_FIST_FLOOR))
18947 (clobber (reg:CC FLAGS_REG))])]
18948 "TARGET_USE_FANCY_MATH_387
18949 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18950 && flag_unsafe_math_optimizations"
18953 (define_expand "lfloor<mode>di2"
18954 [(match_operand:DI 0 "nonimmediate_operand" "")
18955 (match_operand:MODEF 1 "register_operand" "")]
18956 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18957 && !flag_trapping_math"
18959 if (optimize_insn_for_size_p ())
18961 ix86_expand_lfloorceil (operand0, operand1, true);
18965 (define_expand "lfloor<mode>si2"
18966 [(match_operand:SI 0 "nonimmediate_operand" "")
18967 (match_operand:MODEF 1 "register_operand" "")]
18968 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18969 && !flag_trapping_math"
18971 if (optimize_insn_for_size_p () && TARGET_64BIT)
18973 ix86_expand_lfloorceil (operand0, operand1, true);
18977 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18978 (define_insn_and_split "frndintxf2_ceil"
18979 [(set (match_operand:XF 0 "register_operand" "")
18980 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18981 UNSPEC_FRNDINT_CEIL))
18982 (clobber (reg:CC FLAGS_REG))]
18983 "TARGET_USE_FANCY_MATH_387
18984 && flag_unsafe_math_optimizations
18985 && can_create_pseudo_p ()"
18990 ix86_optimize_mode_switching[I387_CEIL] = 1;
18992 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18993 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18995 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18996 operands[2], operands[3]));
18999 [(set_attr "type" "frndint")
19000 (set_attr "i387_cw" "ceil")
19001 (set_attr "mode" "XF")])
19003 (define_insn "frndintxf2_ceil_i387"
19004 [(set (match_operand:XF 0 "register_operand" "=f")
19005 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19006 UNSPEC_FRNDINT_CEIL))
19007 (use (match_operand:HI 2 "memory_operand" "m"))
19008 (use (match_operand:HI 3 "memory_operand" "m"))]
19009 "TARGET_USE_FANCY_MATH_387
19010 && flag_unsafe_math_optimizations"
19011 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19012 [(set_attr "type" "frndint")
19013 (set_attr "i387_cw" "ceil")
19014 (set_attr "mode" "XF")])
19016 (define_expand "ceilxf2"
19017 [(use (match_operand:XF 0 "register_operand" ""))
19018 (use (match_operand:XF 1 "register_operand" ""))]
19019 "TARGET_USE_FANCY_MATH_387
19020 && flag_unsafe_math_optimizations"
19022 if (optimize_insn_for_size_p ())
19024 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19028 (define_expand "ceil<mode>2"
19029 [(use (match_operand:MODEF 0 "register_operand" ""))
19030 (use (match_operand:MODEF 1 "register_operand" ""))]
19031 "(TARGET_USE_FANCY_MATH_387
19032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19033 || TARGET_MIX_SSE_I387)
19034 && flag_unsafe_math_optimizations)
19035 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19036 && !flag_trapping_math)"
19038 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19039 && !flag_trapping_math
19040 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19043 emit_insn (gen_sse4_1_round<mode>2
19044 (operands[0], operands[1], GEN_INT (0x02)));
19045 else if (optimize_insn_for_size_p ())
19047 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19048 ix86_expand_floorceil (operand0, operand1, false);
19050 ix86_expand_floorceildf_32 (operand0, operand1, false);
19056 if (optimize_insn_for_size_p ())
19059 op0 = gen_reg_rtx (XFmode);
19060 op1 = gen_reg_rtx (XFmode);
19061 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19062 emit_insn (gen_frndintxf2_ceil (op0, op1));
19064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19069 (define_insn_and_split "*fist<mode>2_ceil_1"
19070 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19071 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19073 (clobber (reg:CC FLAGS_REG))]
19074 "TARGET_USE_FANCY_MATH_387
19075 && flag_unsafe_math_optimizations
19076 && can_create_pseudo_p ()"
19081 ix86_optimize_mode_switching[I387_CEIL] = 1;
19083 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19084 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19085 if (memory_operand (operands[0], VOIDmode))
19086 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19087 operands[2], operands[3]));
19090 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19091 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19092 operands[2], operands[3],
19097 [(set_attr "type" "fistp")
19098 (set_attr "i387_cw" "ceil")
19099 (set_attr "mode" "<MODE>")])
19101 (define_insn "fistdi2_ceil"
19102 [(set (match_operand:DI 0 "memory_operand" "=m")
19103 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19105 (use (match_operand:HI 2 "memory_operand" "m"))
19106 (use (match_operand:HI 3 "memory_operand" "m"))
19107 (clobber (match_scratch:XF 4 "=&1f"))]
19108 "TARGET_USE_FANCY_MATH_387
19109 && flag_unsafe_math_optimizations"
19110 "* return output_fix_trunc (insn, operands, 0);"
19111 [(set_attr "type" "fistp")
19112 (set_attr "i387_cw" "ceil")
19113 (set_attr "mode" "DI")])
19115 (define_insn "fistdi2_ceil_with_temp"
19116 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19117 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19119 (use (match_operand:HI 2 "memory_operand" "m,m"))
19120 (use (match_operand:HI 3 "memory_operand" "m,m"))
19121 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19122 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19123 "TARGET_USE_FANCY_MATH_387
19124 && flag_unsafe_math_optimizations"
19126 [(set_attr "type" "fistp")
19127 (set_attr "i387_cw" "ceil")
19128 (set_attr "mode" "DI")])
19131 [(set (match_operand:DI 0 "register_operand" "")
19132 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19134 (use (match_operand:HI 2 "memory_operand" ""))
19135 (use (match_operand:HI 3 "memory_operand" ""))
19136 (clobber (match_operand:DI 4 "memory_operand" ""))
19137 (clobber (match_scratch 5 ""))]
19139 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19140 (use (match_dup 2))
19141 (use (match_dup 3))
19142 (clobber (match_dup 5))])
19143 (set (match_dup 0) (match_dup 4))]
19147 [(set (match_operand:DI 0 "memory_operand" "")
19148 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19150 (use (match_operand:HI 2 "memory_operand" ""))
19151 (use (match_operand:HI 3 "memory_operand" ""))
19152 (clobber (match_operand:DI 4 "memory_operand" ""))
19153 (clobber (match_scratch 5 ""))]
19155 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19156 (use (match_dup 2))
19157 (use (match_dup 3))
19158 (clobber (match_dup 5))])]
19161 (define_insn "fist<mode>2_ceil"
19162 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19163 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19165 (use (match_operand:HI 2 "memory_operand" "m"))
19166 (use (match_operand:HI 3 "memory_operand" "m"))]
19167 "TARGET_USE_FANCY_MATH_387
19168 && flag_unsafe_math_optimizations"
19169 "* return output_fix_trunc (insn, operands, 0);"
19170 [(set_attr "type" "fistp")
19171 (set_attr "i387_cw" "ceil")
19172 (set_attr "mode" "<MODE>")])
19174 (define_insn "fist<mode>2_ceil_with_temp"
19175 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19176 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19178 (use (match_operand:HI 2 "memory_operand" "m,m"))
19179 (use (match_operand:HI 3 "memory_operand" "m,m"))
19180 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19181 "TARGET_USE_FANCY_MATH_387
19182 && flag_unsafe_math_optimizations"
19184 [(set_attr "type" "fistp")
19185 (set_attr "i387_cw" "ceil")
19186 (set_attr "mode" "<MODE>")])
19189 [(set (match_operand:X87MODEI12 0 "register_operand" "")
19190 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19192 (use (match_operand:HI 2 "memory_operand" ""))
19193 (use (match_operand:HI 3 "memory_operand" ""))
19194 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19196 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19198 (use (match_dup 2))
19199 (use (match_dup 3))])
19200 (set (match_dup 0) (match_dup 4))]
19204 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19205 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19207 (use (match_operand:HI 2 "memory_operand" ""))
19208 (use (match_operand:HI 3 "memory_operand" ""))
19209 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19211 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19213 (use (match_dup 2))
19214 (use (match_dup 3))])]
19217 (define_expand "lceilxf<mode>2"
19218 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19219 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19221 (clobber (reg:CC FLAGS_REG))])]
19222 "TARGET_USE_FANCY_MATH_387
19223 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19224 && flag_unsafe_math_optimizations"
19227 (define_expand "lceil<mode>di2"
19228 [(match_operand:DI 0 "nonimmediate_operand" "")
19229 (match_operand:MODEF 1 "register_operand" "")]
19230 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19231 && !flag_trapping_math"
19233 ix86_expand_lfloorceil (operand0, operand1, false);
19237 (define_expand "lceil<mode>si2"
19238 [(match_operand:SI 0 "nonimmediate_operand" "")
19239 (match_operand:MODEF 1 "register_operand" "")]
19240 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19241 && !flag_trapping_math"
19243 ix86_expand_lfloorceil (operand0, operand1, false);
19247 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19248 (define_insn_and_split "frndintxf2_trunc"
19249 [(set (match_operand:XF 0 "register_operand" "")
19250 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19251 UNSPEC_FRNDINT_TRUNC))
19252 (clobber (reg:CC FLAGS_REG))]
19253 "TARGET_USE_FANCY_MATH_387
19254 && flag_unsafe_math_optimizations
19255 && can_create_pseudo_p ()"
19260 ix86_optimize_mode_switching[I387_TRUNC] = 1;
19262 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19263 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19265 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19266 operands[2], operands[3]));
19269 [(set_attr "type" "frndint")
19270 (set_attr "i387_cw" "trunc")
19271 (set_attr "mode" "XF")])
19273 (define_insn "frndintxf2_trunc_i387"
19274 [(set (match_operand:XF 0 "register_operand" "=f")
19275 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19276 UNSPEC_FRNDINT_TRUNC))
19277 (use (match_operand:HI 2 "memory_operand" "m"))
19278 (use (match_operand:HI 3 "memory_operand" "m"))]
19279 "TARGET_USE_FANCY_MATH_387
19280 && flag_unsafe_math_optimizations"
19281 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19282 [(set_attr "type" "frndint")
19283 (set_attr "i387_cw" "trunc")
19284 (set_attr "mode" "XF")])
19286 (define_expand "btruncxf2"
19287 [(use (match_operand:XF 0 "register_operand" ""))
19288 (use (match_operand:XF 1 "register_operand" ""))]
19289 "TARGET_USE_FANCY_MATH_387
19290 && flag_unsafe_math_optimizations"
19292 if (optimize_insn_for_size_p ())
19294 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19298 (define_expand "btrunc<mode>2"
19299 [(use (match_operand:MODEF 0 "register_operand" ""))
19300 (use (match_operand:MODEF 1 "register_operand" ""))]
19301 "(TARGET_USE_FANCY_MATH_387
19302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19303 || TARGET_MIX_SSE_I387)
19304 && flag_unsafe_math_optimizations)
19305 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19306 && !flag_trapping_math)"
19308 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19309 && !flag_trapping_math
19310 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19313 emit_insn (gen_sse4_1_round<mode>2
19314 (operands[0], operands[1], GEN_INT (0x03)));
19315 else if (optimize_insn_for_size_p ())
19317 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19318 ix86_expand_trunc (operand0, operand1);
19320 ix86_expand_truncdf_32 (operand0, operand1);
19326 if (optimize_insn_for_size_p ())
19329 op0 = gen_reg_rtx (XFmode);
19330 op1 = gen_reg_rtx (XFmode);
19331 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19332 emit_insn (gen_frndintxf2_trunc (op0, op1));
19334 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19339 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19340 (define_insn_and_split "frndintxf2_mask_pm"
19341 [(set (match_operand:XF 0 "register_operand" "")
19342 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19343 UNSPEC_FRNDINT_MASK_PM))
19344 (clobber (reg:CC FLAGS_REG))]
19345 "TARGET_USE_FANCY_MATH_387
19346 && flag_unsafe_math_optimizations
19347 && can_create_pseudo_p ()"
19352 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19354 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19355 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19357 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19358 operands[2], operands[3]));
19361 [(set_attr "type" "frndint")
19362 (set_attr "i387_cw" "mask_pm")
19363 (set_attr "mode" "XF")])
19365 (define_insn "frndintxf2_mask_pm_i387"
19366 [(set (match_operand:XF 0 "register_operand" "=f")
19367 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19368 UNSPEC_FRNDINT_MASK_PM))
19369 (use (match_operand:HI 2 "memory_operand" "m"))
19370 (use (match_operand:HI 3 "memory_operand" "m"))]
19371 "TARGET_USE_FANCY_MATH_387
19372 && flag_unsafe_math_optimizations"
19373 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19374 [(set_attr "type" "frndint")
19375 (set_attr "i387_cw" "mask_pm")
19376 (set_attr "mode" "XF")])
19378 (define_expand "nearbyintxf2"
19379 [(use (match_operand:XF 0 "register_operand" ""))
19380 (use (match_operand:XF 1 "register_operand" ""))]
19381 "TARGET_USE_FANCY_MATH_387
19382 && flag_unsafe_math_optimizations"
19384 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19389 (define_expand "nearbyint<mode>2"
19390 [(use (match_operand:MODEF 0 "register_operand" ""))
19391 (use (match_operand:MODEF 1 "register_operand" ""))]
19392 "TARGET_USE_FANCY_MATH_387
19393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19394 || TARGET_MIX_SSE_I387)
19395 && flag_unsafe_math_optimizations"
19397 rtx op0 = gen_reg_rtx (XFmode);
19398 rtx op1 = gen_reg_rtx (XFmode);
19400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19401 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19403 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19407 (define_insn "fxam<mode>2_i387"
19408 [(set (match_operand:HI 0 "register_operand" "=a")
19410 [(match_operand:X87MODEF 1 "register_operand" "f")]
19412 "TARGET_USE_FANCY_MATH_387"
19413 "fxam\n\tfnstsw\t%0"
19414 [(set_attr "type" "multi")
19415 (set_attr "length" "4")
19416 (set_attr "unit" "i387")
19417 (set_attr "mode" "<MODE>")])
19419 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19420 [(set (match_operand:HI 0 "register_operand" "")
19422 [(match_operand:MODEF 1 "memory_operand" "")]
19424 "TARGET_USE_FANCY_MATH_387
19425 && can_create_pseudo_p ()"
19428 [(set (match_dup 2)(match_dup 1))
19430 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19432 operands[2] = gen_reg_rtx (<MODE>mode);
19434 MEM_VOLATILE_P (operands[1]) = 1;
19436 [(set_attr "type" "multi")
19437 (set_attr "unit" "i387")
19438 (set_attr "mode" "<MODE>")])
19440 (define_expand "isinfxf2"
19441 [(use (match_operand:SI 0 "register_operand" ""))
19442 (use (match_operand:XF 1 "register_operand" ""))]
19443 "TARGET_USE_FANCY_MATH_387
19444 && TARGET_C99_FUNCTIONS"
19446 rtx mask = GEN_INT (0x45);
19447 rtx val = GEN_INT (0x05);
19451 rtx scratch = gen_reg_rtx (HImode);
19452 rtx res = gen_reg_rtx (QImode);
19454 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19456 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19457 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19458 cond = gen_rtx_fmt_ee (EQ, QImode,
19459 gen_rtx_REG (CCmode, FLAGS_REG),
19461 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19462 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19466 (define_expand "isinf<mode>2"
19467 [(use (match_operand:SI 0 "register_operand" ""))
19468 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19469 "TARGET_USE_FANCY_MATH_387
19470 && TARGET_C99_FUNCTIONS
19471 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19473 rtx mask = GEN_INT (0x45);
19474 rtx val = GEN_INT (0x05);
19478 rtx scratch = gen_reg_rtx (HImode);
19479 rtx res = gen_reg_rtx (QImode);
19481 /* Remove excess precision by forcing value through memory. */
19482 if (memory_operand (operands[1], VOIDmode))
19483 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19486 enum ix86_stack_slot slot = (virtuals_instantiated
19489 rtx temp = assign_386_stack_local (<MODE>mode, slot);
19491 emit_move_insn (temp, operands[1]);
19492 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19495 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19496 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19497 cond = gen_rtx_fmt_ee (EQ, QImode,
19498 gen_rtx_REG (CCmode, FLAGS_REG),
19500 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19501 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19505 (define_expand "signbit<mode>2"
19506 [(use (match_operand:SI 0 "register_operand" ""))
19507 (use (match_operand:X87MODEF 1 "register_operand" ""))]
19508 "TARGET_USE_FANCY_MATH_387
19509 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19511 rtx mask = GEN_INT (0x0200);
19513 rtx scratch = gen_reg_rtx (HImode);
19515 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19516 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19520 ;; Block operation instructions
19523 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19526 [(set_attr "length" "1")
19527 (set_attr "length_immediate" "0")
19528 (set_attr "modrm" "0")])
19530 (define_expand "movmemsi"
19531 [(use (match_operand:BLK 0 "memory_operand" ""))
19532 (use (match_operand:BLK 1 "memory_operand" ""))
19533 (use (match_operand:SI 2 "nonmemory_operand" ""))
19534 (use (match_operand:SI 3 "const_int_operand" ""))
19535 (use (match_operand:SI 4 "const_int_operand" ""))
19536 (use (match_operand:SI 5 "const_int_operand" ""))]
19539 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19540 operands[4], operands[5]))
19546 (define_expand "movmemdi"
19547 [(use (match_operand:BLK 0 "memory_operand" ""))
19548 (use (match_operand:BLK 1 "memory_operand" ""))
19549 (use (match_operand:DI 2 "nonmemory_operand" ""))
19550 (use (match_operand:DI 3 "const_int_operand" ""))
19551 (use (match_operand:SI 4 "const_int_operand" ""))
19552 (use (match_operand:SI 5 "const_int_operand" ""))]
19555 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19556 operands[4], operands[5]))
19562 ;; Most CPUs don't like single string operations
19563 ;; Handle this case here to simplify previous expander.
19565 (define_expand "strmov"
19566 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19567 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19568 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19569 (clobber (reg:CC FLAGS_REG))])
19570 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19571 (clobber (reg:CC FLAGS_REG))])]
19574 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19576 /* If .md ever supports :P for Pmode, these can be directly
19577 in the pattern above. */
19578 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19579 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19581 /* Can't use this if the user has appropriated esi or edi. */
19582 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19583 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19585 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19586 operands[2], operands[3],
19587 operands[5], operands[6]));
19591 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19594 (define_expand "strmov_singleop"
19595 [(parallel [(set (match_operand 1 "memory_operand" "")
19596 (match_operand 3 "memory_operand" ""))
19597 (set (match_operand 0 "register_operand" "")
19598 (match_operand 4 "" ""))
19599 (set (match_operand 2 "register_operand" "")
19600 (match_operand 5 "" ""))])]
19602 "ix86_current_function_needs_cld = 1;")
19604 (define_insn "*strmovdi_rex_1"
19605 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19606 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19607 (set (match_operand:DI 0 "register_operand" "=D")
19608 (plus:DI (match_dup 2)
19610 (set (match_operand:DI 1 "register_operand" "=S")
19611 (plus:DI (match_dup 3)
19615 [(set_attr "type" "str")
19616 (set_attr "mode" "DI")
19617 (set_attr "memory" "both")])
19619 (define_insn "*strmovsi_1"
19620 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19621 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19622 (set (match_operand:SI 0 "register_operand" "=D")
19623 (plus:SI (match_dup 2)
19625 (set (match_operand:SI 1 "register_operand" "=S")
19626 (plus:SI (match_dup 3)
19630 [(set_attr "type" "str")
19631 (set_attr "mode" "SI")
19632 (set_attr "memory" "both")])
19634 (define_insn "*strmovsi_rex_1"
19635 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19636 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19637 (set (match_operand:DI 0 "register_operand" "=D")
19638 (plus:DI (match_dup 2)
19640 (set (match_operand:DI 1 "register_operand" "=S")
19641 (plus:DI (match_dup 3)
19645 [(set_attr "type" "str")
19646 (set_attr "mode" "SI")
19647 (set_attr "memory" "both")])
19649 (define_insn "*strmovhi_1"
19650 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19651 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19652 (set (match_operand:SI 0 "register_operand" "=D")
19653 (plus:SI (match_dup 2)
19655 (set (match_operand:SI 1 "register_operand" "=S")
19656 (plus:SI (match_dup 3)
19660 [(set_attr "type" "str")
19661 (set_attr "memory" "both")
19662 (set_attr "mode" "HI")])
19664 (define_insn "*strmovhi_rex_1"
19665 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19666 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19667 (set (match_operand:DI 0 "register_operand" "=D")
19668 (plus:DI (match_dup 2)
19670 (set (match_operand:DI 1 "register_operand" "=S")
19671 (plus:DI (match_dup 3)
19675 [(set_attr "type" "str")
19676 (set_attr "memory" "both")
19677 (set_attr "mode" "HI")])
19679 (define_insn "*strmovqi_1"
19680 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19681 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19682 (set (match_operand:SI 0 "register_operand" "=D")
19683 (plus:SI (match_dup 2)
19685 (set (match_operand:SI 1 "register_operand" "=S")
19686 (plus:SI (match_dup 3)
19690 [(set_attr "type" "str")
19691 (set_attr "memory" "both")
19692 (set_attr "mode" "QI")])
19694 (define_insn "*strmovqi_rex_1"
19695 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19696 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19697 (set (match_operand:DI 0 "register_operand" "=D")
19698 (plus:DI (match_dup 2)
19700 (set (match_operand:DI 1 "register_operand" "=S")
19701 (plus:DI (match_dup 3)
19705 [(set_attr "type" "str")
19706 (set_attr "memory" "both")
19707 (set_attr "prefix_rex" "0")
19708 (set_attr "mode" "QI")])
19710 (define_expand "rep_mov"
19711 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19712 (set (match_operand 0 "register_operand" "")
19713 (match_operand 5 "" ""))
19714 (set (match_operand 2 "register_operand" "")
19715 (match_operand 6 "" ""))
19716 (set (match_operand 1 "memory_operand" "")
19717 (match_operand 3 "memory_operand" ""))
19718 (use (match_dup 4))])]
19720 "ix86_current_function_needs_cld = 1;")
19722 (define_insn "*rep_movdi_rex64"
19723 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19724 (set (match_operand:DI 0 "register_operand" "=D")
19725 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19727 (match_operand:DI 3 "register_operand" "0")))
19728 (set (match_operand:DI 1 "register_operand" "=S")
19729 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19730 (match_operand:DI 4 "register_operand" "1")))
19731 (set (mem:BLK (match_dup 3))
19732 (mem:BLK (match_dup 4)))
19733 (use (match_dup 5))]
19736 [(set_attr "type" "str")
19737 (set_attr "prefix_rep" "1")
19738 (set_attr "memory" "both")
19739 (set_attr "mode" "DI")])
19741 (define_insn "*rep_movsi"
19742 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19743 (set (match_operand:SI 0 "register_operand" "=D")
19744 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19746 (match_operand:SI 3 "register_operand" "0")))
19747 (set (match_operand:SI 1 "register_operand" "=S")
19748 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19749 (match_operand:SI 4 "register_operand" "1")))
19750 (set (mem:BLK (match_dup 3))
19751 (mem:BLK (match_dup 4)))
19752 (use (match_dup 5))]
19755 [(set_attr "type" "str")
19756 (set_attr "prefix_rep" "1")
19757 (set_attr "memory" "both")
19758 (set_attr "mode" "SI")])
19760 (define_insn "*rep_movsi_rex64"
19761 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19762 (set (match_operand:DI 0 "register_operand" "=D")
19763 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19765 (match_operand:DI 3 "register_operand" "0")))
19766 (set (match_operand:DI 1 "register_operand" "=S")
19767 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19768 (match_operand:DI 4 "register_operand" "1")))
19769 (set (mem:BLK (match_dup 3))
19770 (mem:BLK (match_dup 4)))
19771 (use (match_dup 5))]
19774 [(set_attr "type" "str")
19775 (set_attr "prefix_rep" "1")
19776 (set_attr "memory" "both")
19777 (set_attr "mode" "SI")])
19779 (define_insn "*rep_movqi"
19780 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19781 (set (match_operand:SI 0 "register_operand" "=D")
19782 (plus:SI (match_operand:SI 3 "register_operand" "0")
19783 (match_operand:SI 5 "register_operand" "2")))
19784 (set (match_operand:SI 1 "register_operand" "=S")
19785 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19786 (set (mem:BLK (match_dup 3))
19787 (mem:BLK (match_dup 4)))
19788 (use (match_dup 5))]
19791 [(set_attr "type" "str")
19792 (set_attr "prefix_rep" "1")
19793 (set_attr "memory" "both")
19794 (set_attr "mode" "SI")])
19796 (define_insn "*rep_movqi_rex64"
19797 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19798 (set (match_operand:DI 0 "register_operand" "=D")
19799 (plus:DI (match_operand:DI 3 "register_operand" "0")
19800 (match_operand:DI 5 "register_operand" "2")))
19801 (set (match_operand:DI 1 "register_operand" "=S")
19802 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19803 (set (mem:BLK (match_dup 3))
19804 (mem:BLK (match_dup 4)))
19805 (use (match_dup 5))]
19808 [(set_attr "type" "str")
19809 (set_attr "prefix_rep" "1")
19810 (set_attr "memory" "both")
19811 (set_attr "mode" "SI")])
19813 (define_expand "setmemsi"
19814 [(use (match_operand:BLK 0 "memory_operand" ""))
19815 (use (match_operand:SI 1 "nonmemory_operand" ""))
19816 (use (match_operand 2 "const_int_operand" ""))
19817 (use (match_operand 3 "const_int_operand" ""))
19818 (use (match_operand:SI 4 "const_int_operand" ""))
19819 (use (match_operand:SI 5 "const_int_operand" ""))]
19822 if (ix86_expand_setmem (operands[0], operands[1],
19823 operands[2], operands[3],
19824 operands[4], operands[5]))
19830 (define_expand "setmemdi"
19831 [(use (match_operand:BLK 0 "memory_operand" ""))
19832 (use (match_operand:DI 1 "nonmemory_operand" ""))
19833 (use (match_operand 2 "const_int_operand" ""))
19834 (use (match_operand 3 "const_int_operand" ""))
19835 (use (match_operand 4 "const_int_operand" ""))
19836 (use (match_operand 5 "const_int_operand" ""))]
19839 if (ix86_expand_setmem (operands[0], operands[1],
19840 operands[2], operands[3],
19841 operands[4], operands[5]))
19847 ;; Most CPUs don't like single string operations
19848 ;; Handle this case here to simplify previous expander.
19850 (define_expand "strset"
19851 [(set (match_operand 1 "memory_operand" "")
19852 (match_operand 2 "register_operand" ""))
19853 (parallel [(set (match_operand 0 "register_operand" "")
19855 (clobber (reg:CC FLAGS_REG))])]
19858 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19859 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19861 /* If .md ever supports :P for Pmode, this can be directly
19862 in the pattern above. */
19863 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19864 GEN_INT (GET_MODE_SIZE (GET_MODE
19866 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19868 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19874 (define_expand "strset_singleop"
19875 [(parallel [(set (match_operand 1 "memory_operand" "")
19876 (match_operand 2 "register_operand" ""))
19877 (set (match_operand 0 "register_operand" "")
19878 (match_operand 3 "" ""))])]
19880 "ix86_current_function_needs_cld = 1;")
19882 (define_insn "*strsetdi_rex_1"
19883 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19884 (match_operand:DI 2 "register_operand" "a"))
19885 (set (match_operand:DI 0 "register_operand" "=D")
19886 (plus:DI (match_dup 1)
19890 [(set_attr "type" "str")
19891 (set_attr "memory" "store")
19892 (set_attr "mode" "DI")])
19894 (define_insn "*strsetsi_1"
19895 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19896 (match_operand:SI 2 "register_operand" "a"))
19897 (set (match_operand:SI 0 "register_operand" "=D")
19898 (plus:SI (match_dup 1)
19902 [(set_attr "type" "str")
19903 (set_attr "memory" "store")
19904 (set_attr "mode" "SI")])
19906 (define_insn "*strsetsi_rex_1"
19907 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19908 (match_operand:SI 2 "register_operand" "a"))
19909 (set (match_operand:DI 0 "register_operand" "=D")
19910 (plus:DI (match_dup 1)
19914 [(set_attr "type" "str")
19915 (set_attr "memory" "store")
19916 (set_attr "mode" "SI")])
19918 (define_insn "*strsethi_1"
19919 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19920 (match_operand:HI 2 "register_operand" "a"))
19921 (set (match_operand:SI 0 "register_operand" "=D")
19922 (plus:SI (match_dup 1)
19926 [(set_attr "type" "str")
19927 (set_attr "memory" "store")
19928 (set_attr "mode" "HI")])
19930 (define_insn "*strsethi_rex_1"
19931 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19932 (match_operand:HI 2 "register_operand" "a"))
19933 (set (match_operand:DI 0 "register_operand" "=D")
19934 (plus:DI (match_dup 1)
19938 [(set_attr "type" "str")
19939 (set_attr "memory" "store")
19940 (set_attr "mode" "HI")])
19942 (define_insn "*strsetqi_1"
19943 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19944 (match_operand:QI 2 "register_operand" "a"))
19945 (set (match_operand:SI 0 "register_operand" "=D")
19946 (plus:SI (match_dup 1)
19950 [(set_attr "type" "str")
19951 (set_attr "memory" "store")
19952 (set_attr "mode" "QI")])
19954 (define_insn "*strsetqi_rex_1"
19955 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19956 (match_operand:QI 2 "register_operand" "a"))
19957 (set (match_operand:DI 0 "register_operand" "=D")
19958 (plus:DI (match_dup 1)
19962 [(set_attr "type" "str")
19963 (set_attr "memory" "store")
19964 (set_attr "prefix_rex" "0")
19965 (set_attr "mode" "QI")])
19967 (define_expand "rep_stos"
19968 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19969 (set (match_operand 0 "register_operand" "")
19970 (match_operand 4 "" ""))
19971 (set (match_operand 2 "memory_operand" "") (const_int 0))
19972 (use (match_operand 3 "register_operand" ""))
19973 (use (match_dup 1))])]
19975 "ix86_current_function_needs_cld = 1;")
19977 (define_insn "*rep_stosdi_rex64"
19978 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19979 (set (match_operand:DI 0 "register_operand" "=D")
19980 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19982 (match_operand:DI 3 "register_operand" "0")))
19983 (set (mem:BLK (match_dup 3))
19985 (use (match_operand:DI 2 "register_operand" "a"))
19986 (use (match_dup 4))]
19989 [(set_attr "type" "str")
19990 (set_attr "prefix_rep" "1")
19991 (set_attr "memory" "store")
19992 (set_attr "mode" "DI")])
19994 (define_insn "*rep_stossi"
19995 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19996 (set (match_operand:SI 0 "register_operand" "=D")
19997 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19999 (match_operand:SI 3 "register_operand" "0")))
20000 (set (mem:BLK (match_dup 3))
20002 (use (match_operand:SI 2 "register_operand" "a"))
20003 (use (match_dup 4))]
20006 [(set_attr "type" "str")
20007 (set_attr "prefix_rep" "1")
20008 (set_attr "memory" "store")
20009 (set_attr "mode" "SI")])
20011 (define_insn "*rep_stossi_rex64"
20012 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20013 (set (match_operand:DI 0 "register_operand" "=D")
20014 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20016 (match_operand:DI 3 "register_operand" "0")))
20017 (set (mem:BLK (match_dup 3))
20019 (use (match_operand:SI 2 "register_operand" "a"))
20020 (use (match_dup 4))]
20023 [(set_attr "type" "str")
20024 (set_attr "prefix_rep" "1")
20025 (set_attr "memory" "store")
20026 (set_attr "mode" "SI")])
20028 (define_insn "*rep_stosqi"
20029 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20030 (set (match_operand:SI 0 "register_operand" "=D")
20031 (plus:SI (match_operand:SI 3 "register_operand" "0")
20032 (match_operand:SI 4 "register_operand" "1")))
20033 (set (mem:BLK (match_dup 3))
20035 (use (match_operand:QI 2 "register_operand" "a"))
20036 (use (match_dup 4))]
20039 [(set_attr "type" "str")
20040 (set_attr "prefix_rep" "1")
20041 (set_attr "memory" "store")
20042 (set_attr "mode" "QI")])
20044 (define_insn "*rep_stosqi_rex64"
20045 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20046 (set (match_operand:DI 0 "register_operand" "=D")
20047 (plus:DI (match_operand:DI 3 "register_operand" "0")
20048 (match_operand:DI 4 "register_operand" "1")))
20049 (set (mem:BLK (match_dup 3))
20051 (use (match_operand:QI 2 "register_operand" "a"))
20052 (use (match_dup 4))]
20055 [(set_attr "type" "str")
20056 (set_attr "prefix_rep" "1")
20057 (set_attr "memory" "store")
20058 (set_attr "prefix_rex" "0")
20059 (set_attr "mode" "QI")])
20061 (define_expand "cmpstrnsi"
20062 [(set (match_operand:SI 0 "register_operand" "")
20063 (compare:SI (match_operand:BLK 1 "general_operand" "")
20064 (match_operand:BLK 2 "general_operand" "")))
20065 (use (match_operand 3 "general_operand" ""))
20066 (use (match_operand 4 "immediate_operand" ""))]
20069 rtx addr1, addr2, out, outlow, count, countreg, align;
20071 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20074 /* Can't use this if the user has appropriated esi or edi. */
20075 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20080 out = gen_reg_rtx (SImode);
20082 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20083 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20084 if (addr1 != XEXP (operands[1], 0))
20085 operands[1] = replace_equiv_address_nv (operands[1], addr1);
20086 if (addr2 != XEXP (operands[2], 0))
20087 operands[2] = replace_equiv_address_nv (operands[2], addr2);
20089 count = operands[3];
20090 countreg = ix86_zero_extend_to_Pmode (count);
20092 /* %%% Iff we are testing strict equality, we can use known alignment
20093 to good advantage. This may be possible with combine, particularly
20094 once cc0 is dead. */
20095 align = operands[4];
20097 if (CONST_INT_P (count))
20099 if (INTVAL (count) == 0)
20101 emit_move_insn (operands[0], const0_rtx);
20104 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20105 operands[1], operands[2]));
20110 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20112 emit_insn (gen_cmpsi_1 (countreg, countreg));
20113 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20114 operands[1], operands[2]));
20117 outlow = gen_lowpart (QImode, out);
20118 emit_insn (gen_cmpintqi (outlow));
20119 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20121 if (operands[0] != out)
20122 emit_move_insn (operands[0], out);
20127 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20129 (define_expand "cmpintqi"
20130 [(set (match_dup 1)
20131 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20133 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20134 (parallel [(set (match_operand:QI 0 "register_operand" "")
20135 (minus:QI (match_dup 1)
20137 (clobber (reg:CC FLAGS_REG))])]
20139 "operands[1] = gen_reg_rtx (QImode);
20140 operands[2] = gen_reg_rtx (QImode);")
20142 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
20143 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
20145 (define_expand "cmpstrnqi_nz_1"
20146 [(parallel [(set (reg:CC FLAGS_REG)
20147 (compare:CC (match_operand 4 "memory_operand" "")
20148 (match_operand 5 "memory_operand" "")))
20149 (use (match_operand 2 "register_operand" ""))
20150 (use (match_operand:SI 3 "immediate_operand" ""))
20151 (clobber (match_operand 0 "register_operand" ""))
20152 (clobber (match_operand 1 "register_operand" ""))
20153 (clobber (match_dup 2))])]
20155 "ix86_current_function_needs_cld = 1;")
20157 (define_insn "*cmpstrnqi_nz_1"
20158 [(set (reg:CC FLAGS_REG)
20159 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20160 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20161 (use (match_operand:SI 6 "register_operand" "2"))
20162 (use (match_operand:SI 3 "immediate_operand" "i"))
20163 (clobber (match_operand:SI 0 "register_operand" "=S"))
20164 (clobber (match_operand:SI 1 "register_operand" "=D"))
20165 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20168 [(set_attr "type" "str")
20169 (set_attr "mode" "QI")
20170 (set_attr "prefix_rep" "1")])
20172 (define_insn "*cmpstrnqi_nz_rex_1"
20173 [(set (reg:CC FLAGS_REG)
20174 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20175 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20176 (use (match_operand:DI 6 "register_operand" "2"))
20177 (use (match_operand:SI 3 "immediate_operand" "i"))
20178 (clobber (match_operand:DI 0 "register_operand" "=S"))
20179 (clobber (match_operand:DI 1 "register_operand" "=D"))
20180 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20183 [(set_attr "type" "str")
20184 (set_attr "mode" "QI")
20185 (set_attr "prefix_rex" "0")
20186 (set_attr "prefix_rep" "1")])
20188 ;; The same, but the count is not known to not be zero.
20190 (define_expand "cmpstrnqi_1"
20191 [(parallel [(set (reg:CC FLAGS_REG)
20192 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20194 (compare:CC (match_operand 4 "memory_operand" "")
20195 (match_operand 5 "memory_operand" ""))
20197 (use (match_operand:SI 3 "immediate_operand" ""))
20198 (use (reg:CC FLAGS_REG))
20199 (clobber (match_operand 0 "register_operand" ""))
20200 (clobber (match_operand 1 "register_operand" ""))
20201 (clobber (match_dup 2))])]
20203 "ix86_current_function_needs_cld = 1;")
20205 (define_insn "*cmpstrnqi_1"
20206 [(set (reg:CC FLAGS_REG)
20207 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20209 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20210 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20212 (use (match_operand:SI 3 "immediate_operand" "i"))
20213 (use (reg:CC FLAGS_REG))
20214 (clobber (match_operand:SI 0 "register_operand" "=S"))
20215 (clobber (match_operand:SI 1 "register_operand" "=D"))
20216 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20219 [(set_attr "type" "str")
20220 (set_attr "mode" "QI")
20221 (set_attr "prefix_rep" "1")])
20223 (define_insn "*cmpstrnqi_rex_1"
20224 [(set (reg:CC FLAGS_REG)
20225 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20227 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20228 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20230 (use (match_operand:SI 3 "immediate_operand" "i"))
20231 (use (reg:CC FLAGS_REG))
20232 (clobber (match_operand:DI 0 "register_operand" "=S"))
20233 (clobber (match_operand:DI 1 "register_operand" "=D"))
20234 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20237 [(set_attr "type" "str")
20238 (set_attr "mode" "QI")
20239 (set_attr "prefix_rex" "0")
20240 (set_attr "prefix_rep" "1")])
20242 (define_expand "strlensi"
20243 [(set (match_operand:SI 0 "register_operand" "")
20244 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20245 (match_operand:QI 2 "immediate_operand" "")
20246 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20249 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20255 (define_expand "strlendi"
20256 [(set (match_operand:DI 0 "register_operand" "")
20257 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20258 (match_operand:QI 2 "immediate_operand" "")
20259 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20262 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20268 (define_expand "strlenqi_1"
20269 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20270 (clobber (match_operand 1 "register_operand" ""))
20271 (clobber (reg:CC FLAGS_REG))])]
20273 "ix86_current_function_needs_cld = 1;")
20275 (define_insn "*strlenqi_1"
20276 [(set (match_operand:SI 0 "register_operand" "=&c")
20277 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20278 (match_operand:QI 2 "register_operand" "a")
20279 (match_operand:SI 3 "immediate_operand" "i")
20280 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20281 (clobber (match_operand:SI 1 "register_operand" "=D"))
20282 (clobber (reg:CC FLAGS_REG))]
20285 [(set_attr "type" "str")
20286 (set_attr "mode" "QI")
20287 (set_attr "prefix_rep" "1")])
20289 (define_insn "*strlenqi_rex_1"
20290 [(set (match_operand:DI 0 "register_operand" "=&c")
20291 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20292 (match_operand:QI 2 "register_operand" "a")
20293 (match_operand:DI 3 "immediate_operand" "i")
20294 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20295 (clobber (match_operand:DI 1 "register_operand" "=D"))
20296 (clobber (reg:CC FLAGS_REG))]
20299 [(set_attr "type" "str")
20300 (set_attr "mode" "QI")
20301 (set_attr "prefix_rex" "0")
20302 (set_attr "prefix_rep" "1")])
20304 ;; Peephole optimizations to clean up after cmpstrn*. This should be
20305 ;; handled in combine, but it is not currently up to the task.
20306 ;; When used for their truth value, the cmpstrn* expanders generate
20315 ;; The intermediate three instructions are unnecessary.
20317 ;; This one handles cmpstrn*_nz_1...
20320 (set (reg:CC FLAGS_REG)
20321 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20322 (mem:BLK (match_operand 5 "register_operand" ""))))
20323 (use (match_operand 6 "register_operand" ""))
20324 (use (match_operand:SI 3 "immediate_operand" ""))
20325 (clobber (match_operand 0 "register_operand" ""))
20326 (clobber (match_operand 1 "register_operand" ""))
20327 (clobber (match_operand 2 "register_operand" ""))])
20328 (set (match_operand:QI 7 "register_operand" "")
20329 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20330 (set (match_operand:QI 8 "register_operand" "")
20331 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20332 (set (reg FLAGS_REG)
20333 (compare (match_dup 7) (match_dup 8)))
20335 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20337 (set (reg:CC FLAGS_REG)
20338 (compare:CC (mem:BLK (match_dup 4))
20339 (mem:BLK (match_dup 5))))
20340 (use (match_dup 6))
20341 (use (match_dup 3))
20342 (clobber (match_dup 0))
20343 (clobber (match_dup 1))
20344 (clobber (match_dup 2))])]
20347 ;; ...and this one handles cmpstrn*_1.
20350 (set (reg:CC FLAGS_REG)
20351 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20353 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20354 (mem:BLK (match_operand 5 "register_operand" "")))
20356 (use (match_operand:SI 3 "immediate_operand" ""))
20357 (use (reg:CC FLAGS_REG))
20358 (clobber (match_operand 0 "register_operand" ""))
20359 (clobber (match_operand 1 "register_operand" ""))
20360 (clobber (match_operand 2 "register_operand" ""))])
20361 (set (match_operand:QI 7 "register_operand" "")
20362 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20363 (set (match_operand:QI 8 "register_operand" "")
20364 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20365 (set (reg FLAGS_REG)
20366 (compare (match_dup 7) (match_dup 8)))
20368 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20370 (set (reg:CC FLAGS_REG)
20371 (if_then_else:CC (ne (match_dup 6)
20373 (compare:CC (mem:BLK (match_dup 4))
20374 (mem:BLK (match_dup 5)))
20376 (use (match_dup 3))
20377 (use (reg:CC FLAGS_REG))
20378 (clobber (match_dup 0))
20379 (clobber (match_dup 1))
20380 (clobber (match_dup 2))])]
20385 ;; Conditional move instructions.
20387 (define_expand "movdicc"
20388 [(set (match_operand:DI 0 "register_operand" "")
20389 (if_then_else:DI (match_operand 1 "comparison_operator" "")
20390 (match_operand:DI 2 "general_operand" "")
20391 (match_operand:DI 3 "general_operand" "")))]
20393 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20395 (define_insn "x86_movdicc_0_m1_rex64"
20396 [(set (match_operand:DI 0 "register_operand" "=r")
20397 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20400 (clobber (reg:CC FLAGS_REG))]
20403 ; Since we don't have the proper number of operands for an alu insn,
20404 ; fill in all the blanks.
20405 [(set_attr "type" "alu")
20406 (set_attr "use_carry" "1")
20407 (set_attr "pent_pair" "pu")
20408 (set_attr "memory" "none")
20409 (set_attr "imm_disp" "false")
20410 (set_attr "mode" "DI")
20411 (set_attr "length_immediate" "0")])
20413 (define_insn "*x86_movdicc_0_m1_se"
20414 [(set (match_operand:DI 0 "register_operand" "=r")
20415 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20418 (clobber (reg:CC FLAGS_REG))]
20421 [(set_attr "type" "alu")
20422 (set_attr "use_carry" "1")
20423 (set_attr "pent_pair" "pu")
20424 (set_attr "memory" "none")
20425 (set_attr "imm_disp" "false")
20426 (set_attr "mode" "DI")
20427 (set_attr "length_immediate" "0")])
20429 (define_insn "*movdicc_c_rex64"
20430 [(set (match_operand:DI 0 "register_operand" "=r,r")
20431 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20432 [(reg FLAGS_REG) (const_int 0)])
20433 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20434 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20435 "TARGET_64BIT && TARGET_CMOVE
20436 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20438 cmov%O2%C1\t{%2, %0|%0, %2}
20439 cmov%O2%c1\t{%3, %0|%0, %3}"
20440 [(set_attr "type" "icmov")
20441 (set_attr "mode" "DI")])
20443 (define_expand "movsicc"
20444 [(set (match_operand:SI 0 "register_operand" "")
20445 (if_then_else:SI (match_operand 1 "comparison_operator" "")
20446 (match_operand:SI 2 "general_operand" "")
20447 (match_operand:SI 3 "general_operand" "")))]
20449 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20451 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20452 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20453 ;; So just document what we're doing explicitly.
20455 (define_insn "x86_movsicc_0_m1"
20456 [(set (match_operand:SI 0 "register_operand" "=r")
20457 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20460 (clobber (reg:CC FLAGS_REG))]
20463 ; Since we don't have the proper number of operands for an alu insn,
20464 ; fill in all the blanks.
20465 [(set_attr "type" "alu")
20466 (set_attr "use_carry" "1")
20467 (set_attr "pent_pair" "pu")
20468 (set_attr "memory" "none")
20469 (set_attr "imm_disp" "false")
20470 (set_attr "mode" "SI")
20471 (set_attr "length_immediate" "0")])
20473 (define_insn "*x86_movsicc_0_m1_se"
20474 [(set (match_operand:SI 0 "register_operand" "=r")
20475 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20478 (clobber (reg:CC FLAGS_REG))]
20481 [(set_attr "type" "alu")
20482 (set_attr "use_carry" "1")
20483 (set_attr "pent_pair" "pu")
20484 (set_attr "memory" "none")
20485 (set_attr "imm_disp" "false")
20486 (set_attr "mode" "SI")
20487 (set_attr "length_immediate" "0")])
20489 (define_insn "*movsicc_noc"
20490 [(set (match_operand:SI 0 "register_operand" "=r,r")
20491 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20492 [(reg FLAGS_REG) (const_int 0)])
20493 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20494 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20496 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20498 cmov%O2%C1\t{%2, %0|%0, %2}
20499 cmov%O2%c1\t{%3, %0|%0, %3}"
20500 [(set_attr "type" "icmov")
20501 (set_attr "mode" "SI")])
20503 (define_expand "movhicc"
20504 [(set (match_operand:HI 0 "register_operand" "")
20505 (if_then_else:HI (match_operand 1 "comparison_operator" "")
20506 (match_operand:HI 2 "general_operand" "")
20507 (match_operand:HI 3 "general_operand" "")))]
20508 "TARGET_HIMODE_MATH"
20509 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20511 (define_insn "*movhicc_noc"
20512 [(set (match_operand:HI 0 "register_operand" "=r,r")
20513 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20514 [(reg FLAGS_REG) (const_int 0)])
20515 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20516 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20518 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20520 cmov%O2%C1\t{%2, %0|%0, %2}
20521 cmov%O2%c1\t{%3, %0|%0, %3}"
20522 [(set_attr "type" "icmov")
20523 (set_attr "mode" "HI")])
20525 (define_expand "movqicc"
20526 [(set (match_operand:QI 0 "register_operand" "")
20527 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20528 (match_operand:QI 2 "general_operand" "")
20529 (match_operand:QI 3 "general_operand" "")))]
20530 "TARGET_QIMODE_MATH"
20531 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20533 (define_insn_and_split "*movqicc_noc"
20534 [(set (match_operand:QI 0 "register_operand" "=r,r")
20535 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20536 [(match_operand 4 "flags_reg_operand" "")
20538 (match_operand:QI 2 "register_operand" "r,0")
20539 (match_operand:QI 3 "register_operand" "0,r")))]
20540 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20542 "&& reload_completed"
20543 [(set (match_dup 0)
20544 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20547 "operands[0] = gen_lowpart (SImode, operands[0]);
20548 operands[2] = gen_lowpart (SImode, operands[2]);
20549 operands[3] = gen_lowpart (SImode, operands[3]);"
20550 [(set_attr "type" "icmov")
20551 (set_attr "mode" "SI")])
20553 (define_expand "mov<mode>cc"
20554 [(set (match_operand:X87MODEF 0 "register_operand" "")
20555 (if_then_else:X87MODEF
20556 (match_operand 1 "ix86_fp_comparison_operator" "")
20557 (match_operand:X87MODEF 2 "register_operand" "")
20558 (match_operand:X87MODEF 3 "register_operand" "")))]
20559 "(TARGET_80387 && TARGET_CMOVE)
20560 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20561 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20563 (define_insn "*movsfcc_1_387"
20564 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20565 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20566 [(reg FLAGS_REG) (const_int 0)])
20567 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20568 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20569 "TARGET_80387 && TARGET_CMOVE
20570 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20572 fcmov%F1\t{%2, %0|%0, %2}
20573 fcmov%f1\t{%3, %0|%0, %3}
20574 cmov%O2%C1\t{%2, %0|%0, %2}
20575 cmov%O2%c1\t{%3, %0|%0, %3}"
20576 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20577 (set_attr "mode" "SF,SF,SI,SI")])
20579 (define_insn "*movdfcc_1"
20580 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20581 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20582 [(reg FLAGS_REG) (const_int 0)])
20583 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20584 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20585 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20586 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20588 fcmov%F1\t{%2, %0|%0, %2}
20589 fcmov%f1\t{%3, %0|%0, %3}
20592 [(set_attr "type" "fcmov,fcmov,multi,multi")
20593 (set_attr "mode" "DF")])
20595 (define_insn "*movdfcc_1_rex64"
20596 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20597 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20598 [(reg FLAGS_REG) (const_int 0)])
20599 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20600 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20601 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20602 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20604 fcmov%F1\t{%2, %0|%0, %2}
20605 fcmov%f1\t{%3, %0|%0, %3}
20606 cmov%O2%C1\t{%2, %0|%0, %2}
20607 cmov%O2%c1\t{%3, %0|%0, %3}"
20608 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20609 (set_attr "mode" "DF")])
20612 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20613 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20614 [(match_operand 4 "flags_reg_operand" "")
20616 (match_operand:DF 2 "nonimmediate_operand" "")
20617 (match_operand:DF 3 "nonimmediate_operand" "")))]
20618 "!TARGET_64BIT && reload_completed"
20619 [(set (match_dup 2)
20620 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20624 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20627 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20628 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20630 (define_insn "*movxfcc_1"
20631 [(set (match_operand:XF 0 "register_operand" "=f,f")
20632 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20633 [(reg FLAGS_REG) (const_int 0)])
20634 (match_operand:XF 2 "register_operand" "f,0")
20635 (match_operand:XF 3 "register_operand" "0,f")))]
20636 "TARGET_80387 && TARGET_CMOVE"
20638 fcmov%F1\t{%2, %0|%0, %2}
20639 fcmov%f1\t{%3, %0|%0, %3}"
20640 [(set_attr "type" "fcmov")
20641 (set_attr "mode" "XF")])
20643 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20644 ;; the scalar versions to have only XMM registers as operands.
20646 ;; SSE5 conditional move
20647 (define_insn "*sse5_pcmov_<mode>"
20648 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20649 (if_then_else:MODEF
20650 (match_operand:MODEF 1 "register_operand" "x,0")
20651 (match_operand:MODEF 2 "register_operand" "0,x")
20652 (match_operand:MODEF 3 "register_operand" "x,x")))]
20653 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20654 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20655 [(set_attr "type" "sse4arg")])
20657 ;; These versions of the min/max patterns are intentionally ignorant of
20658 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20659 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20660 ;; are undefined in this condition, we're certain this is correct.
20662 (define_insn "*avx_<code><mode>3"
20663 [(set (match_operand:MODEF 0 "register_operand" "=x")
20665 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20666 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20667 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20668 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20669 [(set_attr "type" "sseadd")
20670 (set_attr "prefix" "vex")
20671 (set_attr "mode" "<MODE>")])
20673 (define_insn "<code><mode>3"
20674 [(set (match_operand:MODEF 0 "register_operand" "=x")
20676 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20677 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20678 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20679 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "sseadd")
20681 (set_attr "mode" "<MODE>")])
20683 ;; These versions of the min/max patterns implement exactly the operations
20684 ;; min = (op1 < op2 ? op1 : op2)
20685 ;; max = (!(op1 < op2) ? op1 : op2)
20686 ;; Their operands are not commutative, and thus they may be used in the
20687 ;; presence of -0.0 and NaN.
20689 (define_insn "*avx_ieee_smin<mode>3"
20690 [(set (match_operand:MODEF 0 "register_operand" "=x")
20692 [(match_operand:MODEF 1 "register_operand" "x")
20693 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20695 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20696 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20697 [(set_attr "type" "sseadd")
20698 (set_attr "prefix" "vex")
20699 (set_attr "mode" "<MODE>")])
20701 (define_insn "*ieee_smin<mode>3"
20702 [(set (match_operand:MODEF 0 "register_operand" "=x")
20704 [(match_operand:MODEF 1 "register_operand" "0")
20705 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20707 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20708 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20709 [(set_attr "type" "sseadd")
20710 (set_attr "mode" "<MODE>")])
20712 (define_insn "*avx_ieee_smax<mode>3"
20713 [(set (match_operand:MODEF 0 "register_operand" "=x")
20715 [(match_operand:MODEF 1 "register_operand" "0")
20716 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20718 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20719 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20720 [(set_attr "type" "sseadd")
20721 (set_attr "prefix" "vex")
20722 (set_attr "mode" "<MODE>")])
20724 (define_insn "*ieee_smax<mode>3"
20725 [(set (match_operand:MODEF 0 "register_operand" "=x")
20727 [(match_operand:MODEF 1 "register_operand" "0")
20728 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20730 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20731 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20732 [(set_attr "type" "sseadd")
20733 (set_attr "mode" "<MODE>")])
20735 ;; Make two stack loads independent:
20737 ;; fld %st(0) -> fld bb
20738 ;; fmul bb fmul %st(1), %st
20740 ;; Actually we only match the last two instructions for simplicity.
20742 [(set (match_operand 0 "fp_register_operand" "")
20743 (match_operand 1 "fp_register_operand" ""))
20745 (match_operator 2 "binary_fp_operator"
20747 (match_operand 3 "memory_operand" "")]))]
20748 "REGNO (operands[0]) != REGNO (operands[1])"
20749 [(set (match_dup 0) (match_dup 3))
20750 (set (match_dup 0) (match_dup 4))]
20752 ;; The % modifier is not operational anymore in peephole2's, so we have to
20753 ;; swap the operands manually in the case of addition and multiplication.
20754 "if (COMMUTATIVE_ARITH_P (operands[2]))
20755 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20756 operands[0], operands[1]);
20758 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20759 operands[1], operands[0]);")
20761 ;; Conditional addition patterns
20762 (define_expand "add<mode>cc"
20763 [(match_operand:SWI 0 "register_operand" "")
20764 (match_operand 1 "comparison_operator" "")
20765 (match_operand:SWI 2 "register_operand" "")
20766 (match_operand:SWI 3 "const_int_operand" "")]
20768 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20771 ;; Misc patterns (?)
20773 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20774 ;; Otherwise there will be nothing to keep
20776 ;; [(set (reg ebp) (reg esp))]
20777 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20778 ;; (clobber (eflags)]
20779 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20781 ;; in proper program order.
20782 (define_insn "pro_epilogue_adjust_stack_1"
20783 [(set (match_operand:SI 0 "register_operand" "=r,r")
20784 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20785 (match_operand:SI 2 "immediate_operand" "i,i")))
20786 (clobber (reg:CC FLAGS_REG))
20787 (clobber (mem:BLK (scratch)))]
20790 switch (get_attr_type (insn))
20793 return "mov{l}\t{%1, %0|%0, %1}";
20796 if (CONST_INT_P (operands[2])
20797 && (INTVAL (operands[2]) == 128
20798 || (INTVAL (operands[2]) < 0
20799 && INTVAL (operands[2]) != -128)))
20801 operands[2] = GEN_INT (-INTVAL (operands[2]));
20802 return "sub{l}\t{%2, %0|%0, %2}";
20804 return "add{l}\t{%2, %0|%0, %2}";
20807 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20808 return "lea{l}\t{%a2, %0|%0, %a2}";
20811 gcc_unreachable ();
20814 [(set (attr "type")
20815 (cond [(and (eq_attr "alternative" "0")
20816 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20817 (const_string "alu")
20818 (match_operand:SI 2 "const0_operand" "")
20819 (const_string "imov")
20821 (const_string "lea")))
20822 (set (attr "length_immediate")
20823 (cond [(eq_attr "type" "imov")
20825 (and (eq_attr "type" "alu")
20826 (match_operand 2 "const128_operand" ""))
20829 (const_string "*")))
20830 (set_attr "mode" "SI")])
20832 (define_insn "pro_epilogue_adjust_stack_rex64"
20833 [(set (match_operand:DI 0 "register_operand" "=r,r")
20834 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20835 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20836 (clobber (reg:CC FLAGS_REG))
20837 (clobber (mem:BLK (scratch)))]
20840 switch (get_attr_type (insn))
20843 return "mov{q}\t{%1, %0|%0, %1}";
20846 if (CONST_INT_P (operands[2])
20847 /* Avoid overflows. */
20848 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20849 && (INTVAL (operands[2]) == 128
20850 || (INTVAL (operands[2]) < 0
20851 && INTVAL (operands[2]) != -128)))
20853 operands[2] = GEN_INT (-INTVAL (operands[2]));
20854 return "sub{q}\t{%2, %0|%0, %2}";
20856 return "add{q}\t{%2, %0|%0, %2}";
20859 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20860 return "lea{q}\t{%a2, %0|%0, %a2}";
20863 gcc_unreachable ();
20866 [(set (attr "type")
20867 (cond [(and (eq_attr "alternative" "0")
20868 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20869 (const_string "alu")
20870 (match_operand:DI 2 "const0_operand" "")
20871 (const_string "imov")
20873 (const_string "lea")))
20874 (set (attr "length_immediate")
20875 (cond [(eq_attr "type" "imov")
20877 (and (eq_attr "type" "alu")
20878 (match_operand 2 "const128_operand" ""))
20881 (const_string "*")))
20882 (set_attr "mode" "DI")])
20884 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20885 [(set (match_operand:DI 0 "register_operand" "=r,r")
20886 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20887 (match_operand:DI 3 "immediate_operand" "i,i")))
20888 (use (match_operand:DI 2 "register_operand" "r,r"))
20889 (clobber (reg:CC FLAGS_REG))
20890 (clobber (mem:BLK (scratch)))]
20893 switch (get_attr_type (insn))
20896 return "add{q}\t{%2, %0|%0, %2}";
20899 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20900 return "lea{q}\t{%a2, %0|%0, %a2}";
20903 gcc_unreachable ();
20906 [(set_attr "type" "alu,lea")
20907 (set_attr "mode" "DI")])
20909 (define_insn "allocate_stack_worker_32"
20910 [(set (match_operand:SI 0 "register_operand" "=a")
20911 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20912 UNSPECV_STACK_PROBE))
20913 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20914 (clobber (reg:CC FLAGS_REG))]
20915 "!TARGET_64BIT && TARGET_STACK_PROBE"
20917 [(set_attr "type" "multi")
20918 (set_attr "length" "5")])
20920 (define_insn "allocate_stack_worker_64"
20921 [(set (match_operand:DI 0 "register_operand" "=a")
20922 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20923 UNSPECV_STACK_PROBE))
20924 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20925 (clobber (reg:DI R10_REG))
20926 (clobber (reg:DI R11_REG))
20927 (clobber (reg:CC FLAGS_REG))]
20928 "TARGET_64BIT && TARGET_STACK_PROBE"
20930 [(set_attr "type" "multi")
20931 (set_attr "length" "5")])
20933 (define_expand "allocate_stack"
20934 [(match_operand 0 "register_operand" "")
20935 (match_operand 1 "general_operand" "")]
20936 "TARGET_STACK_PROBE"
20940 #ifndef CHECK_STACK_LIMIT
20941 #define CHECK_STACK_LIMIT 0
20944 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20945 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20947 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20948 stack_pointer_rtx, 0, OPTAB_DIRECT);
20949 if (x != stack_pointer_rtx)
20950 emit_move_insn (stack_pointer_rtx, x);
20954 x = copy_to_mode_reg (Pmode, operands[1]);
20956 x = gen_allocate_stack_worker_64 (x, x);
20958 x = gen_allocate_stack_worker_32 (x, x);
20962 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20966 (define_expand "builtin_setjmp_receiver"
20967 [(label_ref (match_operand 0 "" ""))]
20968 "!TARGET_64BIT && flag_pic"
20974 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20975 rtx label_rtx = gen_label_rtx ();
20976 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20977 xops[0] = xops[1] = picreg;
20978 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20979 ix86_expand_binary_operator (MINUS, SImode, xops);
20983 emit_insn (gen_set_got (pic_offset_table_rtx));
20987 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20990 [(set (match_operand 0 "register_operand" "")
20991 (match_operator 3 "promotable_binary_operator"
20992 [(match_operand 1 "register_operand" "")
20993 (match_operand 2 "aligned_operand" "")]))
20994 (clobber (reg:CC FLAGS_REG))]
20995 "! TARGET_PARTIAL_REG_STALL && reload_completed
20996 && ((GET_MODE (operands[0]) == HImode
20997 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20998 /* ??? next two lines just !satisfies_constraint_K (...) */
20999 || !CONST_INT_P (operands[2])
21000 || satisfies_constraint_K (operands[2])))
21001 || (GET_MODE (operands[0]) == QImode
21002 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21003 [(parallel [(set (match_dup 0)
21004 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21005 (clobber (reg:CC FLAGS_REG))])]
21006 "operands[0] = gen_lowpart (SImode, operands[0]);
21007 operands[1] = gen_lowpart (SImode, operands[1]);
21008 if (GET_CODE (operands[3]) != ASHIFT)
21009 operands[2] = gen_lowpart (SImode, operands[2]);
21010 PUT_MODE (operands[3], SImode);")
21012 ; Promote the QImode tests, as i386 has encoding of the AND
21013 ; instruction with 32-bit sign-extended immediate and thus the
21014 ; instruction size is unchanged, except in the %eax case for
21015 ; which it is increased by one byte, hence the ! optimize_size.
21017 [(set (match_operand 0 "flags_reg_operand" "")
21018 (match_operator 2 "compare_operator"
21019 [(and (match_operand 3 "aligned_operand" "")
21020 (match_operand 4 "const_int_operand" ""))
21022 (set (match_operand 1 "register_operand" "")
21023 (and (match_dup 3) (match_dup 4)))]
21024 "! TARGET_PARTIAL_REG_STALL && reload_completed
21025 && optimize_insn_for_speed_p ()
21026 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21027 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21028 /* Ensure that the operand will remain sign-extended immediate. */
21029 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21030 [(parallel [(set (match_dup 0)
21031 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21034 (and:SI (match_dup 3) (match_dup 4)))])]
21037 = gen_int_mode (INTVAL (operands[4])
21038 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21039 operands[1] = gen_lowpart (SImode, operands[1]);
21040 operands[3] = gen_lowpart (SImode, operands[3]);
21043 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21044 ; the TEST instruction with 32-bit sign-extended immediate and thus
21045 ; the instruction size would at least double, which is not what we
21046 ; want even with ! optimize_size.
21048 [(set (match_operand 0 "flags_reg_operand" "")
21049 (match_operator 1 "compare_operator"
21050 [(and (match_operand:HI 2 "aligned_operand" "")
21051 (match_operand:HI 3 "const_int_operand" ""))
21053 "! TARGET_PARTIAL_REG_STALL && reload_completed
21054 && ! TARGET_FAST_PREFIX
21055 && optimize_insn_for_speed_p ()
21056 /* Ensure that the operand will remain sign-extended immediate. */
21057 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21058 [(set (match_dup 0)
21059 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21063 = gen_int_mode (INTVAL (operands[3])
21064 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21065 operands[2] = gen_lowpart (SImode, operands[2]);
21069 [(set (match_operand 0 "register_operand" "")
21070 (neg (match_operand 1 "register_operand" "")))
21071 (clobber (reg:CC FLAGS_REG))]
21072 "! TARGET_PARTIAL_REG_STALL && reload_completed
21073 && (GET_MODE (operands[0]) == HImode
21074 || (GET_MODE (operands[0]) == QImode
21075 && (TARGET_PROMOTE_QImode
21076 || optimize_insn_for_size_p ())))"
21077 [(parallel [(set (match_dup 0)
21078 (neg:SI (match_dup 1)))
21079 (clobber (reg:CC FLAGS_REG))])]
21080 "operands[0] = gen_lowpart (SImode, operands[0]);
21081 operands[1] = gen_lowpart (SImode, operands[1]);")
21084 [(set (match_operand 0 "register_operand" "")
21085 (not (match_operand 1 "register_operand" "")))]
21086 "! TARGET_PARTIAL_REG_STALL && reload_completed
21087 && (GET_MODE (operands[0]) == HImode
21088 || (GET_MODE (operands[0]) == QImode
21089 && (TARGET_PROMOTE_QImode
21090 || optimize_insn_for_size_p ())))"
21091 [(set (match_dup 0)
21092 (not:SI (match_dup 1)))]
21093 "operands[0] = gen_lowpart (SImode, operands[0]);
21094 operands[1] = gen_lowpart (SImode, operands[1]);")
21097 [(set (match_operand 0 "register_operand" "")
21098 (if_then_else (match_operator 1 "comparison_operator"
21099 [(reg FLAGS_REG) (const_int 0)])
21100 (match_operand 2 "register_operand" "")
21101 (match_operand 3 "register_operand" "")))]
21102 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21103 && (GET_MODE (operands[0]) == HImode
21104 || (GET_MODE (operands[0]) == QImode
21105 && (TARGET_PROMOTE_QImode
21106 || optimize_insn_for_size_p ())))"
21107 [(set (match_dup 0)
21108 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21109 "operands[0] = gen_lowpart (SImode, operands[0]);
21110 operands[2] = gen_lowpart (SImode, operands[2]);
21111 operands[3] = gen_lowpart (SImode, operands[3]);")
21114 ;; RTL Peephole optimizations, run before sched2. These primarily look to
21115 ;; transform a complex memory operation into two memory to register operations.
21117 ;; Don't push memory operands
21119 [(set (match_operand:SI 0 "push_operand" "")
21120 (match_operand:SI 1 "memory_operand" ""))
21121 (match_scratch:SI 2 "r")]
21122 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21123 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21124 [(set (match_dup 2) (match_dup 1))
21125 (set (match_dup 0) (match_dup 2))]
21129 [(set (match_operand:DI 0 "push_operand" "")
21130 (match_operand:DI 1 "memory_operand" ""))
21131 (match_scratch:DI 2 "r")]
21132 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21133 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21134 [(set (match_dup 2) (match_dup 1))
21135 (set (match_dup 0) (match_dup 2))]
21138 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21141 [(set (match_operand:SF 0 "push_operand" "")
21142 (match_operand:SF 1 "memory_operand" ""))
21143 (match_scratch:SF 2 "r")]
21144 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21145 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21146 [(set (match_dup 2) (match_dup 1))
21147 (set (match_dup 0) (match_dup 2))]
21151 [(set (match_operand:HI 0 "push_operand" "")
21152 (match_operand:HI 1 "memory_operand" ""))
21153 (match_scratch:HI 2 "r")]
21154 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21155 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21156 [(set (match_dup 2) (match_dup 1))
21157 (set (match_dup 0) (match_dup 2))]
21161 [(set (match_operand:QI 0 "push_operand" "")
21162 (match_operand:QI 1 "memory_operand" ""))
21163 (match_scratch:QI 2 "q")]
21164 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21165 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21166 [(set (match_dup 2) (match_dup 1))
21167 (set (match_dup 0) (match_dup 2))]
21170 ;; Don't move an immediate directly to memory when the instruction
21173 [(match_scratch:SI 1 "r")
21174 (set (match_operand:SI 0 "memory_operand" "")
21176 "optimize_insn_for_speed_p ()
21177 && ! TARGET_USE_MOV0
21178 && TARGET_SPLIT_LONG_MOVES
21179 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21180 && peep2_regno_dead_p (0, FLAGS_REG)"
21181 [(parallel [(set (match_dup 1) (const_int 0))
21182 (clobber (reg:CC FLAGS_REG))])
21183 (set (match_dup 0) (match_dup 1))]
21187 [(match_scratch:HI 1 "r")
21188 (set (match_operand:HI 0 "memory_operand" "")
21190 "optimize_insn_for_speed_p ()
21191 && ! TARGET_USE_MOV0
21192 && TARGET_SPLIT_LONG_MOVES
21193 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21194 && peep2_regno_dead_p (0, FLAGS_REG)"
21195 [(parallel [(set (match_dup 2) (const_int 0))
21196 (clobber (reg:CC FLAGS_REG))])
21197 (set (match_dup 0) (match_dup 1))]
21198 "operands[2] = gen_lowpart (SImode, operands[1]);")
21201 [(match_scratch:QI 1 "q")
21202 (set (match_operand:QI 0 "memory_operand" "")
21204 "optimize_insn_for_speed_p ()
21205 && ! TARGET_USE_MOV0
21206 && TARGET_SPLIT_LONG_MOVES
21207 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21208 && peep2_regno_dead_p (0, FLAGS_REG)"
21209 [(parallel [(set (match_dup 2) (const_int 0))
21210 (clobber (reg:CC FLAGS_REG))])
21211 (set (match_dup 0) (match_dup 1))]
21212 "operands[2] = gen_lowpart (SImode, operands[1]);")
21215 [(match_scratch:SI 2 "r")
21216 (set (match_operand:SI 0 "memory_operand" "")
21217 (match_operand:SI 1 "immediate_operand" ""))]
21218 "optimize_insn_for_speed_p ()
21219 && TARGET_SPLIT_LONG_MOVES
21220 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21221 [(set (match_dup 2) (match_dup 1))
21222 (set (match_dup 0) (match_dup 2))]
21226 [(match_scratch:HI 2 "r")
21227 (set (match_operand:HI 0 "memory_operand" "")
21228 (match_operand:HI 1 "immediate_operand" ""))]
21229 "optimize_insn_for_speed_p ()
21230 && TARGET_SPLIT_LONG_MOVES
21231 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21232 [(set (match_dup 2) (match_dup 1))
21233 (set (match_dup 0) (match_dup 2))]
21237 [(match_scratch:QI 2 "q")
21238 (set (match_operand:QI 0 "memory_operand" "")
21239 (match_operand:QI 1 "immediate_operand" ""))]
21240 "optimize_insn_for_speed_p ()
21241 && TARGET_SPLIT_LONG_MOVES
21242 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21243 [(set (match_dup 2) (match_dup 1))
21244 (set (match_dup 0) (match_dup 2))]
21247 ;; Don't compare memory with zero, load and use a test instead.
21249 [(set (match_operand 0 "flags_reg_operand" "")
21250 (match_operator 1 "compare_operator"
21251 [(match_operand:SI 2 "memory_operand" "")
21253 (match_scratch:SI 3 "r")]
21254 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21255 [(set (match_dup 3) (match_dup 2))
21256 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21259 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21260 ;; Don't split NOTs with a displacement operand, because resulting XOR
21261 ;; will not be pairable anyway.
21263 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21264 ;; represented using a modRM byte. The XOR replacement is long decoded,
21265 ;; so this split helps here as well.
21267 ;; Note: Can't do this as a regular split because we can't get proper
21268 ;; lifetime information then.
21271 [(set (match_operand:SI 0 "nonimmediate_operand" "")
21272 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21273 "optimize_insn_for_speed_p ()
21274 && ((TARGET_NOT_UNPAIRABLE
21275 && (!MEM_P (operands[0])
21276 || !memory_displacement_operand (operands[0], SImode)))
21277 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21278 && peep2_regno_dead_p (0, FLAGS_REG)"
21279 [(parallel [(set (match_dup 0)
21280 (xor:SI (match_dup 1) (const_int -1)))
21281 (clobber (reg:CC FLAGS_REG))])]
21285 [(set (match_operand:HI 0 "nonimmediate_operand" "")
21286 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21287 "optimize_insn_for_speed_p ()
21288 && ((TARGET_NOT_UNPAIRABLE
21289 && (!MEM_P (operands[0])
21290 || !memory_displacement_operand (operands[0], HImode)))
21291 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21292 && peep2_regno_dead_p (0, FLAGS_REG)"
21293 [(parallel [(set (match_dup 0)
21294 (xor:HI (match_dup 1) (const_int -1)))
21295 (clobber (reg:CC FLAGS_REG))])]
21299 [(set (match_operand:QI 0 "nonimmediate_operand" "")
21300 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21301 "optimize_insn_for_speed_p ()
21302 && ((TARGET_NOT_UNPAIRABLE
21303 && (!MEM_P (operands[0])
21304 || !memory_displacement_operand (operands[0], QImode)))
21305 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21306 && peep2_regno_dead_p (0, FLAGS_REG)"
21307 [(parallel [(set (match_dup 0)
21308 (xor:QI (match_dup 1) (const_int -1)))
21309 (clobber (reg:CC FLAGS_REG))])]
21312 ;; Non pairable "test imm, reg" instructions can be translated to
21313 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
21314 ;; byte opcode instead of two, have a short form for byte operands),
21315 ;; so do it for other CPUs as well. Given that the value was dead,
21316 ;; this should not create any new dependencies. Pass on the sub-word
21317 ;; versions if we're concerned about partial register stalls.
21320 [(set (match_operand 0 "flags_reg_operand" "")
21321 (match_operator 1 "compare_operator"
21322 [(and:SI (match_operand:SI 2 "register_operand" "")
21323 (match_operand:SI 3 "immediate_operand" ""))
21325 "ix86_match_ccmode (insn, CCNOmode)
21326 && (true_regnum (operands[2]) != AX_REG
21327 || satisfies_constraint_K (operands[3]))
21328 && peep2_reg_dead_p (1, operands[2])"
21330 [(set (match_dup 0)
21331 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21334 (and:SI (match_dup 2) (match_dup 3)))])]
21337 ;; We don't need to handle HImode case, because it will be promoted to SImode
21338 ;; on ! TARGET_PARTIAL_REG_STALL
21341 [(set (match_operand 0 "flags_reg_operand" "")
21342 (match_operator 1 "compare_operator"
21343 [(and:QI (match_operand:QI 2 "register_operand" "")
21344 (match_operand:QI 3 "immediate_operand" ""))
21346 "! TARGET_PARTIAL_REG_STALL
21347 && ix86_match_ccmode (insn, CCNOmode)
21348 && true_regnum (operands[2]) != AX_REG
21349 && peep2_reg_dead_p (1, operands[2])"
21351 [(set (match_dup 0)
21352 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21355 (and:QI (match_dup 2) (match_dup 3)))])]
21359 [(set (match_operand 0 "flags_reg_operand" "")
21360 (match_operator 1 "compare_operator"
21363 (match_operand 2 "ext_register_operand" "")
21366 (match_operand 3 "const_int_operand" ""))
21368 "! TARGET_PARTIAL_REG_STALL
21369 && ix86_match_ccmode (insn, CCNOmode)
21370 && true_regnum (operands[2]) != AX_REG
21371 && peep2_reg_dead_p (1, operands[2])"
21372 [(parallel [(set (match_dup 0)
21381 (set (zero_extract:SI (match_dup 2)
21392 ;; Don't do logical operations with memory inputs.
21394 [(match_scratch:SI 2 "r")
21395 (parallel [(set (match_operand:SI 0 "register_operand" "")
21396 (match_operator:SI 3 "arith_or_logical_operator"
21398 (match_operand:SI 1 "memory_operand" "")]))
21399 (clobber (reg:CC FLAGS_REG))])]
21400 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21401 [(set (match_dup 2) (match_dup 1))
21402 (parallel [(set (match_dup 0)
21403 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21404 (clobber (reg:CC FLAGS_REG))])]
21408 [(match_scratch:SI 2 "r")
21409 (parallel [(set (match_operand:SI 0 "register_operand" "")
21410 (match_operator:SI 3 "arith_or_logical_operator"
21411 [(match_operand:SI 1 "memory_operand" "")
21413 (clobber (reg:CC FLAGS_REG))])]
21414 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21415 [(set (match_dup 2) (match_dup 1))
21416 (parallel [(set (match_dup 0)
21417 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21418 (clobber (reg:CC FLAGS_REG))])]
21421 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
21422 ;; refers to the destination of the load!
21425 [(set (match_operand:SI 0 "register_operand" "")
21426 (match_operand:SI 1 "register_operand" ""))
21427 (parallel [(set (match_dup 0)
21428 (match_operator:SI 3 "commutative_operator"
21430 (match_operand:SI 2 "memory_operand" "")]))
21431 (clobber (reg:CC FLAGS_REG))])]
21432 "REGNO (operands[0]) != REGNO (operands[1])
21433 && GENERAL_REGNO_P (REGNO (operands[0]))
21434 && GENERAL_REGNO_P (REGNO (operands[1]))"
21435 [(set (match_dup 0) (match_dup 4))
21436 (parallel [(set (match_dup 0)
21437 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21438 (clobber (reg:CC FLAGS_REG))])]
21439 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21442 [(set (match_operand 0 "register_operand" "")
21443 (match_operand 1 "register_operand" ""))
21445 (match_operator 3 "commutative_operator"
21447 (match_operand 2 "memory_operand" "")]))]
21448 "REGNO (operands[0]) != REGNO (operands[1])
21449 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
21450 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21451 [(set (match_dup 0) (match_dup 2))
21453 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21456 ; Don't do logical operations with memory outputs
21458 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21459 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
21460 ; the same decoder scheduling characteristics as the original.
21463 [(match_scratch:SI 2 "r")
21464 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21465 (match_operator:SI 3 "arith_or_logical_operator"
21467 (match_operand:SI 1 "nonmemory_operand" "")]))
21468 (clobber (reg:CC FLAGS_REG))])]
21469 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21470 [(set (match_dup 2) (match_dup 0))
21471 (parallel [(set (match_dup 2)
21472 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21473 (clobber (reg:CC FLAGS_REG))])
21474 (set (match_dup 0) (match_dup 2))]
21478 [(match_scratch:SI 2 "r")
21479 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21480 (match_operator:SI 3 "arith_or_logical_operator"
21481 [(match_operand:SI 1 "nonmemory_operand" "")
21483 (clobber (reg:CC FLAGS_REG))])]
21484 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21485 [(set (match_dup 2) (match_dup 0))
21486 (parallel [(set (match_dup 2)
21487 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21488 (clobber (reg:CC FLAGS_REG))])
21489 (set (match_dup 0) (match_dup 2))]
21492 ;; Attempt to always use XOR for zeroing registers.
21494 [(set (match_operand 0 "register_operand" "")
21495 (match_operand 1 "const0_operand" ""))]
21496 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21497 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21498 && GENERAL_REG_P (operands[0])
21499 && peep2_regno_dead_p (0, FLAGS_REG)"
21500 [(parallel [(set (match_dup 0) (const_int 0))
21501 (clobber (reg:CC FLAGS_REG))])]
21503 operands[0] = gen_lowpart (word_mode, operands[0]);
21507 [(set (strict_low_part (match_operand 0 "register_operand" ""))
21509 "(GET_MODE (operands[0]) == QImode
21510 || GET_MODE (operands[0]) == HImode)
21511 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21512 && peep2_regno_dead_p (0, FLAGS_REG)"
21513 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21514 (clobber (reg:CC FLAGS_REG))])])
21516 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21518 [(set (match_operand 0 "register_operand" "")
21520 "(GET_MODE (operands[0]) == HImode
21521 || GET_MODE (operands[0]) == SImode
21522 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21523 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21524 && peep2_regno_dead_p (0, FLAGS_REG)"
21525 [(parallel [(set (match_dup 0) (const_int -1))
21526 (clobber (reg:CC FLAGS_REG))])]
21527 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21530 ;; Attempt to convert simple leas to adds. These can be created by
21533 [(set (match_operand:SI 0 "register_operand" "")
21534 (plus:SI (match_dup 0)
21535 (match_operand:SI 1 "nonmemory_operand" "")))]
21536 "peep2_regno_dead_p (0, FLAGS_REG)"
21537 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21538 (clobber (reg:CC FLAGS_REG))])]
21542 [(set (match_operand:SI 0 "register_operand" "")
21543 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21544 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21545 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21546 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21547 (clobber (reg:CC FLAGS_REG))])]
21548 "operands[2] = gen_lowpart (SImode, operands[2]);")
21551 [(set (match_operand:DI 0 "register_operand" "")
21552 (plus:DI (match_dup 0)
21553 (match_operand:DI 1 "x86_64_general_operand" "")))]
21554 "peep2_regno_dead_p (0, FLAGS_REG)"
21555 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21556 (clobber (reg:CC FLAGS_REG))])]
21560 [(set (match_operand:SI 0 "register_operand" "")
21561 (mult:SI (match_dup 0)
21562 (match_operand:SI 1 "const_int_operand" "")))]
21563 "exact_log2 (INTVAL (operands[1])) >= 0
21564 && peep2_regno_dead_p (0, FLAGS_REG)"
21565 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21566 (clobber (reg:CC FLAGS_REG))])]
21567 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21570 [(set (match_operand:DI 0 "register_operand" "")
21571 (mult:DI (match_dup 0)
21572 (match_operand:DI 1 "const_int_operand" "")))]
21573 "exact_log2 (INTVAL (operands[1])) >= 0
21574 && peep2_regno_dead_p (0, FLAGS_REG)"
21575 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21576 (clobber (reg:CC FLAGS_REG))])]
21577 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21580 [(set (match_operand:SI 0 "register_operand" "")
21581 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21582 (match_operand:DI 2 "const_int_operand" "")) 0))]
21583 "exact_log2 (INTVAL (operands[2])) >= 0
21584 && REGNO (operands[0]) == REGNO (operands[1])
21585 && peep2_regno_dead_p (0, FLAGS_REG)"
21586 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21587 (clobber (reg:CC FLAGS_REG))])]
21588 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21590 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21591 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21592 ;; many CPUs it is also faster, since special hardware to avoid esp
21593 ;; dependencies is present.
21595 ;; While some of these conversions may be done using splitters, we use peepholes
21596 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21598 ;; Convert prologue esp subtractions to push.
21599 ;; We need register to push. In order to keep verify_flow_info happy we have
21601 ;; - use scratch and clobber it in order to avoid dependencies
21602 ;; - use already live register
21603 ;; We can't use the second way right now, since there is no reliable way how to
21604 ;; verify that given register is live. First choice will also most likely in
21605 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21606 ;; call clobbered registers are dead. We may want to use base pointer as an
21607 ;; alternative when no register is available later.
21610 [(match_scratch:SI 0 "r")
21611 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21612 (clobber (reg:CC FLAGS_REG))
21613 (clobber (mem:BLK (scratch)))])]
21614 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21615 [(clobber (match_dup 0))
21616 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21617 (clobber (mem:BLK (scratch)))])])
21620 [(match_scratch:SI 0 "r")
21621 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21622 (clobber (reg:CC FLAGS_REG))
21623 (clobber (mem:BLK (scratch)))])]
21624 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21625 [(clobber (match_dup 0))
21626 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21627 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21628 (clobber (mem:BLK (scratch)))])])
21630 ;; Convert esp subtractions to push.
21632 [(match_scratch:SI 0 "r")
21633 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21634 (clobber (reg:CC FLAGS_REG))])]
21635 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21636 [(clobber (match_dup 0))
21637 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21640 [(match_scratch:SI 0 "r")
21641 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21642 (clobber (reg:CC FLAGS_REG))])]
21643 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21644 [(clobber (match_dup 0))
21645 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21646 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21648 ;; Convert epilogue deallocator to pop.
21650 [(match_scratch:SI 0 "r")
21651 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21652 (clobber (reg:CC FLAGS_REG))
21653 (clobber (mem:BLK (scratch)))])]
21654 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21655 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21656 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21657 (clobber (mem:BLK (scratch)))])]
21660 ;; Two pops case is tricky, since pop causes dependency on destination register.
21661 ;; We use two registers if available.
21663 [(match_scratch:SI 0 "r")
21664 (match_scratch:SI 1 "r")
21665 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21666 (clobber (reg:CC FLAGS_REG))
21667 (clobber (mem:BLK (scratch)))])]
21668 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21669 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21670 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21671 (clobber (mem:BLK (scratch)))])
21672 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21673 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21677 [(match_scratch:SI 0 "r")
21678 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21679 (clobber (reg:CC FLAGS_REG))
21680 (clobber (mem:BLK (scratch)))])]
21681 "optimize_insn_for_size_p ()"
21682 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21683 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21684 (clobber (mem:BLK (scratch)))])
21685 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21686 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21689 ;; Convert esp additions to pop.
21691 [(match_scratch:SI 0 "r")
21692 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21693 (clobber (reg:CC FLAGS_REG))])]
21695 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21696 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21699 ;; Two pops case is tricky, since pop causes dependency on destination register.
21700 ;; We use two registers if available.
21702 [(match_scratch:SI 0 "r")
21703 (match_scratch:SI 1 "r")
21704 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21705 (clobber (reg:CC FLAGS_REG))])]
21707 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21708 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21709 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21710 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21714 [(match_scratch:SI 0 "r")
21715 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21716 (clobber (reg:CC FLAGS_REG))])]
21717 "optimize_insn_for_size_p ()"
21718 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21720 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21721 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21724 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21725 ;; required and register dies. Similarly for 128 to -128.
21727 [(set (match_operand 0 "flags_reg_operand" "")
21728 (match_operator 1 "compare_operator"
21729 [(match_operand 2 "register_operand" "")
21730 (match_operand 3 "const_int_operand" "")]))]
21731 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21732 && incdec_operand (operands[3], GET_MODE (operands[3])))
21733 || (!TARGET_FUSE_CMP_AND_BRANCH
21734 && INTVAL (operands[3]) == 128))
21735 && ix86_match_ccmode (insn, CCGCmode)
21736 && peep2_reg_dead_p (1, operands[2])"
21737 [(parallel [(set (match_dup 0)
21738 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21739 (clobber (match_dup 2))])]
21743 [(match_scratch:DI 0 "r")
21744 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21745 (clobber (reg:CC FLAGS_REG))
21746 (clobber (mem:BLK (scratch)))])]
21747 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21748 [(clobber (match_dup 0))
21749 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21750 (clobber (mem:BLK (scratch)))])])
21753 [(match_scratch:DI 0 "r")
21754 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21755 (clobber (reg:CC FLAGS_REG))
21756 (clobber (mem:BLK (scratch)))])]
21757 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21758 [(clobber (match_dup 0))
21759 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21760 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21761 (clobber (mem:BLK (scratch)))])])
21763 ;; Convert esp subtractions to push.
21765 [(match_scratch:DI 0 "r")
21766 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21767 (clobber (reg:CC FLAGS_REG))])]
21768 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21769 [(clobber (match_dup 0))
21770 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21773 [(match_scratch:DI 0 "r")
21774 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21775 (clobber (reg:CC FLAGS_REG))])]
21776 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21777 [(clobber (match_dup 0))
21778 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21779 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21781 ;; Convert epilogue deallocator to pop.
21783 [(match_scratch:DI 0 "r")
21784 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21785 (clobber (reg:CC FLAGS_REG))
21786 (clobber (mem:BLK (scratch)))])]
21787 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21788 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21789 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21790 (clobber (mem:BLK (scratch)))])]
21793 ;; Two pops case is tricky, since pop causes dependency on destination register.
21794 ;; We use two registers if available.
21796 [(match_scratch:DI 0 "r")
21797 (match_scratch:DI 1 "r")
21798 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21799 (clobber (reg:CC FLAGS_REG))
21800 (clobber (mem:BLK (scratch)))])]
21801 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21802 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21803 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21804 (clobber (mem:BLK (scratch)))])
21805 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21806 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21810 [(match_scratch:DI 0 "r")
21811 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21812 (clobber (reg:CC FLAGS_REG))
21813 (clobber (mem:BLK (scratch)))])]
21814 "optimize_insn_for_size_p ()"
21815 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21816 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21817 (clobber (mem:BLK (scratch)))])
21818 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21819 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21822 ;; Convert esp additions to pop.
21824 [(match_scratch:DI 0 "r")
21825 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21826 (clobber (reg:CC FLAGS_REG))])]
21828 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21829 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21832 ;; Two pops case is tricky, since pop causes dependency on destination register.
21833 ;; We use two registers if available.
21835 [(match_scratch:DI 0 "r")
21836 (match_scratch:DI 1 "r")
21837 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21838 (clobber (reg:CC FLAGS_REG))])]
21840 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21841 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21842 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21843 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21847 [(match_scratch:DI 0 "r")
21848 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21849 (clobber (reg:CC FLAGS_REG))])]
21850 "optimize_insn_for_size_p ()"
21851 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21853 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21854 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21857 ;; Convert imul by three, five and nine into lea
21860 [(set (match_operand:SI 0 "register_operand" "")
21861 (mult:SI (match_operand:SI 1 "register_operand" "")
21862 (match_operand:SI 2 "const_int_operand" "")))
21863 (clobber (reg:CC FLAGS_REG))])]
21864 "INTVAL (operands[2]) == 3
21865 || INTVAL (operands[2]) == 5
21866 || INTVAL (operands[2]) == 9"
21867 [(set (match_dup 0)
21868 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21870 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21874 [(set (match_operand:SI 0 "register_operand" "")
21875 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21876 (match_operand:SI 2 "const_int_operand" "")))
21877 (clobber (reg:CC FLAGS_REG))])]
21878 "optimize_insn_for_speed_p ()
21879 && (INTVAL (operands[2]) == 3
21880 || INTVAL (operands[2]) == 5
21881 || INTVAL (operands[2]) == 9)"
21882 [(set (match_dup 0) (match_dup 1))
21884 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21886 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21890 [(set (match_operand:DI 0 "register_operand" "")
21891 (mult:DI (match_operand:DI 1 "register_operand" "")
21892 (match_operand:DI 2 "const_int_operand" "")))
21893 (clobber (reg:CC FLAGS_REG))])]
21895 && (INTVAL (operands[2]) == 3
21896 || INTVAL (operands[2]) == 5
21897 || INTVAL (operands[2]) == 9)"
21898 [(set (match_dup 0)
21899 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21901 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21905 [(set (match_operand:DI 0 "register_operand" "")
21906 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21907 (match_operand:DI 2 "const_int_operand" "")))
21908 (clobber (reg:CC FLAGS_REG))])]
21910 && optimize_insn_for_speed_p ()
21911 && (INTVAL (operands[2]) == 3
21912 || INTVAL (operands[2]) == 5
21913 || INTVAL (operands[2]) == 9)"
21914 [(set (match_dup 0) (match_dup 1))
21916 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21918 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21920 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21921 ;; imul $32bit_imm, reg, reg is direct decoded.
21923 [(match_scratch:DI 3 "r")
21924 (parallel [(set (match_operand:DI 0 "register_operand" "")
21925 (mult:DI (match_operand:DI 1 "memory_operand" "")
21926 (match_operand:DI 2 "immediate_operand" "")))
21927 (clobber (reg:CC FLAGS_REG))])]
21928 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21929 && !satisfies_constraint_K (operands[2])"
21930 [(set (match_dup 3) (match_dup 1))
21931 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21932 (clobber (reg:CC FLAGS_REG))])]
21936 [(match_scratch:SI 3 "r")
21937 (parallel [(set (match_operand:SI 0 "register_operand" "")
21938 (mult:SI (match_operand:SI 1 "memory_operand" "")
21939 (match_operand:SI 2 "immediate_operand" "")))
21940 (clobber (reg:CC FLAGS_REG))])]
21941 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21942 && !satisfies_constraint_K (operands[2])"
21943 [(set (match_dup 3) (match_dup 1))
21944 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21945 (clobber (reg:CC FLAGS_REG))])]
21949 [(match_scratch:SI 3 "r")
21950 (parallel [(set (match_operand:DI 0 "register_operand" "")
21952 (mult:SI (match_operand:SI 1 "memory_operand" "")
21953 (match_operand:SI 2 "immediate_operand" ""))))
21954 (clobber (reg:CC FLAGS_REG))])]
21955 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21956 && !satisfies_constraint_K (operands[2])"
21957 [(set (match_dup 3) (match_dup 1))
21958 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21959 (clobber (reg:CC FLAGS_REG))])]
21962 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21963 ;; Convert it into imul reg, reg
21964 ;; It would be better to force assembler to encode instruction using long
21965 ;; immediate, but there is apparently no way to do so.
21967 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21968 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21969 (match_operand:DI 2 "const_int_operand" "")))
21970 (clobber (reg:CC FLAGS_REG))])
21971 (match_scratch:DI 3 "r")]
21972 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21973 && satisfies_constraint_K (operands[2])"
21974 [(set (match_dup 3) (match_dup 2))
21975 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21976 (clobber (reg:CC FLAGS_REG))])]
21978 if (!rtx_equal_p (operands[0], operands[1]))
21979 emit_move_insn (operands[0], operands[1]);
21983 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21984 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21985 (match_operand:SI 2 "const_int_operand" "")))
21986 (clobber (reg:CC FLAGS_REG))])
21987 (match_scratch:SI 3 "r")]
21988 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21989 && satisfies_constraint_K (operands[2])"
21990 [(set (match_dup 3) (match_dup 2))
21991 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21992 (clobber (reg:CC FLAGS_REG))])]
21994 if (!rtx_equal_p (operands[0], operands[1]))
21995 emit_move_insn (operands[0], operands[1]);
21999 [(parallel [(set (match_operand:HI 0 "register_operand" "")
22000 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22001 (match_operand:HI 2 "immediate_operand" "")))
22002 (clobber (reg:CC FLAGS_REG))])
22003 (match_scratch:HI 3 "r")]
22004 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22005 [(set (match_dup 3) (match_dup 2))
22006 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22007 (clobber (reg:CC FLAGS_REG))])]
22009 if (!rtx_equal_p (operands[0], operands[1]))
22010 emit_move_insn (operands[0], operands[1]);
22013 ;; After splitting up read-modify operations, array accesses with memory
22014 ;; operands might end up in form:
22016 ;; movl 4(%esp), %edx
22018 ;; instead of pre-splitting:
22020 ;; addl 4(%esp), %eax
22022 ;; movl 4(%esp), %edx
22023 ;; leal (%edx,%eax,4), %eax
22026 [(parallel [(set (match_operand 0 "register_operand" "")
22027 (ashift (match_operand 1 "register_operand" "")
22028 (match_operand 2 "const_int_operand" "")))
22029 (clobber (reg:CC FLAGS_REG))])
22030 (set (match_operand 3 "register_operand")
22031 (match_operand 4 "x86_64_general_operand" ""))
22032 (parallel [(set (match_operand 5 "register_operand" "")
22033 (plus (match_operand 6 "register_operand" "")
22034 (match_operand 7 "register_operand" "")))
22035 (clobber (reg:CC FLAGS_REG))])]
22036 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22037 /* Validate MODE for lea. */
22038 && ((!TARGET_PARTIAL_REG_STALL
22039 && (GET_MODE (operands[0]) == QImode
22040 || GET_MODE (operands[0]) == HImode))
22041 || GET_MODE (operands[0]) == SImode
22042 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22043 /* We reorder load and the shift. */
22044 && !rtx_equal_p (operands[1], operands[3])
22045 && !reg_overlap_mentioned_p (operands[0], operands[4])
22046 /* Last PLUS must consist of operand 0 and 3. */
22047 && !rtx_equal_p (operands[0], operands[3])
22048 && (rtx_equal_p (operands[3], operands[6])
22049 || rtx_equal_p (operands[3], operands[7]))
22050 && (rtx_equal_p (operands[0], operands[6])
22051 || rtx_equal_p (operands[0], operands[7]))
22052 /* The intermediate operand 0 must die or be same as output. */
22053 && (rtx_equal_p (operands[0], operands[5])
22054 || peep2_reg_dead_p (3, operands[0]))"
22055 [(set (match_dup 3) (match_dup 4))
22056 (set (match_dup 0) (match_dup 1))]
22058 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22059 int scale = 1 << INTVAL (operands[2]);
22060 rtx index = gen_lowpart (Pmode, operands[1]);
22061 rtx base = gen_lowpart (Pmode, operands[3]);
22062 rtx dest = gen_lowpart (mode, operands[5]);
22064 operands[1] = gen_rtx_PLUS (Pmode, base,
22065 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22067 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22068 operands[0] = dest;
22071 ;; Call-value patterns last so that the wildcard operand does not
22072 ;; disrupt insn-recog's switch tables.
22074 (define_insn "*call_value_pop_0"
22075 [(set (match_operand 0 "" "")
22076 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22077 (match_operand:SI 2 "" "")))
22078 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22079 (match_operand:SI 3 "immediate_operand" "")))]
22082 if (SIBLING_CALL_P (insn))
22085 return "call\t%P1";
22087 [(set_attr "type" "callv")])
22089 (define_insn "*call_value_pop_1"
22090 [(set (match_operand 0 "" "")
22091 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22092 (match_operand:SI 2 "" "")))
22093 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22094 (match_operand:SI 3 "immediate_operand" "i")))]
22097 if (constant_call_address_operand (operands[1], Pmode))
22099 if (SIBLING_CALL_P (insn))
22102 return "call\t%P1";
22104 if (SIBLING_CALL_P (insn))
22107 return "call\t%A1";
22109 [(set_attr "type" "callv")])
22111 (define_insn "*call_value_0"
22112 [(set (match_operand 0 "" "")
22113 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22114 (match_operand:SI 2 "" "")))]
22117 if (SIBLING_CALL_P (insn))
22120 return "call\t%P1";
22122 [(set_attr "type" "callv")])
22124 (define_insn "*call_value_0_rex64"
22125 [(set (match_operand 0 "" "")
22126 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22127 (match_operand:DI 2 "const_int_operand" "")))]
22130 if (SIBLING_CALL_P (insn))
22133 return "call\t%P1";
22135 [(set_attr "type" "callv")])
22137 (define_insn "*call_value_0_rex64_ms_sysv"
22138 [(set (match_operand 0 "" "")
22139 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22140 (match_operand:DI 2 "const_int_operand" "")))
22141 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22142 (clobber (reg:TI XMM6_REG))
22143 (clobber (reg:TI XMM7_REG))
22144 (clobber (reg:TI XMM8_REG))
22145 (clobber (reg:TI XMM9_REG))
22146 (clobber (reg:TI XMM10_REG))
22147 (clobber (reg:TI XMM11_REG))
22148 (clobber (reg:TI XMM12_REG))
22149 (clobber (reg:TI XMM13_REG))
22150 (clobber (reg:TI XMM14_REG))
22151 (clobber (reg:TI XMM15_REG))
22152 (clobber (reg:DI SI_REG))
22153 (clobber (reg:DI DI_REG))]
22154 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22156 if (SIBLING_CALL_P (insn))
22159 return "call\t%P1";
22161 [(set_attr "type" "callv")])
22163 (define_insn "*call_value_1"
22164 [(set (match_operand 0 "" "")
22165 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22166 (match_operand:SI 2 "" "")))]
22167 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22169 if (constant_call_address_operand (operands[1], Pmode))
22170 return "call\t%P1";
22171 return "call\t%A1";
22173 [(set_attr "type" "callv")])
22175 (define_insn "*sibcall_value_1"
22176 [(set (match_operand 0 "" "")
22177 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
22178 (match_operand:SI 2 "" "")))]
22179 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22183 [(set_attr "type" "callv")])
22185 (define_insn "*call_value_1_rex64"
22186 [(set (match_operand 0 "" "")
22187 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22188 (match_operand:DI 2 "" "")))]
22189 "!SIBLING_CALL_P (insn) && TARGET_64BIT
22190 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22192 if (constant_call_address_operand (operands[1], Pmode))
22193 return "call\t%P1";
22194 return "call\t%A1";
22196 [(set_attr "type" "callv")])
22198 (define_insn "*call_value_1_rex64_ms_sysv"
22199 [(set (match_operand 0 "" "")
22200 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22201 (match_operand:DI 2 "" "")))
22202 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22203 (clobber (reg:TI 27))
22204 (clobber (reg:TI 28))
22205 (clobber (reg:TI 45))
22206 (clobber (reg:TI 46))
22207 (clobber (reg:TI 47))
22208 (clobber (reg:TI 48))
22209 (clobber (reg:TI 49))
22210 (clobber (reg:TI 50))
22211 (clobber (reg:TI 51))
22212 (clobber (reg:TI 52))
22213 (clobber (reg:DI SI_REG))
22214 (clobber (reg:DI DI_REG))]
22215 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22217 if (constant_call_address_operand (operands[1], Pmode))
22218 return "call\t%P1";
22219 return "call\t%A1";
22221 [(set_attr "type" "callv")])
22223 (define_insn "*call_value_1_rex64_large"
22224 [(set (match_operand 0 "" "")
22225 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22226 (match_operand:DI 2 "" "")))]
22227 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22229 [(set_attr "type" "callv")])
22231 (define_insn "*sibcall_value_1_rex64"
22232 [(set (match_operand 0 "" "")
22233 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
22234 (match_operand:DI 2 "" "")))]
22235 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22239 [(set_attr "type" "callv")])
22241 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22242 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22243 ;; caught for use by garbage collectors and the like. Using an insn that
22244 ;; maps to SIGILL makes it more likely the program will rightfully die.
22245 ;; Keeping with tradition, "6" is in honor of #UD.
22246 (define_insn "trap"
22247 [(trap_if (const_int 1) (const_int 6))]
22249 { return ASM_SHORT "0x0b0f"; }
22250 [(set_attr "length" "2")])
22252 (define_expand "sse_prologue_save"
22253 [(parallel [(set (match_operand:BLK 0 "" "")
22254 (unspec:BLK [(reg:DI 21)
22261 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22262 (use (match_operand:DI 1 "register_operand" ""))
22263 (use (match_operand:DI 2 "immediate_operand" ""))
22264 (use (label_ref:DI (match_operand 3 "" "")))])]
22268 (define_insn "*sse_prologue_save_insn"
22269 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22270 (match_operand:DI 4 "const_int_operand" "n")))
22271 (unspec:BLK [(reg:DI 21)
22278 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22279 (use (match_operand:DI 1 "register_operand" "r"))
22280 (use (match_operand:DI 2 "const_int_operand" "i"))
22281 (use (label_ref:DI (match_operand 3 "" "X")))]
22283 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22284 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22287 operands[0] = gen_rtx_MEM (Pmode,
22288 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22289 /* VEX instruction with a REX prefix will #UD. */
22290 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22291 gcc_unreachable ();
22293 output_asm_insn ("jmp\t%A1", operands);
22294 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22296 operands[4] = adjust_address (operands[0], DImode, i*16);
22297 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22298 PUT_MODE (operands[4], TImode);
22299 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22300 output_asm_insn ("rex", operands);
22301 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22303 (*targetm.asm_out.internal_label) (asm_out_file, "L",
22304 CODE_LABEL_NUMBER (operands[3]));
22307 [(set_attr "type" "other")
22308 (set_attr "length_immediate" "0")
22309 (set_attr "length_address" "0")
22310 (set (attr "length")
22312 (eq (symbol_ref "TARGET_AVX") (const_int 0))
22313 (const_string "34")
22314 (const_string "42")))
22315 (set_attr "memory" "store")
22316 (set_attr "modrm" "0")
22317 (set_attr "prefix" "maybe_vex")
22318 (set_attr "mode" "DI")])
22320 (define_expand "prefetch"
22321 [(prefetch (match_operand 0 "address_operand" "")
22322 (match_operand:SI 1 "const_int_operand" "")
22323 (match_operand:SI 2 "const_int_operand" ""))]
22324 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22326 int rw = INTVAL (operands[1]);
22327 int locality = INTVAL (operands[2]);
22329 gcc_assert (rw == 0 || rw == 1);
22330 gcc_assert (locality >= 0 && locality <= 3);
22331 gcc_assert (GET_MODE (operands[0]) == Pmode
22332 || GET_MODE (operands[0]) == VOIDmode);
22334 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22335 supported by SSE counterpart or the SSE prefetch is not available
22336 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22338 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22339 operands[2] = GEN_INT (3);
22341 operands[1] = const0_rtx;
22344 (define_insn "*prefetch_sse"
22345 [(prefetch (match_operand:SI 0 "address_operand" "p")
22347 (match_operand:SI 1 "const_int_operand" ""))]
22348 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22350 static const char * const patterns[4] = {
22351 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22354 int locality = INTVAL (operands[1]);
22355 gcc_assert (locality >= 0 && locality <= 3);
22357 return patterns[locality];
22359 [(set_attr "type" "sse")
22360 (set_attr "atom_sse_attr" "prefetch")
22361 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22362 (set_attr "memory" "none")])
22364 (define_insn "*prefetch_sse_rex"
22365 [(prefetch (match_operand:DI 0 "address_operand" "p")
22367 (match_operand:SI 1 "const_int_operand" ""))]
22368 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22370 static const char * const patterns[4] = {
22371 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22374 int locality = INTVAL (operands[1]);
22375 gcc_assert (locality >= 0 && locality <= 3);
22377 return patterns[locality];
22379 [(set_attr "type" "sse")
22380 (set_attr "atom_sse_attr" "prefetch")
22381 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22382 (set_attr "memory" "none")])
22384 (define_insn "*prefetch_3dnow"
22385 [(prefetch (match_operand:SI 0 "address_operand" "p")
22386 (match_operand:SI 1 "const_int_operand" "n")
22388 "TARGET_3DNOW && !TARGET_64BIT"
22390 if (INTVAL (operands[1]) == 0)
22391 return "prefetch\t%a0";
22393 return "prefetchw\t%a0";
22395 [(set_attr "type" "mmx")
22396 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22397 (set_attr "memory" "none")])
22399 (define_insn "*prefetch_3dnow_rex"
22400 [(prefetch (match_operand:DI 0 "address_operand" "p")
22401 (match_operand:SI 1 "const_int_operand" "n")
22403 "TARGET_3DNOW && TARGET_64BIT"
22405 if (INTVAL (operands[1]) == 0)
22406 return "prefetch\t%a0";
22408 return "prefetchw\t%a0";
22410 [(set_attr "type" "mmx")
22411 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22412 (set_attr "memory" "none")])
22414 (define_expand "stack_protect_set"
22415 [(match_operand 0 "memory_operand" "")
22416 (match_operand 1 "memory_operand" "")]
22419 #ifdef TARGET_THREAD_SSP_OFFSET
22421 emit_insn (gen_stack_tls_protect_set_di (operands[0],
22422 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22424 emit_insn (gen_stack_tls_protect_set_si (operands[0],
22425 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22428 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22430 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22435 (define_insn "stack_protect_set_si"
22436 [(set (match_operand:SI 0 "memory_operand" "=m")
22437 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22438 (set (match_scratch:SI 2 "=&r") (const_int 0))
22439 (clobber (reg:CC FLAGS_REG))]
22441 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22442 [(set_attr "type" "multi")])
22444 (define_insn "stack_protect_set_di"
22445 [(set (match_operand:DI 0 "memory_operand" "=m")
22446 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22447 (set (match_scratch:DI 2 "=&r") (const_int 0))
22448 (clobber (reg:CC FLAGS_REG))]
22450 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22451 [(set_attr "type" "multi")])
22453 (define_insn "stack_tls_protect_set_si"
22454 [(set (match_operand:SI 0 "memory_operand" "=m")
22455 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22456 (set (match_scratch:SI 2 "=&r") (const_int 0))
22457 (clobber (reg:CC FLAGS_REG))]
22459 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22460 [(set_attr "type" "multi")])
22462 (define_insn "stack_tls_protect_set_di"
22463 [(set (match_operand:DI 0 "memory_operand" "=m")
22464 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22465 (set (match_scratch:DI 2 "=&r") (const_int 0))
22466 (clobber (reg:CC FLAGS_REG))]
22469 /* The kernel uses a different segment register for performance reasons; a
22470 system call would not have to trash the userspace segment register,
22471 which would be expensive */
22472 if (ix86_cmodel != CM_KERNEL)
22473 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22475 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22477 [(set_attr "type" "multi")])
22479 (define_expand "stack_protect_test"
22480 [(match_operand 0 "memory_operand" "")
22481 (match_operand 1 "memory_operand" "")
22482 (match_operand 2 "" "")]
22485 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22487 #ifdef TARGET_THREAD_SSP_OFFSET
22489 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22490 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22492 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22493 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22496 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22498 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22501 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22502 flags, const0_rtx, operands[2]));
22506 (define_insn "stack_protect_test_si"
22507 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22508 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22509 (match_operand:SI 2 "memory_operand" "m")]
22511 (clobber (match_scratch:SI 3 "=&r"))]
22513 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22514 [(set_attr "type" "multi")])
22516 (define_insn "stack_protect_test_di"
22517 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22518 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22519 (match_operand:DI 2 "memory_operand" "m")]
22521 (clobber (match_scratch:DI 3 "=&r"))]
22523 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22524 [(set_attr "type" "multi")])
22526 (define_insn "stack_tls_protect_test_si"
22527 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22528 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22529 (match_operand:SI 2 "const_int_operand" "i")]
22530 UNSPEC_SP_TLS_TEST))
22531 (clobber (match_scratch:SI 3 "=r"))]
22533 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22534 [(set_attr "type" "multi")])
22536 (define_insn "stack_tls_protect_test_di"
22537 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22538 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22539 (match_operand:DI 2 "const_int_operand" "i")]
22540 UNSPEC_SP_TLS_TEST))
22541 (clobber (match_scratch:DI 3 "=r"))]
22544 /* The kernel uses a different segment register for performance reasons; a
22545 system call would not have to trash the userspace segment register,
22546 which would be expensive */
22547 if (ix86_cmodel != CM_KERNEL)
22548 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22550 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22552 [(set_attr "type" "multi")])
22554 (define_mode_iterator CRC32MODE [QI HI SI])
22555 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22556 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22558 (define_insn "sse4_2_crc32<mode>"
22559 [(set (match_operand:SI 0 "register_operand" "=r")
22561 [(match_operand:SI 1 "register_operand" "0")
22562 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22564 "TARGET_SSE4_2 || TARGET_CRC32"
22565 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22566 [(set_attr "type" "sselog1")
22567 (set_attr "prefix_rep" "1")
22568 (set_attr "prefix_extra" "1")
22569 (set (attr "prefix_data16")
22570 (if_then_else (match_operand:HI 2 "" "")
22572 (const_string "*")))
22573 (set (attr "prefix_rex")
22574 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22576 (const_string "*")))
22577 (set_attr "mode" "SI")])
22579 (define_insn "sse4_2_crc32di"
22580 [(set (match_operand:DI 0 "register_operand" "=r")
22582 [(match_operand:DI 1 "register_operand" "0")
22583 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22585 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22586 "crc32q\t{%2, %0|%0, %2}"
22587 [(set_attr "type" "sselog1")
22588 (set_attr "prefix_rep" "1")
22589 (set_attr "prefix_extra" "1")
22590 (set_attr "mode" "DI")])
22592 (define_expand "rdpmc"
22593 [(match_operand:DI 0 "register_operand" "")
22594 (match_operand:SI 1 "register_operand" "")]
22597 rtx reg = gen_reg_rtx (DImode);
22600 /* Force operand 1 into ECX. */
22601 rtx ecx = gen_rtx_REG (SImode, CX_REG);
22602 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
22603 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
22608 rtvec vec = rtvec_alloc (2);
22609 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22610 rtx upper = gen_reg_rtx (DImode);
22611 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22612 gen_rtvec (1, const0_rtx),
22614 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
22615 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22617 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22618 NULL, 1, OPTAB_DIRECT);
22619 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22623 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
22624 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22628 (define_insn "*rdpmc"
22629 [(set (match_operand:DI 0 "register_operand" "=A")
22630 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
22634 [(set_attr "type" "other")
22635 (set_attr "length" "2")])
22637 (define_insn "*rdpmc_rex64"
22638 [(set (match_operand:DI 0 "register_operand" "=a")
22639 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
22641 (set (match_operand:DI 1 "register_operand" "=d")
22642 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
22645 [(set_attr "type" "other")
22646 (set_attr "length" "2")])
22648 (define_expand "rdtsc"
22649 [(set (match_operand:DI 0 "register_operand" "")
22650 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22655 rtvec vec = rtvec_alloc (2);
22656 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22657 rtx upper = gen_reg_rtx (DImode);
22658 rtx lower = gen_reg_rtx (DImode);
22659 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
22660 gen_rtvec (1, const0_rtx),
22662 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
22663 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
22665 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22666 NULL, 1, OPTAB_DIRECT);
22667 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
22669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
22674 (define_insn "*rdtsc"
22675 [(set (match_operand:DI 0 "register_operand" "=A")
22676 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22679 [(set_attr "type" "other")
22680 (set_attr "length" "2")])
22682 (define_insn "*rdtsc_rex64"
22683 [(set (match_operand:DI 0 "register_operand" "=a")
22684 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
22685 (set (match_operand:DI 1 "register_operand" "=d")
22686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22689 [(set_attr "type" "other")
22690 (set_attr "length" "2")])
22692 (define_expand "rdtscp"
22693 [(match_operand:DI 0 "register_operand" "")
22694 (match_operand:SI 1 "memory_operand" "")]
22697 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22698 gen_rtvec (1, const0_rtx),
22700 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
22701 gen_rtvec (1, const0_rtx),
22703 rtx reg = gen_reg_rtx (DImode);
22704 rtx tmp = gen_reg_rtx (SImode);
22708 rtvec vec = rtvec_alloc (3);
22709 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22710 rtx upper = gen_reg_rtx (DImode);
22711 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22712 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22713 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22715 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22716 NULL, 1, OPTAB_DIRECT);
22717 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22722 rtvec vec = rtvec_alloc (2);
22723 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22724 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22725 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22728 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22729 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22733 (define_insn "*rdtscp"
22734 [(set (match_operand:DI 0 "register_operand" "=A")
22735 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22736 (set (match_operand:SI 1 "register_operand" "=c")
22737 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22740 [(set_attr "type" "other")
22741 (set_attr "length" "3")])
22743 (define_insn "*rdtscp_rex64"
22744 [(set (match_operand:DI 0 "register_operand" "=a")
22745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22746 (set (match_operand:DI 1 "register_operand" "=d")
22747 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22748 (set (match_operand:SI 2 "register_operand" "=c")
22749 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22752 [(set_attr "type" "other")
22753 (set_attr "length" "3")])
22757 (include "sync.md")