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 && !(reload_completed || reload_in_progress)"
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 && !(reload_completed || reload_in_progress)"
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 && !(reload_completed || reload_in_progress)"
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 && !(reload_completed || reload_in_progress)"
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,c,d,a"))
15540 (match_operand 1 "" ""))]
15541 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15543 if (constant_call_address_operand (operands[0], Pmode))
15547 [(set_attr "type" "call")])
15549 (define_insn "*call_1_rex64"
15550 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15551 (match_operand 1 "" ""))]
15552 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15553 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15555 if (constant_call_address_operand (operands[0], Pmode))
15556 return "call\t%P0";
15557 return "call\t%A0";
15559 [(set_attr "type" "call")])
15561 (define_insn "*call_1_rex64_ms_sysv"
15562 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15563 (match_operand 1 "" ""))
15564 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15565 (clobber (reg:TI XMM6_REG))
15566 (clobber (reg:TI XMM7_REG))
15567 (clobber (reg:TI XMM8_REG))
15568 (clobber (reg:TI XMM9_REG))
15569 (clobber (reg:TI XMM10_REG))
15570 (clobber (reg:TI XMM11_REG))
15571 (clobber (reg:TI XMM12_REG))
15572 (clobber (reg:TI XMM13_REG))
15573 (clobber (reg:TI XMM14_REG))
15574 (clobber (reg:TI XMM15_REG))
15575 (clobber (reg:DI SI_REG))
15576 (clobber (reg:DI DI_REG))]
15577 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15579 if (constant_call_address_operand (operands[0], Pmode))
15580 return "call\t%P0";
15581 return "call\t%A0";
15583 [(set_attr "type" "call")])
15585 (define_insn "*call_1_rex64_large"
15586 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15587 (match_operand 1 "" ""))]
15588 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15590 [(set_attr "type" "call")])
15592 (define_insn "*sibcall_1_rex64"
15593 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15594 (match_operand 1 "" ""))]
15595 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15597 [(set_attr "type" "call")])
15599 (define_insn "*sibcall_1_rex64_v"
15600 [(call (mem:QI (reg:DI R11_REG))
15601 (match_operand 0 "" ""))]
15602 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15604 [(set_attr "type" "call")])
15607 ;; Call subroutine, returning value in operand 0
15609 (define_expand "call_value_pop"
15610 [(parallel [(set (match_operand 0 "" "")
15611 (call (match_operand:QI 1 "" "")
15612 (match_operand:SI 2 "" "")))
15613 (set (reg:SI SP_REG)
15614 (plus:SI (reg:SI SP_REG)
15615 (match_operand:SI 4 "" "")))])]
15618 ix86_expand_call (operands[0], operands[1], operands[2],
15619 operands[3], operands[4], 0);
15623 (define_expand "call_value"
15624 [(set (match_operand 0 "" "")
15625 (call (match_operand:QI 1 "" "")
15626 (match_operand:SI 2 "" "")))
15627 (use (match_operand:SI 3 "" ""))]
15628 ;; Operand 2 not used on the i386.
15631 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15635 (define_expand "sibcall_value"
15636 [(set (match_operand 0 "" "")
15637 (call (match_operand:QI 1 "" "")
15638 (match_operand:SI 2 "" "")))
15639 (use (match_operand:SI 3 "" ""))]
15640 ;; Operand 2 not used on the i386.
15643 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15647 ;; Call subroutine returning any type.
15649 (define_expand "untyped_call"
15650 [(parallel [(call (match_operand 0 "" "")
15652 (match_operand 1 "" "")
15653 (match_operand 2 "" "")])]
15658 /* In order to give reg-stack an easier job in validating two
15659 coprocessor registers as containing a possible return value,
15660 simply pretend the untyped call returns a complex long double
15663 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15664 and should have the default ABI. */
15666 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15667 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15668 operands[0], const0_rtx,
15669 GEN_INT ((TARGET_64BIT
15670 ? (ix86_abi == SYSV_ABI
15671 ? X86_64_SSE_REGPARM_MAX
15672 : X86_64_MS_SSE_REGPARM_MAX)
15673 : X86_32_SSE_REGPARM_MAX)
15677 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15679 rtx set = XVECEXP (operands[2], 0, i);
15680 emit_move_insn (SET_DEST (set), SET_SRC (set));
15683 /* The optimizer does not know that the call sets the function value
15684 registers we stored in the result block. We avoid problems by
15685 claiming that all hard registers are used and clobbered at this
15687 emit_insn (gen_blockage ());
15692 ;; Prologue and epilogue instructions
15694 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15695 ;; all of memory. This blocks insns from being moved across this point.
15697 (define_insn "blockage"
15698 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15701 [(set_attr "length" "0")])
15703 ;; Do not schedule instructions accessing memory across this point.
15705 (define_expand "memory_blockage"
15706 [(set (match_dup 0)
15707 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15710 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15711 MEM_VOLATILE_P (operands[0]) = 1;
15714 (define_insn "*memory_blockage"
15715 [(set (match_operand:BLK 0 "" "")
15716 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15719 [(set_attr "length" "0")])
15721 ;; As USE insns aren't meaningful after reload, this is used instead
15722 ;; to prevent deleting instructions setting registers for PIC code
15723 (define_insn "prologue_use"
15724 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15727 [(set_attr "length" "0")])
15729 ;; Insn emitted into the body of a function to return from a function.
15730 ;; This is only done if the function's epilogue is known to be simple.
15731 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15733 (define_expand "return"
15735 "ix86_can_use_return_insn_p ()"
15737 if (crtl->args.pops_args)
15739 rtx popc = GEN_INT (crtl->args.pops_args);
15740 emit_jump_insn (gen_return_pop_internal (popc));
15745 (define_insn "return_internal"
15749 [(set_attr "length" "1")
15750 (set_attr "atom_unit" "jeu")
15751 (set_attr "length_immediate" "0")
15752 (set_attr "modrm" "0")])
15754 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15755 ;; instruction Athlon and K8 have.
15757 (define_insn "return_internal_long"
15759 (unspec [(const_int 0)] UNSPEC_REP)]
15762 [(set_attr "length" "2")
15763 (set_attr "atom_unit" "jeu")
15764 (set_attr "length_immediate" "0")
15765 (set_attr "prefix_rep" "1")
15766 (set_attr "modrm" "0")])
15768 (define_insn "return_pop_internal"
15770 (use (match_operand:SI 0 "const_int_operand" ""))]
15773 [(set_attr "length" "3")
15774 (set_attr "atom_unit" "jeu")
15775 (set_attr "length_immediate" "2")
15776 (set_attr "modrm" "0")])
15778 (define_insn "return_indirect_internal"
15780 (use (match_operand:SI 0 "register_operand" "r"))]
15783 [(set_attr "type" "ibr")
15784 (set_attr "length_immediate" "0")])
15790 [(set_attr "length" "1")
15791 (set_attr "length_immediate" "0")
15792 (set_attr "modrm" "0")])
15794 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
15795 ;; branch prediction penalty for the third jump in a 16-byte
15799 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15803 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15805 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15806 The align insn is used to avoid 3 jump instructions in the row to improve
15807 branch prediction and the benefits hardly outweigh the cost of extra 8
15808 nops on the average inserted by full alignment pseudo operation. */
15812 [(set_attr "length" "16")])
15814 (define_expand "prologue"
15817 "ix86_expand_prologue (); DONE;")
15819 (define_insn "set_got"
15820 [(set (match_operand:SI 0 "register_operand" "=r")
15821 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15822 (clobber (reg:CC FLAGS_REG))]
15824 { return output_set_got (operands[0], NULL_RTX); }
15825 [(set_attr "type" "multi")
15826 (set_attr "length" "12")])
15828 (define_insn "set_got_labelled"
15829 [(set (match_operand:SI 0 "register_operand" "=r")
15830 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15832 (clobber (reg:CC FLAGS_REG))]
15834 { return output_set_got (operands[0], operands[1]); }
15835 [(set_attr "type" "multi")
15836 (set_attr "length" "12")])
15838 (define_insn "set_got_rex64"
15839 [(set (match_operand:DI 0 "register_operand" "=r")
15840 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15842 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15843 [(set_attr "type" "lea")
15844 (set_attr "length_address" "4")
15845 (set_attr "mode" "DI")])
15847 (define_insn "set_rip_rex64"
15848 [(set (match_operand:DI 0 "register_operand" "=r")
15849 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15851 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15852 [(set_attr "type" "lea")
15853 (set_attr "length_address" "4")
15854 (set_attr "mode" "DI")])
15856 (define_insn "set_got_offset_rex64"
15857 [(set (match_operand:DI 0 "register_operand" "=r")
15859 [(label_ref (match_operand 1 "" ""))]
15860 UNSPEC_SET_GOT_OFFSET))]
15862 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15863 [(set_attr "type" "imov")
15864 (set_attr "length_immediate" "0")
15865 (set_attr "length_address" "8")
15866 (set_attr "mode" "DI")])
15868 (define_expand "epilogue"
15871 "ix86_expand_epilogue (1); DONE;")
15873 (define_expand "sibcall_epilogue"
15876 "ix86_expand_epilogue (0); DONE;")
15878 (define_expand "eh_return"
15879 [(use (match_operand 0 "register_operand" ""))]
15882 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15884 /* Tricky bit: we write the address of the handler to which we will
15885 be returning into someone else's stack frame, one word below the
15886 stack address we wish to restore. */
15887 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15888 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15889 tmp = gen_rtx_MEM (Pmode, tmp);
15890 emit_move_insn (tmp, ra);
15892 emit_jump_insn (gen_eh_return_internal ());
15897 (define_insn_and_split "eh_return_internal"
15901 "epilogue_completed"
15903 "ix86_expand_epilogue (2); DONE;")
15905 (define_insn "leave"
15906 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15907 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15908 (clobber (mem:BLK (scratch)))]
15911 [(set_attr "type" "leave")])
15913 (define_insn "leave_rex64"
15914 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15915 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15916 (clobber (mem:BLK (scratch)))]
15919 [(set_attr "type" "leave")])
15921 (define_expand "ffssi2"
15923 [(set (match_operand:SI 0 "register_operand" "")
15924 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15925 (clobber (match_scratch:SI 2 ""))
15926 (clobber (reg:CC FLAGS_REG))])]
15931 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15936 (define_expand "ffs_cmove"
15937 [(set (match_dup 2) (const_int -1))
15938 (parallel [(set (reg:CCZ FLAGS_REG)
15939 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15941 (set (match_operand:SI 0 "register_operand" "")
15942 (ctz:SI (match_dup 1)))])
15943 (set (match_dup 0) (if_then_else:SI
15944 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15947 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15948 (clobber (reg:CC FLAGS_REG))])]
15950 "operands[2] = gen_reg_rtx (SImode);")
15952 (define_insn_and_split "*ffs_no_cmove"
15953 [(set (match_operand:SI 0 "register_operand" "=r")
15954 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15955 (clobber (match_scratch:SI 2 "=&q"))
15956 (clobber (reg:CC FLAGS_REG))]
15959 "&& reload_completed"
15960 [(parallel [(set (reg:CCZ FLAGS_REG)
15961 (compare:CCZ (match_dup 1) (const_int 0)))
15962 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15963 (set (strict_low_part (match_dup 3))
15964 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15965 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15966 (clobber (reg:CC FLAGS_REG))])
15967 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15968 (clobber (reg:CC FLAGS_REG))])
15969 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15970 (clobber (reg:CC FLAGS_REG))])]
15972 operands[3] = gen_lowpart (QImode, operands[2]);
15973 ix86_expand_clear (operands[2]);
15976 (define_insn "*ffssi_1"
15977 [(set (reg:CCZ FLAGS_REG)
15978 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15980 (set (match_operand:SI 0 "register_operand" "=r")
15981 (ctz:SI (match_dup 1)))]
15983 "bsf{l}\t{%1, %0|%0, %1}"
15984 [(set_attr "type" "alu1")
15985 (set_attr "prefix_0f" "1")
15986 (set_attr "mode" "SI")])
15988 (define_expand "ffsdi2"
15989 [(set (match_dup 2) (const_int -1))
15990 (parallel [(set (reg:CCZ FLAGS_REG)
15991 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15993 (set (match_operand:DI 0 "register_operand" "")
15994 (ctz:DI (match_dup 1)))])
15995 (set (match_dup 0) (if_then_else:DI
15996 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15999 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16000 (clobber (reg:CC FLAGS_REG))])]
16002 "operands[2] = gen_reg_rtx (DImode);")
16004 (define_insn "*ffsdi_1"
16005 [(set (reg:CCZ FLAGS_REG)
16006 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
16008 (set (match_operand:DI 0 "register_operand" "=r")
16009 (ctz:DI (match_dup 1)))]
16011 "bsf{q}\t{%1, %0|%0, %1}"
16012 [(set_attr "type" "alu1")
16013 (set_attr "prefix_0f" "1")
16014 (set_attr "mode" "DI")])
16016 (define_insn "ctzsi2"
16017 [(set (match_operand:SI 0 "register_operand" "=r")
16018 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16019 (clobber (reg:CC FLAGS_REG))]
16021 "bsf{l}\t{%1, %0|%0, %1}"
16022 [(set_attr "type" "alu1")
16023 (set_attr "prefix_0f" "1")
16024 (set_attr "mode" "SI")])
16026 (define_insn "ctzdi2"
16027 [(set (match_operand:DI 0 "register_operand" "=r")
16028 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16029 (clobber (reg:CC FLAGS_REG))]
16031 "bsf{q}\t{%1, %0|%0, %1}"
16032 [(set_attr "type" "alu1")
16033 (set_attr "prefix_0f" "1")
16034 (set_attr "mode" "DI")])
16036 (define_expand "clzsi2"
16038 [(set (match_operand:SI 0 "register_operand" "")
16039 (minus:SI (const_int 31)
16040 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16041 (clobber (reg:CC FLAGS_REG))])
16043 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16044 (clobber (reg:CC FLAGS_REG))])]
16049 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16054 (define_insn "clzsi2_abm"
16055 [(set (match_operand:SI 0 "register_operand" "=r")
16056 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16057 (clobber (reg:CC FLAGS_REG))]
16059 "lzcnt{l}\t{%1, %0|%0, %1}"
16060 [(set_attr "prefix_rep" "1")
16061 (set_attr "type" "bitmanip")
16062 (set_attr "mode" "SI")])
16065 [(set (match_operand:SI 0 "register_operand" "=r")
16066 (minus:SI (const_int 31)
16067 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16068 (clobber (reg:CC FLAGS_REG))]
16070 "bsr{l}\t{%1, %0|%0, %1}"
16071 [(set_attr "type" "alu1")
16072 (set_attr "prefix_0f" "1")
16073 (set_attr "mode" "SI")])
16075 (define_insn "popcount<mode>2"
16076 [(set (match_operand:SWI248 0 "register_operand" "=r")
16078 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16079 (clobber (reg:CC FLAGS_REG))]
16083 return "popcnt\t{%1, %0|%0, %1}";
16085 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16088 [(set_attr "prefix_rep" "1")
16089 (set_attr "type" "bitmanip")
16090 (set_attr "mode" "<MODE>")])
16092 (define_insn "*popcount<mode>2_cmp"
16093 [(set (reg FLAGS_REG)
16096 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16098 (set (match_operand:SWI248 0 "register_operand" "=r")
16099 (popcount:SWI248 (match_dup 1)))]
16100 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16103 return "popcnt\t{%1, %0|%0, %1}";
16105 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16108 [(set_attr "prefix_rep" "1")
16109 (set_attr "type" "bitmanip")
16110 (set_attr "mode" "<MODE>")])
16112 (define_insn "*popcountsi2_cmp_zext"
16113 [(set (reg FLAGS_REG)
16115 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16117 (set (match_operand:DI 0 "register_operand" "=r")
16118 (zero_extend:DI(popcount:SI (match_dup 1))))]
16119 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16122 return "popcnt\t{%1, %0|%0, %1}";
16124 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16127 [(set_attr "prefix_rep" "1")
16128 (set_attr "type" "bitmanip")
16129 (set_attr "mode" "SI")])
16131 (define_expand "bswapsi2"
16132 [(set (match_operand:SI 0 "register_operand" "")
16133 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16136 if (!(TARGET_BSWAP || TARGET_MOVBE))
16138 rtx x = operands[0];
16140 emit_move_insn (x, operands[1]);
16141 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16142 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16143 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16148 (define_insn "*bswapsi_movbe"
16149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16150 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16151 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16154 movbe\t{%1, %0|%0, %1}
16155 movbe\t{%1, %0|%0, %1}"
16156 [(set_attr "type" "*,imov,imov")
16157 (set_attr "modrm" "*,1,1")
16158 (set_attr "prefix_0f" "1")
16159 (set_attr "prefix_extra" "*,1,1")
16160 (set_attr "length" "2,*,*")
16161 (set_attr "mode" "SI")])
16163 (define_insn "*bswapsi_1"
16164 [(set (match_operand:SI 0 "register_operand" "=r")
16165 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16168 [(set_attr "prefix_0f" "1")
16169 (set_attr "length" "2")])
16171 (define_insn "*bswaphi_lowpart_1"
16172 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16173 (bswap:HI (match_dup 0)))
16174 (clobber (reg:CC FLAGS_REG))]
16175 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16177 xchg{b}\t{%h0, %b0|%b0, %h0}
16178 rol{w}\t{$8, %0|%0, 8}"
16179 [(set_attr "length" "2,4")
16180 (set_attr "mode" "QI,HI")])
16182 (define_insn "bswaphi_lowpart"
16183 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16184 (bswap:HI (match_dup 0)))
16185 (clobber (reg:CC FLAGS_REG))]
16187 "rol{w}\t{$8, %0|%0, 8}"
16188 [(set_attr "length" "4")
16189 (set_attr "mode" "HI")])
16191 (define_expand "bswapdi2"
16192 [(set (match_operand:DI 0 "register_operand" "")
16193 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16197 (define_insn "*bswapdi_movbe"
16198 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16199 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16200 "TARGET_64BIT && TARGET_MOVBE
16201 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16204 movbe\t{%1, %0|%0, %1}
16205 movbe\t{%1, %0|%0, %1}"
16206 [(set_attr "type" "*,imov,imov")
16207 (set_attr "modrm" "*,1,1")
16208 (set_attr "prefix_0f" "1")
16209 (set_attr "prefix_extra" "*,1,1")
16210 (set_attr "length" "3,*,*")
16211 (set_attr "mode" "DI")])
16213 (define_insn "*bswapdi_1"
16214 [(set (match_operand:DI 0 "register_operand" "=r")
16215 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16218 [(set_attr "prefix_0f" "1")
16219 (set_attr "length" "3")])
16221 (define_expand "clzdi2"
16223 [(set (match_operand:DI 0 "register_operand" "")
16224 (minus:DI (const_int 63)
16225 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16226 (clobber (reg:CC FLAGS_REG))])
16228 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16229 (clobber (reg:CC FLAGS_REG))])]
16234 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16239 (define_insn "clzdi2_abm"
16240 [(set (match_operand:DI 0 "register_operand" "=r")
16241 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16242 (clobber (reg:CC FLAGS_REG))]
16243 "TARGET_64BIT && TARGET_ABM"
16244 "lzcnt{q}\t{%1, %0|%0, %1}"
16245 [(set_attr "prefix_rep" "1")
16246 (set_attr "type" "bitmanip")
16247 (set_attr "mode" "DI")])
16249 (define_insn "bsr_rex64"
16250 [(set (match_operand:DI 0 "register_operand" "=r")
16251 (minus:DI (const_int 63)
16252 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16253 (clobber (reg:CC FLAGS_REG))]
16255 "bsr{q}\t{%1, %0|%0, %1}"
16256 [(set_attr "type" "alu1")
16257 (set_attr "prefix_0f" "1")
16258 (set_attr "mode" "DI")])
16260 (define_expand "clzhi2"
16262 [(set (match_operand:HI 0 "register_operand" "")
16263 (minus:HI (const_int 15)
16264 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16265 (clobber (reg:CC FLAGS_REG))])
16267 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16268 (clobber (reg:CC FLAGS_REG))])]
16273 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16278 (define_insn "clzhi2_abm"
16279 [(set (match_operand:HI 0 "register_operand" "=r")
16280 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16281 (clobber (reg:CC FLAGS_REG))]
16283 "lzcnt{w}\t{%1, %0|%0, %1}"
16284 [(set_attr "prefix_rep" "1")
16285 (set_attr "type" "bitmanip")
16286 (set_attr "mode" "HI")])
16288 (define_insn "*bsrhi"
16289 [(set (match_operand:HI 0 "register_operand" "=r")
16290 (minus:HI (const_int 15)
16291 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16292 (clobber (reg:CC FLAGS_REG))]
16294 "bsr{w}\t{%1, %0|%0, %1}"
16295 [(set_attr "type" "alu1")
16296 (set_attr "prefix_0f" "1")
16297 (set_attr "mode" "HI")])
16299 (define_expand "paritydi2"
16300 [(set (match_operand:DI 0 "register_operand" "")
16301 (parity:DI (match_operand:DI 1 "register_operand" "")))]
16304 rtx scratch = gen_reg_rtx (QImode);
16307 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16308 NULL_RTX, operands[1]));
16310 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16311 gen_rtx_REG (CCmode, FLAGS_REG),
16313 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16316 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16319 rtx tmp = gen_reg_rtx (SImode);
16321 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16322 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16327 (define_insn_and_split "paritydi2_cmp"
16328 [(set (reg:CC FLAGS_REG)
16329 (parity:CC (match_operand:DI 3 "register_operand" "0")))
16330 (clobber (match_scratch:DI 0 "=r"))
16331 (clobber (match_scratch:SI 1 "=&r"))
16332 (clobber (match_scratch:HI 2 "=Q"))]
16335 "&& reload_completed"
16337 [(set (match_dup 1)
16338 (xor:SI (match_dup 1) (match_dup 4)))
16339 (clobber (reg:CC FLAGS_REG))])
16341 [(set (reg:CC FLAGS_REG)
16342 (parity:CC (match_dup 1)))
16343 (clobber (match_dup 1))
16344 (clobber (match_dup 2))])]
16346 operands[4] = gen_lowpart (SImode, operands[3]);
16350 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16351 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16354 operands[1] = gen_highpart (SImode, operands[3]);
16357 (define_expand "paritysi2"
16358 [(set (match_operand:SI 0 "register_operand" "")
16359 (parity:SI (match_operand:SI 1 "register_operand" "")))]
16362 rtx scratch = gen_reg_rtx (QImode);
16365 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16367 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16368 gen_rtx_REG (CCmode, FLAGS_REG),
16370 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16372 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16376 (define_insn_and_split "paritysi2_cmp"
16377 [(set (reg:CC FLAGS_REG)
16378 (parity:CC (match_operand:SI 2 "register_operand" "0")))
16379 (clobber (match_scratch:SI 0 "=r"))
16380 (clobber (match_scratch:HI 1 "=&Q"))]
16383 "&& reload_completed"
16385 [(set (match_dup 1)
16386 (xor:HI (match_dup 1) (match_dup 3)))
16387 (clobber (reg:CC FLAGS_REG))])
16389 [(set (reg:CC FLAGS_REG)
16390 (parity:CC (match_dup 1)))
16391 (clobber (match_dup 1))])]
16393 operands[3] = gen_lowpart (HImode, operands[2]);
16395 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16396 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16399 (define_insn "*parityhi2_cmp"
16400 [(set (reg:CC FLAGS_REG)
16401 (parity:CC (match_operand:HI 1 "register_operand" "0")))
16402 (clobber (match_scratch:HI 0 "=Q"))]
16404 "xor{b}\t{%h0, %b0|%b0, %h0}"
16405 [(set_attr "length" "2")
16406 (set_attr "mode" "HI")])
16408 (define_insn "*parityqi2_cmp"
16409 [(set (reg:CC FLAGS_REG)
16410 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16413 [(set_attr "length" "2")
16414 (set_attr "mode" "QI")])
16416 ;; Thread-local storage patterns for ELF.
16418 ;; Note that these code sequences must appear exactly as shown
16419 ;; in order to allow linker relaxation.
16421 (define_insn "*tls_global_dynamic_32_gnu"
16422 [(set (match_operand:SI 0 "register_operand" "=a")
16423 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16424 (match_operand:SI 2 "tls_symbolic_operand" "")
16425 (match_operand:SI 3 "call_insn_operand" "")]
16427 (clobber (match_scratch:SI 4 "=d"))
16428 (clobber (match_scratch:SI 5 "=c"))
16429 (clobber (reg:CC FLAGS_REG))]
16430 "!TARGET_64BIT && TARGET_GNU_TLS"
16431 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16432 [(set_attr "type" "multi")
16433 (set_attr "length" "12")])
16435 (define_insn "*tls_global_dynamic_32_sun"
16436 [(set (match_operand:SI 0 "register_operand" "=a")
16437 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16438 (match_operand:SI 2 "tls_symbolic_operand" "")
16439 (match_operand:SI 3 "call_insn_operand" "")]
16441 (clobber (match_scratch:SI 4 "=d"))
16442 (clobber (match_scratch:SI 5 "=c"))
16443 (clobber (reg:CC FLAGS_REG))]
16444 "!TARGET_64BIT && TARGET_SUN_TLS"
16445 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16446 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16447 [(set_attr "type" "multi")
16448 (set_attr "length" "14")])
16450 (define_expand "tls_global_dynamic_32"
16451 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16454 (match_operand:SI 1 "tls_symbolic_operand" "")
16457 (clobber (match_scratch:SI 4 ""))
16458 (clobber (match_scratch:SI 5 ""))
16459 (clobber (reg:CC FLAGS_REG))])]
16463 operands[2] = pic_offset_table_rtx;
16466 operands[2] = gen_reg_rtx (Pmode);
16467 emit_insn (gen_set_got (operands[2]));
16469 if (TARGET_GNU2_TLS)
16471 emit_insn (gen_tls_dynamic_gnu2_32
16472 (operands[0], operands[1], operands[2]));
16475 operands[3] = ix86_tls_get_addr ();
16478 (define_insn "*tls_global_dynamic_64"
16479 [(set (match_operand:DI 0 "register_operand" "=a")
16480 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16481 (match_operand:DI 3 "" "")))
16482 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16485 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16486 [(set_attr "type" "multi")
16487 (set_attr "length" "16")])
16489 (define_expand "tls_global_dynamic_64"
16490 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16491 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16492 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16496 if (TARGET_GNU2_TLS)
16498 emit_insn (gen_tls_dynamic_gnu2_64
16499 (operands[0], operands[1]));
16502 operands[2] = ix86_tls_get_addr ();
16505 (define_insn "*tls_local_dynamic_base_32_gnu"
16506 [(set (match_operand:SI 0 "register_operand" "=a")
16507 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16508 (match_operand:SI 2 "call_insn_operand" "")]
16509 UNSPEC_TLS_LD_BASE))
16510 (clobber (match_scratch:SI 3 "=d"))
16511 (clobber (match_scratch:SI 4 "=c"))
16512 (clobber (reg:CC FLAGS_REG))]
16513 "!TARGET_64BIT && TARGET_GNU_TLS"
16514 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16515 [(set_attr "type" "multi")
16516 (set_attr "length" "11")])
16518 (define_insn "*tls_local_dynamic_base_32_sun"
16519 [(set (match_operand:SI 0 "register_operand" "=a")
16520 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16521 (match_operand:SI 2 "call_insn_operand" "")]
16522 UNSPEC_TLS_LD_BASE))
16523 (clobber (match_scratch:SI 3 "=d"))
16524 (clobber (match_scratch:SI 4 "=c"))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "!TARGET_64BIT && TARGET_SUN_TLS"
16527 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16528 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16529 [(set_attr "type" "multi")
16530 (set_attr "length" "13")])
16532 (define_expand "tls_local_dynamic_base_32"
16533 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16534 (unspec:SI [(match_dup 1) (match_dup 2)]
16535 UNSPEC_TLS_LD_BASE))
16536 (clobber (match_scratch:SI 3 ""))
16537 (clobber (match_scratch:SI 4 ""))
16538 (clobber (reg:CC FLAGS_REG))])]
16542 operands[1] = pic_offset_table_rtx;
16545 operands[1] = gen_reg_rtx (Pmode);
16546 emit_insn (gen_set_got (operands[1]));
16548 if (TARGET_GNU2_TLS)
16550 emit_insn (gen_tls_dynamic_gnu2_32
16551 (operands[0], ix86_tls_module_base (), operands[1]));
16554 operands[2] = ix86_tls_get_addr ();
16557 (define_insn "*tls_local_dynamic_base_64"
16558 [(set (match_operand:DI 0 "register_operand" "=a")
16559 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16560 (match_operand:DI 2 "" "")))
16561 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16563 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16564 [(set_attr "type" "multi")
16565 (set_attr "length" "12")])
16567 (define_expand "tls_local_dynamic_base_64"
16568 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16569 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16570 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16573 if (TARGET_GNU2_TLS)
16575 emit_insn (gen_tls_dynamic_gnu2_64
16576 (operands[0], ix86_tls_module_base ()));
16579 operands[1] = ix86_tls_get_addr ();
16582 ;; Local dynamic of a single variable is a lose. Show combine how
16583 ;; to convert that back to global dynamic.
16585 (define_insn_and_split "*tls_local_dynamic_32_once"
16586 [(set (match_operand:SI 0 "register_operand" "=a")
16587 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16588 (match_operand:SI 2 "call_insn_operand" "")]
16589 UNSPEC_TLS_LD_BASE)
16590 (const:SI (unspec:SI
16591 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16593 (clobber (match_scratch:SI 4 "=d"))
16594 (clobber (match_scratch:SI 5 "=c"))
16595 (clobber (reg:CC FLAGS_REG))]
16599 [(parallel [(set (match_dup 0)
16600 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16602 (clobber (match_dup 4))
16603 (clobber (match_dup 5))
16604 (clobber (reg:CC FLAGS_REG))])]
16607 ;; Load and add the thread base pointer from %gs:0.
16609 (define_insn "*load_tp_si"
16610 [(set (match_operand:SI 0 "register_operand" "=r")
16611 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16613 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16614 [(set_attr "type" "imov")
16615 (set_attr "modrm" "0")
16616 (set_attr "length" "7")
16617 (set_attr "memory" "load")
16618 (set_attr "imm_disp" "false")])
16620 (define_insn "*add_tp_si"
16621 [(set (match_operand:SI 0 "register_operand" "=r")
16622 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16623 (match_operand:SI 1 "register_operand" "0")))
16624 (clobber (reg:CC FLAGS_REG))]
16626 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16627 [(set_attr "type" "alu")
16628 (set_attr "modrm" "0")
16629 (set_attr "length" "7")
16630 (set_attr "memory" "load")
16631 (set_attr "imm_disp" "false")])
16633 (define_insn "*load_tp_di"
16634 [(set (match_operand:DI 0 "register_operand" "=r")
16635 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16637 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16638 [(set_attr "type" "imov")
16639 (set_attr "modrm" "0")
16640 (set_attr "length" "7")
16641 (set_attr "memory" "load")
16642 (set_attr "imm_disp" "false")])
16644 (define_insn "*add_tp_di"
16645 [(set (match_operand:DI 0 "register_operand" "=r")
16646 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16647 (match_operand:DI 1 "register_operand" "0")))
16648 (clobber (reg:CC FLAGS_REG))]
16650 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16651 [(set_attr "type" "alu")
16652 (set_attr "modrm" "0")
16653 (set_attr "length" "7")
16654 (set_attr "memory" "load")
16655 (set_attr "imm_disp" "false")])
16657 ;; GNU2 TLS patterns can be split.
16659 (define_expand "tls_dynamic_gnu2_32"
16660 [(set (match_dup 3)
16661 (plus:SI (match_operand:SI 2 "register_operand" "")
16663 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16666 [(set (match_operand:SI 0 "register_operand" "")
16667 (unspec:SI [(match_dup 1) (match_dup 3)
16668 (match_dup 2) (reg:SI SP_REG)]
16670 (clobber (reg:CC FLAGS_REG))])]
16671 "!TARGET_64BIT && TARGET_GNU2_TLS"
16673 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16674 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16677 (define_insn "*tls_dynamic_lea_32"
16678 [(set (match_operand:SI 0 "register_operand" "=r")
16679 (plus:SI (match_operand:SI 1 "register_operand" "b")
16681 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16682 UNSPEC_TLSDESC))))]
16683 "!TARGET_64BIT && TARGET_GNU2_TLS"
16684 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16685 [(set_attr "type" "lea")
16686 (set_attr "mode" "SI")
16687 (set_attr "length" "6")
16688 (set_attr "length_address" "4")])
16690 (define_insn "*tls_dynamic_call_32"
16691 [(set (match_operand:SI 0 "register_operand" "=a")
16692 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16693 (match_operand:SI 2 "register_operand" "0")
16694 ;; we have to make sure %ebx still points to the GOT
16695 (match_operand:SI 3 "register_operand" "b")
16698 (clobber (reg:CC FLAGS_REG))]
16699 "!TARGET_64BIT && TARGET_GNU2_TLS"
16700 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16701 [(set_attr "type" "call")
16702 (set_attr "length" "2")
16703 (set_attr "length_address" "0")])
16705 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16706 [(set (match_operand:SI 0 "register_operand" "=&a")
16708 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16709 (match_operand:SI 4 "" "")
16710 (match_operand:SI 2 "register_operand" "b")
16713 (const:SI (unspec:SI
16714 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16716 (clobber (reg:CC FLAGS_REG))]
16717 "!TARGET_64BIT && TARGET_GNU2_TLS"
16720 [(set (match_dup 0) (match_dup 5))]
16722 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16723 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16726 (define_expand "tls_dynamic_gnu2_64"
16727 [(set (match_dup 2)
16728 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16731 [(set (match_operand:DI 0 "register_operand" "")
16732 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16734 (clobber (reg:CC FLAGS_REG))])]
16735 "TARGET_64BIT && TARGET_GNU2_TLS"
16737 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16738 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16741 (define_insn "*tls_dynamic_lea_64"
16742 [(set (match_operand:DI 0 "register_operand" "=r")
16743 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16745 "TARGET_64BIT && TARGET_GNU2_TLS"
16746 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16747 [(set_attr "type" "lea")
16748 (set_attr "mode" "DI")
16749 (set_attr "length" "7")
16750 (set_attr "length_address" "4")])
16752 (define_insn "*tls_dynamic_call_64"
16753 [(set (match_operand:DI 0 "register_operand" "=a")
16754 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16755 (match_operand:DI 2 "register_operand" "0")
16758 (clobber (reg:CC FLAGS_REG))]
16759 "TARGET_64BIT && TARGET_GNU2_TLS"
16760 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16761 [(set_attr "type" "call")
16762 (set_attr "length" "2")
16763 (set_attr "length_address" "0")])
16765 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16766 [(set (match_operand:DI 0 "register_operand" "=&a")
16768 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16769 (match_operand:DI 3 "" "")
16772 (const:DI (unspec:DI
16773 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16775 (clobber (reg:CC FLAGS_REG))]
16776 "TARGET_64BIT && TARGET_GNU2_TLS"
16779 [(set (match_dup 0) (match_dup 4))]
16781 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16782 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16787 ;; These patterns match the binary 387 instructions for addM3, subM3,
16788 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16789 ;; SFmode. The first is the normal insn, the second the same insn but
16790 ;; with one operand a conversion, and the third the same insn but with
16791 ;; the other operand a conversion. The conversion may be SFmode or
16792 ;; SImode if the target mode DFmode, but only SImode if the target mode
16795 ;; Gcc is slightly more smart about handling normal two address instructions
16796 ;; so use special patterns for add and mull.
16798 (define_insn "*fop_<mode>_comm_mixed_avx"
16799 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16800 (match_operator:MODEF 3 "binary_fp_operator"
16801 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16802 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16803 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16804 && COMMUTATIVE_ARITH_P (operands[3])
16805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16806 "* return output_387_binary_op (insn, operands);"
16807 [(set (attr "type")
16808 (if_then_else (eq_attr "alternative" "1")
16809 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16810 (const_string "ssemul")
16811 (const_string "sseadd"))
16812 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16813 (const_string "fmul")
16814 (const_string "fop"))))
16815 (set_attr "prefix" "orig,maybe_vex")
16816 (set_attr "mode" "<MODE>")])
16818 (define_insn "*fop_<mode>_comm_mixed"
16819 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16820 (match_operator:MODEF 3 "binary_fp_operator"
16821 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16822 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16823 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16824 && COMMUTATIVE_ARITH_P (operands[3])
16825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16826 "* return output_387_binary_op (insn, operands);"
16827 [(set (attr "type")
16828 (if_then_else (eq_attr "alternative" "1")
16829 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16830 (const_string "ssemul")
16831 (const_string "sseadd"))
16832 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16833 (const_string "fmul")
16834 (const_string "fop"))))
16835 (set_attr "mode" "<MODE>")])
16837 (define_insn "*fop_<mode>_comm_avx"
16838 [(set (match_operand:MODEF 0 "register_operand" "=x")
16839 (match_operator:MODEF 3 "binary_fp_operator"
16840 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16841 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16842 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16843 && COMMUTATIVE_ARITH_P (operands[3])
16844 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16845 "* return output_387_binary_op (insn, operands);"
16846 [(set (attr "type")
16847 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16848 (const_string "ssemul")
16849 (const_string "sseadd")))
16850 (set_attr "prefix" "vex")
16851 (set_attr "mode" "<MODE>")])
16853 (define_insn "*fop_<mode>_comm_sse"
16854 [(set (match_operand:MODEF 0 "register_operand" "=x")
16855 (match_operator:MODEF 3 "binary_fp_operator"
16856 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16857 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16858 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16859 && COMMUTATIVE_ARITH_P (operands[3])
16860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16861 "* return output_387_binary_op (insn, operands);"
16862 [(set (attr "type")
16863 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16864 (const_string "ssemul")
16865 (const_string "sseadd")))
16866 (set_attr "mode" "<MODE>")])
16868 (define_insn "*fop_<mode>_comm_i387"
16869 [(set (match_operand:MODEF 0 "register_operand" "=f")
16870 (match_operator:MODEF 3 "binary_fp_operator"
16871 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16872 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16873 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16874 && COMMUTATIVE_ARITH_P (operands[3])
16875 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16876 "* return output_387_binary_op (insn, operands);"
16877 [(set (attr "type")
16878 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16879 (const_string "fmul")
16880 (const_string "fop")))
16881 (set_attr "mode" "<MODE>")])
16883 (define_insn "*fop_<mode>_1_mixed_avx"
16884 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16885 (match_operator:MODEF 3 "binary_fp_operator"
16886 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16887 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16888 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16889 && !COMMUTATIVE_ARITH_P (operands[3])
16890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16891 "* return output_387_binary_op (insn, operands);"
16892 [(set (attr "type")
16893 (cond [(and (eq_attr "alternative" "2")
16894 (match_operand:MODEF 3 "mult_operator" ""))
16895 (const_string "ssemul")
16896 (and (eq_attr "alternative" "2")
16897 (match_operand:MODEF 3 "div_operator" ""))
16898 (const_string "ssediv")
16899 (eq_attr "alternative" "2")
16900 (const_string "sseadd")
16901 (match_operand:MODEF 3 "mult_operator" "")
16902 (const_string "fmul")
16903 (match_operand:MODEF 3 "div_operator" "")
16904 (const_string "fdiv")
16906 (const_string "fop")))
16907 (set_attr "prefix" "orig,orig,maybe_vex")
16908 (set_attr "mode" "<MODE>")])
16910 (define_insn "*fop_<mode>_1_mixed"
16911 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16912 (match_operator:MODEF 3 "binary_fp_operator"
16913 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16914 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16915 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16916 && !COMMUTATIVE_ARITH_P (operands[3])
16917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16918 "* return output_387_binary_op (insn, operands);"
16919 [(set (attr "type")
16920 (cond [(and (eq_attr "alternative" "2")
16921 (match_operand:MODEF 3 "mult_operator" ""))
16922 (const_string "ssemul")
16923 (and (eq_attr "alternative" "2")
16924 (match_operand:MODEF 3 "div_operator" ""))
16925 (const_string "ssediv")
16926 (eq_attr "alternative" "2")
16927 (const_string "sseadd")
16928 (match_operand:MODEF 3 "mult_operator" "")
16929 (const_string "fmul")
16930 (match_operand:MODEF 3 "div_operator" "")
16931 (const_string "fdiv")
16933 (const_string "fop")))
16934 (set_attr "mode" "<MODE>")])
16936 (define_insn "*rcpsf2_sse"
16937 [(set (match_operand:SF 0 "register_operand" "=x")
16938 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16941 "%vrcpss\t{%1, %d0|%d0, %1}"
16942 [(set_attr "type" "sse")
16943 (set_attr "atom_sse_attr" "rcp")
16944 (set_attr "prefix" "maybe_vex")
16945 (set_attr "mode" "SF")])
16947 (define_insn "*fop_<mode>_1_avx"
16948 [(set (match_operand:MODEF 0 "register_operand" "=x")
16949 (match_operator:MODEF 3 "binary_fp_operator"
16950 [(match_operand:MODEF 1 "register_operand" "x")
16951 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16952 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16953 && !COMMUTATIVE_ARITH_P (operands[3])"
16954 "* return output_387_binary_op (insn, operands);"
16955 [(set (attr "type")
16956 (cond [(match_operand:MODEF 3 "mult_operator" "")
16957 (const_string "ssemul")
16958 (match_operand:MODEF 3 "div_operator" "")
16959 (const_string "ssediv")
16961 (const_string "sseadd")))
16962 (set_attr "prefix" "vex")
16963 (set_attr "mode" "<MODE>")])
16965 (define_insn "*fop_<mode>_1_sse"
16966 [(set (match_operand:MODEF 0 "register_operand" "=x")
16967 (match_operator:MODEF 3 "binary_fp_operator"
16968 [(match_operand:MODEF 1 "register_operand" "0")
16969 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16971 && !COMMUTATIVE_ARITH_P (operands[3])"
16972 "* return output_387_binary_op (insn, operands);"
16973 [(set (attr "type")
16974 (cond [(match_operand:MODEF 3 "mult_operator" "")
16975 (const_string "ssemul")
16976 (match_operand:MODEF 3 "div_operator" "")
16977 (const_string "ssediv")
16979 (const_string "sseadd")))
16980 (set_attr "mode" "<MODE>")])
16982 ;; This pattern is not fully shadowed by the pattern above.
16983 (define_insn "*fop_<mode>_1_i387"
16984 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16985 (match_operator:MODEF 3 "binary_fp_operator"
16986 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16987 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16988 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16989 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16990 && !COMMUTATIVE_ARITH_P (operands[3])
16991 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16992 "* return output_387_binary_op (insn, operands);"
16993 [(set (attr "type")
16994 (cond [(match_operand:MODEF 3 "mult_operator" "")
16995 (const_string "fmul")
16996 (match_operand:MODEF 3 "div_operator" "")
16997 (const_string "fdiv")
16999 (const_string "fop")))
17000 (set_attr "mode" "<MODE>")])
17002 ;; ??? Add SSE splitters for these!
17003 (define_insn "*fop_<MODEF:mode>_2_i387"
17004 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17005 (match_operator:MODEF 3 "binary_fp_operator"
17007 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17008 (match_operand:MODEF 2 "register_operand" "0,0")]))]
17009 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17010 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17011 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17012 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17013 [(set (attr "type")
17014 (cond [(match_operand:MODEF 3 "mult_operator" "")
17015 (const_string "fmul")
17016 (match_operand:MODEF 3 "div_operator" "")
17017 (const_string "fdiv")
17019 (const_string "fop")))
17020 (set_attr "fp_int_src" "true")
17021 (set_attr "mode" "<X87MODEI12:MODE>")])
17023 (define_insn "*fop_<MODEF:mode>_3_i387"
17024 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17025 (match_operator:MODEF 3 "binary_fp_operator"
17026 [(match_operand:MODEF 1 "register_operand" "0,0")
17028 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17029 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17030 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17031 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17032 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17033 [(set (attr "type")
17034 (cond [(match_operand:MODEF 3 "mult_operator" "")
17035 (const_string "fmul")
17036 (match_operand:MODEF 3 "div_operator" "")
17037 (const_string "fdiv")
17039 (const_string "fop")))
17040 (set_attr "fp_int_src" "true")
17041 (set_attr "mode" "<MODE>")])
17043 (define_insn "*fop_df_4_i387"
17044 [(set (match_operand:DF 0 "register_operand" "=f,f")
17045 (match_operator:DF 3 "binary_fp_operator"
17047 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17048 (match_operand:DF 2 "register_operand" "0,f")]))]
17049 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17050 && !(TARGET_SSE2 && TARGET_SSE_MATH)
17051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17052 "* return output_387_binary_op (insn, operands);"
17053 [(set (attr "type")
17054 (cond [(match_operand:DF 3 "mult_operator" "")
17055 (const_string "fmul")
17056 (match_operand:DF 3 "div_operator" "")
17057 (const_string "fdiv")
17059 (const_string "fop")))
17060 (set_attr "mode" "SF")])
17062 (define_insn "*fop_df_5_i387"
17063 [(set (match_operand:DF 0 "register_operand" "=f,f")
17064 (match_operator:DF 3 "binary_fp_operator"
17065 [(match_operand:DF 1 "register_operand" "0,f")
17067 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17068 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17069 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17070 "* return output_387_binary_op (insn, operands);"
17071 [(set (attr "type")
17072 (cond [(match_operand:DF 3 "mult_operator" "")
17073 (const_string "fmul")
17074 (match_operand:DF 3 "div_operator" "")
17075 (const_string "fdiv")
17077 (const_string "fop")))
17078 (set_attr "mode" "SF")])
17080 (define_insn "*fop_df_6_i387"
17081 [(set (match_operand:DF 0 "register_operand" "=f,f")
17082 (match_operator:DF 3 "binary_fp_operator"
17084 (match_operand:SF 1 "register_operand" "0,f"))
17086 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17087 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17088 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17089 "* return output_387_binary_op (insn, operands);"
17090 [(set (attr "type")
17091 (cond [(match_operand:DF 3 "mult_operator" "")
17092 (const_string "fmul")
17093 (match_operand:DF 3 "div_operator" "")
17094 (const_string "fdiv")
17096 (const_string "fop")))
17097 (set_attr "mode" "SF")])
17099 (define_insn "*fop_xf_comm_i387"
17100 [(set (match_operand:XF 0 "register_operand" "=f")
17101 (match_operator:XF 3 "binary_fp_operator"
17102 [(match_operand:XF 1 "register_operand" "%0")
17103 (match_operand:XF 2 "register_operand" "f")]))]
17105 && COMMUTATIVE_ARITH_P (operands[3])"
17106 "* return output_387_binary_op (insn, operands);"
17107 [(set (attr "type")
17108 (if_then_else (match_operand:XF 3 "mult_operator" "")
17109 (const_string "fmul")
17110 (const_string "fop")))
17111 (set_attr "mode" "XF")])
17113 (define_insn "*fop_xf_1_i387"
17114 [(set (match_operand:XF 0 "register_operand" "=f,f")
17115 (match_operator:XF 3 "binary_fp_operator"
17116 [(match_operand:XF 1 "register_operand" "0,f")
17117 (match_operand:XF 2 "register_operand" "f,0")]))]
17119 && !COMMUTATIVE_ARITH_P (operands[3])"
17120 "* return output_387_binary_op (insn, operands);"
17121 [(set (attr "type")
17122 (cond [(match_operand:XF 3 "mult_operator" "")
17123 (const_string "fmul")
17124 (match_operand:XF 3 "div_operator" "")
17125 (const_string "fdiv")
17127 (const_string "fop")))
17128 (set_attr "mode" "XF")])
17130 (define_insn "*fop_xf_2_i387"
17131 [(set (match_operand:XF 0 "register_operand" "=f,f")
17132 (match_operator:XF 3 "binary_fp_operator"
17134 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17135 (match_operand:XF 2 "register_operand" "0,0")]))]
17136 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17137 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17138 [(set (attr "type")
17139 (cond [(match_operand:XF 3 "mult_operator" "")
17140 (const_string "fmul")
17141 (match_operand:XF 3 "div_operator" "")
17142 (const_string "fdiv")
17144 (const_string "fop")))
17145 (set_attr "fp_int_src" "true")
17146 (set_attr "mode" "<MODE>")])
17148 (define_insn "*fop_xf_3_i387"
17149 [(set (match_operand:XF 0 "register_operand" "=f,f")
17150 (match_operator:XF 3 "binary_fp_operator"
17151 [(match_operand:XF 1 "register_operand" "0,0")
17153 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17154 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17155 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17156 [(set (attr "type")
17157 (cond [(match_operand:XF 3 "mult_operator" "")
17158 (const_string "fmul")
17159 (match_operand:XF 3 "div_operator" "")
17160 (const_string "fdiv")
17162 (const_string "fop")))
17163 (set_attr "fp_int_src" "true")
17164 (set_attr "mode" "<MODE>")])
17166 (define_insn "*fop_xf_4_i387"
17167 [(set (match_operand:XF 0 "register_operand" "=f,f")
17168 (match_operator:XF 3 "binary_fp_operator"
17170 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17171 (match_operand:XF 2 "register_operand" "0,f")]))]
17173 "* return output_387_binary_op (insn, operands);"
17174 [(set (attr "type")
17175 (cond [(match_operand:XF 3 "mult_operator" "")
17176 (const_string "fmul")
17177 (match_operand:XF 3 "div_operator" "")
17178 (const_string "fdiv")
17180 (const_string "fop")))
17181 (set_attr "mode" "<MODE>")])
17183 (define_insn "*fop_xf_5_i387"
17184 [(set (match_operand:XF 0 "register_operand" "=f,f")
17185 (match_operator:XF 3 "binary_fp_operator"
17186 [(match_operand:XF 1 "register_operand" "0,f")
17188 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17190 "* return output_387_binary_op (insn, operands);"
17191 [(set (attr "type")
17192 (cond [(match_operand:XF 3 "mult_operator" "")
17193 (const_string "fmul")
17194 (match_operand:XF 3 "div_operator" "")
17195 (const_string "fdiv")
17197 (const_string "fop")))
17198 (set_attr "mode" "<MODE>")])
17200 (define_insn "*fop_xf_6_i387"
17201 [(set (match_operand:XF 0 "register_operand" "=f,f")
17202 (match_operator:XF 3 "binary_fp_operator"
17204 (match_operand:MODEF 1 "register_operand" "0,f"))
17206 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17208 "* return output_387_binary_op (insn, operands);"
17209 [(set (attr "type")
17210 (cond [(match_operand:XF 3 "mult_operator" "")
17211 (const_string "fmul")
17212 (match_operand:XF 3 "div_operator" "")
17213 (const_string "fdiv")
17215 (const_string "fop")))
17216 (set_attr "mode" "<MODE>")])
17219 [(set (match_operand 0 "register_operand" "")
17220 (match_operator 3 "binary_fp_operator"
17221 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17222 (match_operand 2 "register_operand" "")]))]
17224 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17225 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17228 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17229 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17230 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17231 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17232 GET_MODE (operands[3]),
17235 ix86_free_from_memory (GET_MODE (operands[1]));
17240 [(set (match_operand 0 "register_operand" "")
17241 (match_operator 3 "binary_fp_operator"
17242 [(match_operand 1 "register_operand" "")
17243 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17245 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17246 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17249 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17250 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17251 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17252 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17253 GET_MODE (operands[3]),
17256 ix86_free_from_memory (GET_MODE (operands[2]));
17260 ;; FPU special functions.
17262 ;; This pattern implements a no-op XFmode truncation for
17263 ;; all fancy i386 XFmode math functions.
17265 (define_insn "truncxf<mode>2_i387_noop_unspec"
17266 [(set (match_operand:MODEF 0 "register_operand" "=f")
17267 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17268 UNSPEC_TRUNC_NOOP))]
17269 "TARGET_USE_FANCY_MATH_387"
17270 "* return output_387_reg_move (insn, operands);"
17271 [(set_attr "type" "fmov")
17272 (set_attr "mode" "<MODE>")])
17274 (define_insn "sqrtxf2"
17275 [(set (match_operand:XF 0 "register_operand" "=f")
17276 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17277 "TARGET_USE_FANCY_MATH_387"
17279 [(set_attr "type" "fpspc")
17280 (set_attr "mode" "XF")
17281 (set_attr "athlon_decode" "direct")
17282 (set_attr "amdfam10_decode" "direct")])
17284 (define_insn "sqrt_extend<mode>xf2_i387"
17285 [(set (match_operand:XF 0 "register_operand" "=f")
17288 (match_operand:MODEF 1 "register_operand" "0"))))]
17289 "TARGET_USE_FANCY_MATH_387"
17291 [(set_attr "type" "fpspc")
17292 (set_attr "mode" "XF")
17293 (set_attr "athlon_decode" "direct")
17294 (set_attr "amdfam10_decode" "direct")])
17296 (define_insn "*rsqrtsf2_sse"
17297 [(set (match_operand:SF 0 "register_operand" "=x")
17298 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17301 "%vrsqrtss\t{%1, %d0|%d0, %1}"
17302 [(set_attr "type" "sse")
17303 (set_attr "atom_sse_attr" "rcp")
17304 (set_attr "prefix" "maybe_vex")
17305 (set_attr "mode" "SF")])
17307 (define_expand "rsqrtsf2"
17308 [(set (match_operand:SF 0 "register_operand" "")
17309 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17313 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17317 (define_insn "*sqrt<mode>2_sse"
17318 [(set (match_operand:MODEF 0 "register_operand" "=x")
17320 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17321 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17322 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17323 [(set_attr "type" "sse")
17324 (set_attr "atom_sse_attr" "sqrt")
17325 (set_attr "prefix" "maybe_vex")
17326 (set_attr "mode" "<MODE>")
17327 (set_attr "athlon_decode" "*")
17328 (set_attr "amdfam10_decode" "*")])
17330 (define_expand "sqrt<mode>2"
17331 [(set (match_operand:MODEF 0 "register_operand" "")
17333 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17334 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17335 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17337 if (<MODE>mode == SFmode
17338 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17339 && flag_finite_math_only && !flag_trapping_math
17340 && flag_unsafe_math_optimizations)
17342 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17346 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17348 rtx op0 = gen_reg_rtx (XFmode);
17349 rtx op1 = force_reg (<MODE>mode, operands[1]);
17351 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17352 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17357 (define_insn "fpremxf4_i387"
17358 [(set (match_operand:XF 0 "register_operand" "=f")
17359 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17360 (match_operand:XF 3 "register_operand" "1")]
17362 (set (match_operand:XF 1 "register_operand" "=u")
17363 (unspec:XF [(match_dup 2) (match_dup 3)]
17365 (set (reg:CCFP FPSR_REG)
17366 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17368 "TARGET_USE_FANCY_MATH_387"
17370 [(set_attr "type" "fpspc")
17371 (set_attr "mode" "XF")])
17373 (define_expand "fmodxf3"
17374 [(use (match_operand:XF 0 "register_operand" ""))
17375 (use (match_operand:XF 1 "general_operand" ""))
17376 (use (match_operand:XF 2 "general_operand" ""))]
17377 "TARGET_USE_FANCY_MATH_387"
17379 rtx label = gen_label_rtx ();
17381 rtx op1 = gen_reg_rtx (XFmode);
17382 rtx op2 = gen_reg_rtx (XFmode);
17384 emit_move_insn (op2, operands[2]);
17385 emit_move_insn (op1, operands[1]);
17387 emit_label (label);
17388 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17389 ix86_emit_fp_unordered_jump (label);
17390 LABEL_NUSES (label) = 1;
17392 emit_move_insn (operands[0], op1);
17396 (define_expand "fmod<mode>3"
17397 [(use (match_operand:MODEF 0 "register_operand" ""))
17398 (use (match_operand:MODEF 1 "general_operand" ""))
17399 (use (match_operand:MODEF 2 "general_operand" ""))]
17400 "TARGET_USE_FANCY_MATH_387"
17402 rtx label = gen_label_rtx ();
17404 rtx op1 = gen_reg_rtx (XFmode);
17405 rtx op2 = gen_reg_rtx (XFmode);
17407 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17408 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17410 emit_label (label);
17411 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17412 ix86_emit_fp_unordered_jump (label);
17413 LABEL_NUSES (label) = 1;
17415 /* Truncate the result properly for strict SSE math. */
17416 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17417 && !TARGET_MIX_SSE_I387)
17418 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17420 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17425 (define_insn "fprem1xf4_i387"
17426 [(set (match_operand:XF 0 "register_operand" "=f")
17427 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17428 (match_operand:XF 3 "register_operand" "1")]
17430 (set (match_operand:XF 1 "register_operand" "=u")
17431 (unspec:XF [(match_dup 2) (match_dup 3)]
17433 (set (reg:CCFP FPSR_REG)
17434 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17436 "TARGET_USE_FANCY_MATH_387"
17438 [(set_attr "type" "fpspc")
17439 (set_attr "mode" "XF")])
17441 (define_expand "remainderxf3"
17442 [(use (match_operand:XF 0 "register_operand" ""))
17443 (use (match_operand:XF 1 "general_operand" ""))
17444 (use (match_operand:XF 2 "general_operand" ""))]
17445 "TARGET_USE_FANCY_MATH_387"
17447 rtx label = gen_label_rtx ();
17449 rtx op1 = gen_reg_rtx (XFmode);
17450 rtx op2 = gen_reg_rtx (XFmode);
17452 emit_move_insn (op2, operands[2]);
17453 emit_move_insn (op1, operands[1]);
17455 emit_label (label);
17456 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17457 ix86_emit_fp_unordered_jump (label);
17458 LABEL_NUSES (label) = 1;
17460 emit_move_insn (operands[0], op1);
17464 (define_expand "remainder<mode>3"
17465 [(use (match_operand:MODEF 0 "register_operand" ""))
17466 (use (match_operand:MODEF 1 "general_operand" ""))
17467 (use (match_operand:MODEF 2 "general_operand" ""))]
17468 "TARGET_USE_FANCY_MATH_387"
17470 rtx label = gen_label_rtx ();
17472 rtx op1 = gen_reg_rtx (XFmode);
17473 rtx op2 = gen_reg_rtx (XFmode);
17475 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17478 emit_label (label);
17480 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17481 ix86_emit_fp_unordered_jump (label);
17482 LABEL_NUSES (label) = 1;
17484 /* Truncate the result properly for strict SSE math. */
17485 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17486 && !TARGET_MIX_SSE_I387)
17487 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17489 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17494 (define_insn "*sinxf2_i387"
17495 [(set (match_operand:XF 0 "register_operand" "=f")
17496 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17497 "TARGET_USE_FANCY_MATH_387
17498 && flag_unsafe_math_optimizations"
17500 [(set_attr "type" "fpspc")
17501 (set_attr "mode" "XF")])
17503 (define_insn "*sin_extend<mode>xf2_i387"
17504 [(set (match_operand:XF 0 "register_operand" "=f")
17505 (unspec:XF [(float_extend:XF
17506 (match_operand:MODEF 1 "register_operand" "0"))]
17508 "TARGET_USE_FANCY_MATH_387
17509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17510 || TARGET_MIX_SSE_I387)
17511 && flag_unsafe_math_optimizations"
17513 [(set_attr "type" "fpspc")
17514 (set_attr "mode" "XF")])
17516 (define_insn "*cosxf2_i387"
17517 [(set (match_operand:XF 0 "register_operand" "=f")
17518 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17519 "TARGET_USE_FANCY_MATH_387
17520 && flag_unsafe_math_optimizations"
17522 [(set_attr "type" "fpspc")
17523 (set_attr "mode" "XF")])
17525 (define_insn "*cos_extend<mode>xf2_i387"
17526 [(set (match_operand:XF 0 "register_operand" "=f")
17527 (unspec:XF [(float_extend:XF
17528 (match_operand:MODEF 1 "register_operand" "0"))]
17530 "TARGET_USE_FANCY_MATH_387
17531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17532 || TARGET_MIX_SSE_I387)
17533 && flag_unsafe_math_optimizations"
17535 [(set_attr "type" "fpspc")
17536 (set_attr "mode" "XF")])
17538 ;; When sincos pattern is defined, sin and cos builtin functions will be
17539 ;; expanded to sincos pattern with one of its outputs left unused.
17540 ;; CSE pass will figure out if two sincos patterns can be combined,
17541 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17542 ;; depending on the unused output.
17544 (define_insn "sincosxf3"
17545 [(set (match_operand:XF 0 "register_operand" "=f")
17546 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17547 UNSPEC_SINCOS_COS))
17548 (set (match_operand:XF 1 "register_operand" "=u")
17549 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17550 "TARGET_USE_FANCY_MATH_387
17551 && flag_unsafe_math_optimizations"
17553 [(set_attr "type" "fpspc")
17554 (set_attr "mode" "XF")])
17557 [(set (match_operand:XF 0 "register_operand" "")
17558 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17559 UNSPEC_SINCOS_COS))
17560 (set (match_operand:XF 1 "register_operand" "")
17561 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17562 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17563 && !(reload_completed || reload_in_progress)"
17564 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17568 [(set (match_operand:XF 0 "register_operand" "")
17569 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17570 UNSPEC_SINCOS_COS))
17571 (set (match_operand:XF 1 "register_operand" "")
17572 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17573 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17574 && !(reload_completed || reload_in_progress)"
17575 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17578 (define_insn "sincos_extend<mode>xf3_i387"
17579 [(set (match_operand:XF 0 "register_operand" "=f")
17580 (unspec:XF [(float_extend:XF
17581 (match_operand:MODEF 2 "register_operand" "0"))]
17582 UNSPEC_SINCOS_COS))
17583 (set (match_operand:XF 1 "register_operand" "=u")
17584 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17585 "TARGET_USE_FANCY_MATH_387
17586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17587 || TARGET_MIX_SSE_I387)
17588 && flag_unsafe_math_optimizations"
17590 [(set_attr "type" "fpspc")
17591 (set_attr "mode" "XF")])
17594 [(set (match_operand:XF 0 "register_operand" "")
17595 (unspec:XF [(float_extend:XF
17596 (match_operand:MODEF 2 "register_operand" ""))]
17597 UNSPEC_SINCOS_COS))
17598 (set (match_operand:XF 1 "register_operand" "")
17599 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17600 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17601 && !(reload_completed || reload_in_progress)"
17602 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17606 [(set (match_operand:XF 0 "register_operand" "")
17607 (unspec:XF [(float_extend:XF
17608 (match_operand:MODEF 2 "register_operand" ""))]
17609 UNSPEC_SINCOS_COS))
17610 (set (match_operand:XF 1 "register_operand" "")
17611 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17612 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17613 && !(reload_completed || reload_in_progress)"
17614 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17617 (define_expand "sincos<mode>3"
17618 [(use (match_operand:MODEF 0 "register_operand" ""))
17619 (use (match_operand:MODEF 1 "register_operand" ""))
17620 (use (match_operand:MODEF 2 "register_operand" ""))]
17621 "TARGET_USE_FANCY_MATH_387
17622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17623 || TARGET_MIX_SSE_I387)
17624 && flag_unsafe_math_optimizations"
17626 rtx op0 = gen_reg_rtx (XFmode);
17627 rtx op1 = gen_reg_rtx (XFmode);
17629 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17630 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17635 (define_insn "fptanxf4_i387"
17636 [(set (match_operand:XF 0 "register_operand" "=f")
17637 (match_operand:XF 3 "const_double_operand" "F"))
17638 (set (match_operand:XF 1 "register_operand" "=u")
17639 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17641 "TARGET_USE_FANCY_MATH_387
17642 && flag_unsafe_math_optimizations
17643 && standard_80387_constant_p (operands[3]) == 2"
17645 [(set_attr "type" "fpspc")
17646 (set_attr "mode" "XF")])
17648 (define_insn "fptan_extend<mode>xf4_i387"
17649 [(set (match_operand:MODEF 0 "register_operand" "=f")
17650 (match_operand:MODEF 3 "const_double_operand" "F"))
17651 (set (match_operand:XF 1 "register_operand" "=u")
17652 (unspec:XF [(float_extend:XF
17653 (match_operand:MODEF 2 "register_operand" "0"))]
17655 "TARGET_USE_FANCY_MATH_387
17656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17657 || TARGET_MIX_SSE_I387)
17658 && flag_unsafe_math_optimizations
17659 && standard_80387_constant_p (operands[3]) == 2"
17661 [(set_attr "type" "fpspc")
17662 (set_attr "mode" "XF")])
17664 (define_expand "tanxf2"
17665 [(use (match_operand:XF 0 "register_operand" ""))
17666 (use (match_operand:XF 1 "register_operand" ""))]
17667 "TARGET_USE_FANCY_MATH_387
17668 && flag_unsafe_math_optimizations"
17670 rtx one = gen_reg_rtx (XFmode);
17671 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17673 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17677 (define_expand "tan<mode>2"
17678 [(use (match_operand:MODEF 0 "register_operand" ""))
17679 (use (match_operand:MODEF 1 "register_operand" ""))]
17680 "TARGET_USE_FANCY_MATH_387
17681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17682 || TARGET_MIX_SSE_I387)
17683 && flag_unsafe_math_optimizations"
17685 rtx op0 = gen_reg_rtx (XFmode);
17687 rtx one = gen_reg_rtx (<MODE>mode);
17688 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17690 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17691 operands[1], op2));
17692 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17696 (define_insn "*fpatanxf3_i387"
17697 [(set (match_operand:XF 0 "register_operand" "=f")
17698 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17699 (match_operand:XF 2 "register_operand" "u")]
17701 (clobber (match_scratch:XF 3 "=2"))]
17702 "TARGET_USE_FANCY_MATH_387
17703 && flag_unsafe_math_optimizations"
17705 [(set_attr "type" "fpspc")
17706 (set_attr "mode" "XF")])
17708 (define_insn "fpatan_extend<mode>xf3_i387"
17709 [(set (match_operand:XF 0 "register_operand" "=f")
17710 (unspec:XF [(float_extend:XF
17711 (match_operand:MODEF 1 "register_operand" "0"))
17713 (match_operand:MODEF 2 "register_operand" "u"))]
17715 (clobber (match_scratch:XF 3 "=2"))]
17716 "TARGET_USE_FANCY_MATH_387
17717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17718 || TARGET_MIX_SSE_I387)
17719 && flag_unsafe_math_optimizations"
17721 [(set_attr "type" "fpspc")
17722 (set_attr "mode" "XF")])
17724 (define_expand "atan2xf3"
17725 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17726 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17727 (match_operand:XF 1 "register_operand" "")]
17729 (clobber (match_scratch:XF 3 ""))])]
17730 "TARGET_USE_FANCY_MATH_387
17731 && flag_unsafe_math_optimizations"
17734 (define_expand "atan2<mode>3"
17735 [(use (match_operand:MODEF 0 "register_operand" ""))
17736 (use (match_operand:MODEF 1 "register_operand" ""))
17737 (use (match_operand:MODEF 2 "register_operand" ""))]
17738 "TARGET_USE_FANCY_MATH_387
17739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17740 || TARGET_MIX_SSE_I387)
17741 && flag_unsafe_math_optimizations"
17743 rtx op0 = gen_reg_rtx (XFmode);
17745 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17750 (define_expand "atanxf2"
17751 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17752 (unspec:XF [(match_dup 2)
17753 (match_operand:XF 1 "register_operand" "")]
17755 (clobber (match_scratch:XF 3 ""))])]
17756 "TARGET_USE_FANCY_MATH_387
17757 && flag_unsafe_math_optimizations"
17759 operands[2] = gen_reg_rtx (XFmode);
17760 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17763 (define_expand "atan<mode>2"
17764 [(use (match_operand:MODEF 0 "register_operand" ""))
17765 (use (match_operand:MODEF 1 "register_operand" ""))]
17766 "TARGET_USE_FANCY_MATH_387
17767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17768 || TARGET_MIX_SSE_I387)
17769 && flag_unsafe_math_optimizations"
17771 rtx op0 = gen_reg_rtx (XFmode);
17773 rtx op2 = gen_reg_rtx (<MODE>mode);
17774 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17776 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17777 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17781 (define_expand "asinxf2"
17782 [(set (match_dup 2)
17783 (mult:XF (match_operand:XF 1 "register_operand" "")
17785 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17786 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17787 (parallel [(set (match_operand:XF 0 "register_operand" "")
17788 (unspec:XF [(match_dup 5) (match_dup 1)]
17790 (clobber (match_scratch:XF 6 ""))])]
17791 "TARGET_USE_FANCY_MATH_387
17792 && flag_unsafe_math_optimizations"
17796 if (optimize_insn_for_size_p ())
17799 for (i = 2; i < 6; i++)
17800 operands[i] = gen_reg_rtx (XFmode);
17802 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17805 (define_expand "asin<mode>2"
17806 [(use (match_operand:MODEF 0 "register_operand" ""))
17807 (use (match_operand:MODEF 1 "general_operand" ""))]
17808 "TARGET_USE_FANCY_MATH_387
17809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17810 || TARGET_MIX_SSE_I387)
17811 && flag_unsafe_math_optimizations"
17813 rtx op0 = gen_reg_rtx (XFmode);
17814 rtx op1 = gen_reg_rtx (XFmode);
17816 if (optimize_insn_for_size_p ())
17819 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17820 emit_insn (gen_asinxf2 (op0, op1));
17821 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17825 (define_expand "acosxf2"
17826 [(set (match_dup 2)
17827 (mult:XF (match_operand:XF 1 "register_operand" "")
17829 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17830 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17831 (parallel [(set (match_operand:XF 0 "register_operand" "")
17832 (unspec:XF [(match_dup 1) (match_dup 5)]
17834 (clobber (match_scratch:XF 6 ""))])]
17835 "TARGET_USE_FANCY_MATH_387
17836 && flag_unsafe_math_optimizations"
17840 if (optimize_insn_for_size_p ())
17843 for (i = 2; i < 6; i++)
17844 operands[i] = gen_reg_rtx (XFmode);
17846 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17849 (define_expand "acos<mode>2"
17850 [(use (match_operand:MODEF 0 "register_operand" ""))
17851 (use (match_operand:MODEF 1 "general_operand" ""))]
17852 "TARGET_USE_FANCY_MATH_387
17853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17854 || TARGET_MIX_SSE_I387)
17855 && flag_unsafe_math_optimizations"
17857 rtx op0 = gen_reg_rtx (XFmode);
17858 rtx op1 = gen_reg_rtx (XFmode);
17860 if (optimize_insn_for_size_p ())
17863 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17864 emit_insn (gen_acosxf2 (op0, op1));
17865 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17869 (define_insn "fyl2xxf3_i387"
17870 [(set (match_operand:XF 0 "register_operand" "=f")
17871 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17872 (match_operand:XF 2 "register_operand" "u")]
17874 (clobber (match_scratch:XF 3 "=2"))]
17875 "TARGET_USE_FANCY_MATH_387
17876 && flag_unsafe_math_optimizations"
17878 [(set_attr "type" "fpspc")
17879 (set_attr "mode" "XF")])
17881 (define_insn "fyl2x_extend<mode>xf3_i387"
17882 [(set (match_operand:XF 0 "register_operand" "=f")
17883 (unspec:XF [(float_extend:XF
17884 (match_operand:MODEF 1 "register_operand" "0"))
17885 (match_operand:XF 2 "register_operand" "u")]
17887 (clobber (match_scratch:XF 3 "=2"))]
17888 "TARGET_USE_FANCY_MATH_387
17889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17890 || TARGET_MIX_SSE_I387)
17891 && flag_unsafe_math_optimizations"
17893 [(set_attr "type" "fpspc")
17894 (set_attr "mode" "XF")])
17896 (define_expand "logxf2"
17897 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17898 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17899 (match_dup 2)] UNSPEC_FYL2X))
17900 (clobber (match_scratch:XF 3 ""))])]
17901 "TARGET_USE_FANCY_MATH_387
17902 && flag_unsafe_math_optimizations"
17904 operands[2] = gen_reg_rtx (XFmode);
17905 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17908 (define_expand "log<mode>2"
17909 [(use (match_operand:MODEF 0 "register_operand" ""))
17910 (use (match_operand:MODEF 1 "register_operand" ""))]
17911 "TARGET_USE_FANCY_MATH_387
17912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17913 || TARGET_MIX_SSE_I387)
17914 && flag_unsafe_math_optimizations"
17916 rtx op0 = gen_reg_rtx (XFmode);
17918 rtx op2 = gen_reg_rtx (XFmode);
17919 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17921 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17926 (define_expand "log10xf2"
17927 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17928 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17929 (match_dup 2)] UNSPEC_FYL2X))
17930 (clobber (match_scratch:XF 3 ""))])]
17931 "TARGET_USE_FANCY_MATH_387
17932 && flag_unsafe_math_optimizations"
17934 operands[2] = gen_reg_rtx (XFmode);
17935 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17938 (define_expand "log10<mode>2"
17939 [(use (match_operand:MODEF 0 "register_operand" ""))
17940 (use (match_operand:MODEF 1 "register_operand" ""))]
17941 "TARGET_USE_FANCY_MATH_387
17942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17943 || TARGET_MIX_SSE_I387)
17944 && flag_unsafe_math_optimizations"
17946 rtx op0 = gen_reg_rtx (XFmode);
17948 rtx op2 = gen_reg_rtx (XFmode);
17949 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17951 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17956 (define_expand "log2xf2"
17957 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17958 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17959 (match_dup 2)] UNSPEC_FYL2X))
17960 (clobber (match_scratch:XF 3 ""))])]
17961 "TARGET_USE_FANCY_MATH_387
17962 && flag_unsafe_math_optimizations"
17964 operands[2] = gen_reg_rtx (XFmode);
17965 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17968 (define_expand "log2<mode>2"
17969 [(use (match_operand:MODEF 0 "register_operand" ""))
17970 (use (match_operand:MODEF 1 "register_operand" ""))]
17971 "TARGET_USE_FANCY_MATH_387
17972 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17973 || TARGET_MIX_SSE_I387)
17974 && flag_unsafe_math_optimizations"
17976 rtx op0 = gen_reg_rtx (XFmode);
17978 rtx op2 = gen_reg_rtx (XFmode);
17979 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17981 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17982 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17986 (define_insn "fyl2xp1xf3_i387"
17987 [(set (match_operand:XF 0 "register_operand" "=f")
17988 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17989 (match_operand:XF 2 "register_operand" "u")]
17991 (clobber (match_scratch:XF 3 "=2"))]
17992 "TARGET_USE_FANCY_MATH_387
17993 && flag_unsafe_math_optimizations"
17995 [(set_attr "type" "fpspc")
17996 (set_attr "mode" "XF")])
17998 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17999 [(set (match_operand:XF 0 "register_operand" "=f")
18000 (unspec:XF [(float_extend:XF
18001 (match_operand:MODEF 1 "register_operand" "0"))
18002 (match_operand:XF 2 "register_operand" "u")]
18004 (clobber (match_scratch:XF 3 "=2"))]
18005 "TARGET_USE_FANCY_MATH_387
18006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18007 || TARGET_MIX_SSE_I387)
18008 && flag_unsafe_math_optimizations"
18010 [(set_attr "type" "fpspc")
18011 (set_attr "mode" "XF")])
18013 (define_expand "log1pxf2"
18014 [(use (match_operand:XF 0 "register_operand" ""))
18015 (use (match_operand:XF 1 "register_operand" ""))]
18016 "TARGET_USE_FANCY_MATH_387
18017 && flag_unsafe_math_optimizations"
18019 if (optimize_insn_for_size_p ())
18022 ix86_emit_i387_log1p (operands[0], operands[1]);
18026 (define_expand "log1p<mode>2"
18027 [(use (match_operand:MODEF 0 "register_operand" ""))
18028 (use (match_operand:MODEF 1 "register_operand" ""))]
18029 "TARGET_USE_FANCY_MATH_387
18030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18031 || TARGET_MIX_SSE_I387)
18032 && flag_unsafe_math_optimizations"
18036 if (optimize_insn_for_size_p ())
18039 op0 = gen_reg_rtx (XFmode);
18041 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18043 ix86_emit_i387_log1p (op0, operands[1]);
18044 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18048 (define_insn "fxtractxf3_i387"
18049 [(set (match_operand:XF 0 "register_operand" "=f")
18050 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18051 UNSPEC_XTRACT_FRACT))
18052 (set (match_operand:XF 1 "register_operand" "=u")
18053 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18054 "TARGET_USE_FANCY_MATH_387
18055 && flag_unsafe_math_optimizations"
18057 [(set_attr "type" "fpspc")
18058 (set_attr "mode" "XF")])
18060 (define_insn "fxtract_extend<mode>xf3_i387"
18061 [(set (match_operand:XF 0 "register_operand" "=f")
18062 (unspec:XF [(float_extend:XF
18063 (match_operand:MODEF 2 "register_operand" "0"))]
18064 UNSPEC_XTRACT_FRACT))
18065 (set (match_operand:XF 1 "register_operand" "=u")
18066 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18067 "TARGET_USE_FANCY_MATH_387
18068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18069 || TARGET_MIX_SSE_I387)
18070 && flag_unsafe_math_optimizations"
18072 [(set_attr "type" "fpspc")
18073 (set_attr "mode" "XF")])
18075 (define_expand "logbxf2"
18076 [(parallel [(set (match_dup 2)
18077 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18078 UNSPEC_XTRACT_FRACT))
18079 (set (match_operand:XF 0 "register_operand" "")
18080 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18081 "TARGET_USE_FANCY_MATH_387
18082 && flag_unsafe_math_optimizations"
18084 operands[2] = gen_reg_rtx (XFmode);
18087 (define_expand "logb<mode>2"
18088 [(use (match_operand:MODEF 0 "register_operand" ""))
18089 (use (match_operand:MODEF 1 "register_operand" ""))]
18090 "TARGET_USE_FANCY_MATH_387
18091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18092 || TARGET_MIX_SSE_I387)
18093 && flag_unsafe_math_optimizations"
18095 rtx op0 = gen_reg_rtx (XFmode);
18096 rtx op1 = gen_reg_rtx (XFmode);
18098 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18103 (define_expand "ilogbxf2"
18104 [(use (match_operand:SI 0 "register_operand" ""))
18105 (use (match_operand:XF 1 "register_operand" ""))]
18106 "TARGET_USE_FANCY_MATH_387
18107 && flag_unsafe_math_optimizations"
18111 if (optimize_insn_for_size_p ())
18114 op0 = gen_reg_rtx (XFmode);
18115 op1 = gen_reg_rtx (XFmode);
18117 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18118 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18122 (define_expand "ilogb<mode>2"
18123 [(use (match_operand:SI 0 "register_operand" ""))
18124 (use (match_operand:MODEF 1 "register_operand" ""))]
18125 "TARGET_USE_FANCY_MATH_387
18126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18127 || TARGET_MIX_SSE_I387)
18128 && flag_unsafe_math_optimizations"
18132 if (optimize_insn_for_size_p ())
18135 op0 = gen_reg_rtx (XFmode);
18136 op1 = gen_reg_rtx (XFmode);
18138 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18139 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18143 (define_insn "*f2xm1xf2_i387"
18144 [(set (match_operand:XF 0 "register_operand" "=f")
18145 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18147 "TARGET_USE_FANCY_MATH_387
18148 && flag_unsafe_math_optimizations"
18150 [(set_attr "type" "fpspc")
18151 (set_attr "mode" "XF")])
18153 (define_insn "*fscalexf4_i387"
18154 [(set (match_operand:XF 0 "register_operand" "=f")
18155 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18156 (match_operand:XF 3 "register_operand" "1")]
18157 UNSPEC_FSCALE_FRACT))
18158 (set (match_operand:XF 1 "register_operand" "=u")
18159 (unspec:XF [(match_dup 2) (match_dup 3)]
18160 UNSPEC_FSCALE_EXP))]
18161 "TARGET_USE_FANCY_MATH_387
18162 && flag_unsafe_math_optimizations"
18164 [(set_attr "type" "fpspc")
18165 (set_attr "mode" "XF")])
18167 (define_expand "expNcorexf3"
18168 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18169 (match_operand:XF 2 "register_operand" "")))
18170 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18171 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18172 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18173 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18174 (parallel [(set (match_operand:XF 0 "register_operand" "")
18175 (unspec:XF [(match_dup 8) (match_dup 4)]
18176 UNSPEC_FSCALE_FRACT))
18178 (unspec:XF [(match_dup 8) (match_dup 4)]
18179 UNSPEC_FSCALE_EXP))])]
18180 "TARGET_USE_FANCY_MATH_387
18181 && flag_unsafe_math_optimizations"
18185 if (optimize_insn_for_size_p ())
18188 for (i = 3; i < 10; i++)
18189 operands[i] = gen_reg_rtx (XFmode);
18191 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
18194 (define_expand "expxf2"
18195 [(use (match_operand:XF 0 "register_operand" ""))
18196 (use (match_operand:XF 1 "register_operand" ""))]
18197 "TARGET_USE_FANCY_MATH_387
18198 && flag_unsafe_math_optimizations"
18202 if (optimize_insn_for_size_p ())
18205 op2 = gen_reg_rtx (XFmode);
18206 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18208 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18212 (define_expand "exp<mode>2"
18213 [(use (match_operand:MODEF 0 "register_operand" ""))
18214 (use (match_operand:MODEF 1 "general_operand" ""))]
18215 "TARGET_USE_FANCY_MATH_387
18216 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18217 || TARGET_MIX_SSE_I387)
18218 && flag_unsafe_math_optimizations"
18222 if (optimize_insn_for_size_p ())
18225 op0 = gen_reg_rtx (XFmode);
18226 op1 = gen_reg_rtx (XFmode);
18228 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18229 emit_insn (gen_expxf2 (op0, op1));
18230 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18234 (define_expand "exp10xf2"
18235 [(use (match_operand:XF 0 "register_operand" ""))
18236 (use (match_operand:XF 1 "register_operand" ""))]
18237 "TARGET_USE_FANCY_MATH_387
18238 && flag_unsafe_math_optimizations"
18242 if (optimize_insn_for_size_p ())
18245 op2 = gen_reg_rtx (XFmode);
18246 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18248 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18252 (define_expand "exp10<mode>2"
18253 [(use (match_operand:MODEF 0 "register_operand" ""))
18254 (use (match_operand:MODEF 1 "general_operand" ""))]
18255 "TARGET_USE_FANCY_MATH_387
18256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18257 || TARGET_MIX_SSE_I387)
18258 && flag_unsafe_math_optimizations"
18262 if (optimize_insn_for_size_p ())
18265 op0 = gen_reg_rtx (XFmode);
18266 op1 = gen_reg_rtx (XFmode);
18268 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18269 emit_insn (gen_exp10xf2 (op0, op1));
18270 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18274 (define_expand "exp2xf2"
18275 [(use (match_operand:XF 0 "register_operand" ""))
18276 (use (match_operand:XF 1 "register_operand" ""))]
18277 "TARGET_USE_FANCY_MATH_387
18278 && flag_unsafe_math_optimizations"
18282 if (optimize_insn_for_size_p ())
18285 op2 = gen_reg_rtx (XFmode);
18286 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
18288 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18292 (define_expand "exp2<mode>2"
18293 [(use (match_operand:MODEF 0 "register_operand" ""))
18294 (use (match_operand:MODEF 1 "general_operand" ""))]
18295 "TARGET_USE_FANCY_MATH_387
18296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18297 || TARGET_MIX_SSE_I387)
18298 && flag_unsafe_math_optimizations"
18302 if (optimize_insn_for_size_p ())
18305 op0 = gen_reg_rtx (XFmode);
18306 op1 = gen_reg_rtx (XFmode);
18308 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18309 emit_insn (gen_exp2xf2 (op0, op1));
18310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18314 (define_expand "expm1xf2"
18315 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18317 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18318 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18319 (set (match_dup 9) (float_extend:XF (match_dup 13)))
18320 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18321 (parallel [(set (match_dup 7)
18322 (unspec:XF [(match_dup 6) (match_dup 4)]
18323 UNSPEC_FSCALE_FRACT))
18325 (unspec:XF [(match_dup 6) (match_dup 4)]
18326 UNSPEC_FSCALE_EXP))])
18327 (parallel [(set (match_dup 10)
18328 (unspec:XF [(match_dup 9) (match_dup 8)]
18329 UNSPEC_FSCALE_FRACT))
18330 (set (match_dup 11)
18331 (unspec:XF [(match_dup 9) (match_dup 8)]
18332 UNSPEC_FSCALE_EXP))])
18333 (set (match_dup 12) (minus:XF (match_dup 10)
18334 (float_extend:XF (match_dup 13))))
18335 (set (match_operand:XF 0 "register_operand" "")
18336 (plus:XF (match_dup 12) (match_dup 7)))]
18337 "TARGET_USE_FANCY_MATH_387
18338 && flag_unsafe_math_optimizations"
18342 if (optimize_insn_for_size_p ())
18345 for (i = 2; i < 13; i++)
18346 operands[i] = gen_reg_rtx (XFmode);
18349 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18351 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18354 (define_expand "expm1<mode>2"
18355 [(use (match_operand:MODEF 0 "register_operand" ""))
18356 (use (match_operand:MODEF 1 "general_operand" ""))]
18357 "TARGET_USE_FANCY_MATH_387
18358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18359 || TARGET_MIX_SSE_I387)
18360 && flag_unsafe_math_optimizations"
18364 if (optimize_insn_for_size_p ())
18367 op0 = gen_reg_rtx (XFmode);
18368 op1 = gen_reg_rtx (XFmode);
18370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18371 emit_insn (gen_expm1xf2 (op0, op1));
18372 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18376 (define_expand "ldexpxf3"
18377 [(set (match_dup 3)
18378 (float:XF (match_operand:SI 2 "register_operand" "")))
18379 (parallel [(set (match_operand:XF 0 " register_operand" "")
18380 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18382 UNSPEC_FSCALE_FRACT))
18384 (unspec:XF [(match_dup 1) (match_dup 3)]
18385 UNSPEC_FSCALE_EXP))])]
18386 "TARGET_USE_FANCY_MATH_387
18387 && flag_unsafe_math_optimizations"
18389 if (optimize_insn_for_size_p ())
18392 operands[3] = gen_reg_rtx (XFmode);
18393 operands[4] = gen_reg_rtx (XFmode);
18396 (define_expand "ldexp<mode>3"
18397 [(use (match_operand:MODEF 0 "register_operand" ""))
18398 (use (match_operand:MODEF 1 "general_operand" ""))
18399 (use (match_operand:SI 2 "register_operand" ""))]
18400 "TARGET_USE_FANCY_MATH_387
18401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18402 || TARGET_MIX_SSE_I387)
18403 && flag_unsafe_math_optimizations"
18407 if (optimize_insn_for_size_p ())
18410 op0 = gen_reg_rtx (XFmode);
18411 op1 = gen_reg_rtx (XFmode);
18413 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18414 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18415 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18419 (define_expand "scalbxf3"
18420 [(parallel [(set (match_operand:XF 0 " register_operand" "")
18421 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18422 (match_operand:XF 2 "register_operand" "")]
18423 UNSPEC_FSCALE_FRACT))
18425 (unspec:XF [(match_dup 1) (match_dup 2)]
18426 UNSPEC_FSCALE_EXP))])]
18427 "TARGET_USE_FANCY_MATH_387
18428 && flag_unsafe_math_optimizations"
18430 if (optimize_insn_for_size_p ())
18433 operands[3] = gen_reg_rtx (XFmode);
18436 (define_expand "scalb<mode>3"
18437 [(use (match_operand:MODEF 0 "register_operand" ""))
18438 (use (match_operand:MODEF 1 "general_operand" ""))
18439 (use (match_operand:MODEF 2 "general_operand" ""))]
18440 "TARGET_USE_FANCY_MATH_387
18441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18442 || TARGET_MIX_SSE_I387)
18443 && flag_unsafe_math_optimizations"
18447 if (optimize_insn_for_size_p ())
18450 op0 = gen_reg_rtx (XFmode);
18451 op1 = gen_reg_rtx (XFmode);
18452 op2 = gen_reg_rtx (XFmode);
18454 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18455 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18456 emit_insn (gen_scalbxf3 (op0, op1, op2));
18457 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18461 (define_expand "significandxf2"
18462 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18463 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18464 UNSPEC_XTRACT_FRACT))
18466 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18467 "TARGET_USE_FANCY_MATH_387
18468 && flag_unsafe_math_optimizations"
18470 operands[2] = gen_reg_rtx (XFmode);
18473 (define_expand "significand<mode>2"
18474 [(use (match_operand:MODEF 0 "register_operand" ""))
18475 (use (match_operand:MODEF 1 "register_operand" ""))]
18476 "TARGET_USE_FANCY_MATH_387
18477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18478 || TARGET_MIX_SSE_I387)
18479 && flag_unsafe_math_optimizations"
18481 rtx op0 = gen_reg_rtx (XFmode);
18482 rtx op1 = gen_reg_rtx (XFmode);
18484 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18485 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18490 (define_insn "sse4_1_round<mode>2"
18491 [(set (match_operand:MODEF 0 "register_operand" "=x")
18492 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18493 (match_operand:SI 2 "const_0_to_15_operand" "n")]
18496 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18497 [(set_attr "type" "ssecvt")
18498 (set_attr "prefix_extra" "1")
18499 (set_attr "prefix" "maybe_vex")
18500 (set_attr "mode" "<MODE>")])
18502 (define_insn "rintxf2"
18503 [(set (match_operand:XF 0 "register_operand" "=f")
18504 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18506 "TARGET_USE_FANCY_MATH_387
18507 && flag_unsafe_math_optimizations"
18509 [(set_attr "type" "fpspc")
18510 (set_attr "mode" "XF")])
18512 (define_expand "rint<mode>2"
18513 [(use (match_operand:MODEF 0 "register_operand" ""))
18514 (use (match_operand:MODEF 1 "register_operand" ""))]
18515 "(TARGET_USE_FANCY_MATH_387
18516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18517 || TARGET_MIX_SSE_I387)
18518 && flag_unsafe_math_optimizations)
18519 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18520 && !flag_trapping_math)"
18522 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18523 && !flag_trapping_math)
18525 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18528 emit_insn (gen_sse4_1_round<mode>2
18529 (operands[0], operands[1], GEN_INT (0x04)));
18531 ix86_expand_rint (operand0, operand1);
18535 rtx op0 = gen_reg_rtx (XFmode);
18536 rtx op1 = gen_reg_rtx (XFmode);
18538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18539 emit_insn (gen_rintxf2 (op0, op1));
18541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18546 (define_expand "round<mode>2"
18547 [(match_operand:MODEF 0 "register_operand" "")
18548 (match_operand:MODEF 1 "nonimmediate_operand" "")]
18549 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18550 && !flag_trapping_math && !flag_rounding_math"
18552 if (optimize_insn_for_size_p ())
18554 if (TARGET_64BIT || (<MODE>mode != DFmode))
18555 ix86_expand_round (operand0, operand1);
18557 ix86_expand_rounddf_32 (operand0, operand1);
18561 (define_insn_and_split "*fistdi2_1"
18562 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18563 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18565 "TARGET_USE_FANCY_MATH_387
18566 && !(reload_completed || reload_in_progress)"
18571 if (memory_operand (operands[0], VOIDmode))
18572 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18575 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18576 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18581 [(set_attr "type" "fpspc")
18582 (set_attr "mode" "DI")])
18584 (define_insn "fistdi2"
18585 [(set (match_operand:DI 0 "memory_operand" "=m")
18586 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18588 (clobber (match_scratch:XF 2 "=&1f"))]
18589 "TARGET_USE_FANCY_MATH_387"
18590 "* return output_fix_trunc (insn, operands, 0);"
18591 [(set_attr "type" "fpspc")
18592 (set_attr "mode" "DI")])
18594 (define_insn "fistdi2_with_temp"
18595 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18596 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18598 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18599 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18600 "TARGET_USE_FANCY_MATH_387"
18602 [(set_attr "type" "fpspc")
18603 (set_attr "mode" "DI")])
18606 [(set (match_operand:DI 0 "register_operand" "")
18607 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18609 (clobber (match_operand:DI 2 "memory_operand" ""))
18610 (clobber (match_scratch 3 ""))]
18612 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18613 (clobber (match_dup 3))])
18614 (set (match_dup 0) (match_dup 2))]
18618 [(set (match_operand:DI 0 "memory_operand" "")
18619 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18621 (clobber (match_operand:DI 2 "memory_operand" ""))
18622 (clobber (match_scratch 3 ""))]
18624 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18625 (clobber (match_dup 3))])]
18628 (define_insn_and_split "*fist<mode>2_1"
18629 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18630 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18632 "TARGET_USE_FANCY_MATH_387
18633 && !(reload_completed || reload_in_progress)"
18638 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18639 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18643 [(set_attr "type" "fpspc")
18644 (set_attr "mode" "<MODE>")])
18646 (define_insn "fist<mode>2"
18647 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18648 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18650 "TARGET_USE_FANCY_MATH_387"
18651 "* return output_fix_trunc (insn, operands, 0);"
18652 [(set_attr "type" "fpspc")
18653 (set_attr "mode" "<MODE>")])
18655 (define_insn "fist<mode>2_with_temp"
18656 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18657 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18659 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18660 "TARGET_USE_FANCY_MATH_387"
18662 [(set_attr "type" "fpspc")
18663 (set_attr "mode" "<MODE>")])
18666 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18667 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18669 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18671 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18672 (set (match_dup 0) (match_dup 2))]
18676 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18677 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18679 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18681 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18684 (define_expand "lrintxf<mode>2"
18685 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18686 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18688 "TARGET_USE_FANCY_MATH_387"
18691 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18692 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18693 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18694 UNSPEC_FIX_NOTRUNC))]
18695 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18696 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18699 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18700 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18701 (match_operand:MODEF 1 "register_operand" "")]
18702 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18703 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18704 && !flag_trapping_math && !flag_rounding_math"
18706 if (optimize_insn_for_size_p ())
18708 ix86_expand_lround (operand0, operand1);
18712 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18713 (define_insn_and_split "frndintxf2_floor"
18714 [(set (match_operand:XF 0 "register_operand" "")
18715 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18716 UNSPEC_FRNDINT_FLOOR))
18717 (clobber (reg:CC FLAGS_REG))]
18718 "TARGET_USE_FANCY_MATH_387
18719 && flag_unsafe_math_optimizations
18720 && !(reload_completed || reload_in_progress)"
18725 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18727 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18728 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18730 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18731 operands[2], operands[3]));
18734 [(set_attr "type" "frndint")
18735 (set_attr "i387_cw" "floor")
18736 (set_attr "mode" "XF")])
18738 (define_insn "frndintxf2_floor_i387"
18739 [(set (match_operand:XF 0 "register_operand" "=f")
18740 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18741 UNSPEC_FRNDINT_FLOOR))
18742 (use (match_operand:HI 2 "memory_operand" "m"))
18743 (use (match_operand:HI 3 "memory_operand" "m"))]
18744 "TARGET_USE_FANCY_MATH_387
18745 && flag_unsafe_math_optimizations"
18746 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18747 [(set_attr "type" "frndint")
18748 (set_attr "i387_cw" "floor")
18749 (set_attr "mode" "XF")])
18751 (define_expand "floorxf2"
18752 [(use (match_operand:XF 0 "register_operand" ""))
18753 (use (match_operand:XF 1 "register_operand" ""))]
18754 "TARGET_USE_FANCY_MATH_387
18755 && flag_unsafe_math_optimizations"
18757 if (optimize_insn_for_size_p ())
18759 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18763 (define_expand "floor<mode>2"
18764 [(use (match_operand:MODEF 0 "register_operand" ""))
18765 (use (match_operand:MODEF 1 "register_operand" ""))]
18766 "(TARGET_USE_FANCY_MATH_387
18767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18768 || TARGET_MIX_SSE_I387)
18769 && flag_unsafe_math_optimizations)
18770 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18771 && !flag_trapping_math)"
18773 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18774 && !flag_trapping_math
18775 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18777 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18780 emit_insn (gen_sse4_1_round<mode>2
18781 (operands[0], operands[1], GEN_INT (0x01)));
18782 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18783 ix86_expand_floorceil (operand0, operand1, true);
18785 ix86_expand_floorceildf_32 (operand0, operand1, true);
18791 if (optimize_insn_for_size_p ())
18794 op0 = gen_reg_rtx (XFmode);
18795 op1 = gen_reg_rtx (XFmode);
18796 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18797 emit_insn (gen_frndintxf2_floor (op0, op1));
18799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18804 (define_insn_and_split "*fist<mode>2_floor_1"
18805 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18806 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18807 UNSPEC_FIST_FLOOR))
18808 (clobber (reg:CC FLAGS_REG))]
18809 "TARGET_USE_FANCY_MATH_387
18810 && flag_unsafe_math_optimizations
18811 && !(reload_completed || reload_in_progress)"
18816 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18818 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18819 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18820 if (memory_operand (operands[0], VOIDmode))
18821 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18822 operands[2], operands[3]));
18825 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18826 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18827 operands[2], operands[3],
18832 [(set_attr "type" "fistp")
18833 (set_attr "i387_cw" "floor")
18834 (set_attr "mode" "<MODE>")])
18836 (define_insn "fistdi2_floor"
18837 [(set (match_operand:DI 0 "memory_operand" "=m")
18838 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18839 UNSPEC_FIST_FLOOR))
18840 (use (match_operand:HI 2 "memory_operand" "m"))
18841 (use (match_operand:HI 3 "memory_operand" "m"))
18842 (clobber (match_scratch:XF 4 "=&1f"))]
18843 "TARGET_USE_FANCY_MATH_387
18844 && flag_unsafe_math_optimizations"
18845 "* return output_fix_trunc (insn, operands, 0);"
18846 [(set_attr "type" "fistp")
18847 (set_attr "i387_cw" "floor")
18848 (set_attr "mode" "DI")])
18850 (define_insn "fistdi2_floor_with_temp"
18851 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18852 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18853 UNSPEC_FIST_FLOOR))
18854 (use (match_operand:HI 2 "memory_operand" "m,m"))
18855 (use (match_operand:HI 3 "memory_operand" "m,m"))
18856 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18857 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18858 "TARGET_USE_FANCY_MATH_387
18859 && flag_unsafe_math_optimizations"
18861 [(set_attr "type" "fistp")
18862 (set_attr "i387_cw" "floor")
18863 (set_attr "mode" "DI")])
18866 [(set (match_operand:DI 0 "register_operand" "")
18867 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18868 UNSPEC_FIST_FLOOR))
18869 (use (match_operand:HI 2 "memory_operand" ""))
18870 (use (match_operand:HI 3 "memory_operand" ""))
18871 (clobber (match_operand:DI 4 "memory_operand" ""))
18872 (clobber (match_scratch 5 ""))]
18874 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18875 (use (match_dup 2))
18876 (use (match_dup 3))
18877 (clobber (match_dup 5))])
18878 (set (match_dup 0) (match_dup 4))]
18882 [(set (match_operand:DI 0 "memory_operand" "")
18883 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18884 UNSPEC_FIST_FLOOR))
18885 (use (match_operand:HI 2 "memory_operand" ""))
18886 (use (match_operand:HI 3 "memory_operand" ""))
18887 (clobber (match_operand:DI 4 "memory_operand" ""))
18888 (clobber (match_scratch 5 ""))]
18890 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18891 (use (match_dup 2))
18892 (use (match_dup 3))
18893 (clobber (match_dup 5))])]
18896 (define_insn "fist<mode>2_floor"
18897 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18898 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18899 UNSPEC_FIST_FLOOR))
18900 (use (match_operand:HI 2 "memory_operand" "m"))
18901 (use (match_operand:HI 3 "memory_operand" "m"))]
18902 "TARGET_USE_FANCY_MATH_387
18903 && flag_unsafe_math_optimizations"
18904 "* return output_fix_trunc (insn, operands, 0);"
18905 [(set_attr "type" "fistp")
18906 (set_attr "i387_cw" "floor")
18907 (set_attr "mode" "<MODE>")])
18909 (define_insn "fist<mode>2_floor_with_temp"
18910 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18911 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18912 UNSPEC_FIST_FLOOR))
18913 (use (match_operand:HI 2 "memory_operand" "m,m"))
18914 (use (match_operand:HI 3 "memory_operand" "m,m"))
18915 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18916 "TARGET_USE_FANCY_MATH_387
18917 && flag_unsafe_math_optimizations"
18919 [(set_attr "type" "fistp")
18920 (set_attr "i387_cw" "floor")
18921 (set_attr "mode" "<MODE>")])
18924 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18925 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18926 UNSPEC_FIST_FLOOR))
18927 (use (match_operand:HI 2 "memory_operand" ""))
18928 (use (match_operand:HI 3 "memory_operand" ""))
18929 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18931 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18932 UNSPEC_FIST_FLOOR))
18933 (use (match_dup 2))
18934 (use (match_dup 3))])
18935 (set (match_dup 0) (match_dup 4))]
18939 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18940 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18941 UNSPEC_FIST_FLOOR))
18942 (use (match_operand:HI 2 "memory_operand" ""))
18943 (use (match_operand:HI 3 "memory_operand" ""))
18944 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18946 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18947 UNSPEC_FIST_FLOOR))
18948 (use (match_dup 2))
18949 (use (match_dup 3))])]
18952 (define_expand "lfloorxf<mode>2"
18953 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18954 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18955 UNSPEC_FIST_FLOOR))
18956 (clobber (reg:CC FLAGS_REG))])]
18957 "TARGET_USE_FANCY_MATH_387
18958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18959 && flag_unsafe_math_optimizations"
18962 (define_expand "lfloor<mode>di2"
18963 [(match_operand:DI 0 "nonimmediate_operand" "")
18964 (match_operand:MODEF 1 "register_operand" "")]
18965 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18966 && !flag_trapping_math"
18968 if (optimize_insn_for_size_p ())
18970 ix86_expand_lfloorceil (operand0, operand1, true);
18974 (define_expand "lfloor<mode>si2"
18975 [(match_operand:SI 0 "nonimmediate_operand" "")
18976 (match_operand:MODEF 1 "register_operand" "")]
18977 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18978 && !flag_trapping_math"
18980 if (optimize_insn_for_size_p () && TARGET_64BIT)
18982 ix86_expand_lfloorceil (operand0, operand1, true);
18986 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18987 (define_insn_and_split "frndintxf2_ceil"
18988 [(set (match_operand:XF 0 "register_operand" "")
18989 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18990 UNSPEC_FRNDINT_CEIL))
18991 (clobber (reg:CC FLAGS_REG))]
18992 "TARGET_USE_FANCY_MATH_387
18993 && flag_unsafe_math_optimizations
18994 && !(reload_completed || reload_in_progress)"
18999 ix86_optimize_mode_switching[I387_CEIL] = 1;
19001 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19002 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19004 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
19005 operands[2], operands[3]));
19008 [(set_attr "type" "frndint")
19009 (set_attr "i387_cw" "ceil")
19010 (set_attr "mode" "XF")])
19012 (define_insn "frndintxf2_ceil_i387"
19013 [(set (match_operand:XF 0 "register_operand" "=f")
19014 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19015 UNSPEC_FRNDINT_CEIL))
19016 (use (match_operand:HI 2 "memory_operand" "m"))
19017 (use (match_operand:HI 3 "memory_operand" "m"))]
19018 "TARGET_USE_FANCY_MATH_387
19019 && flag_unsafe_math_optimizations"
19020 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19021 [(set_attr "type" "frndint")
19022 (set_attr "i387_cw" "ceil")
19023 (set_attr "mode" "XF")])
19025 (define_expand "ceilxf2"
19026 [(use (match_operand:XF 0 "register_operand" ""))
19027 (use (match_operand:XF 1 "register_operand" ""))]
19028 "TARGET_USE_FANCY_MATH_387
19029 && flag_unsafe_math_optimizations"
19031 if (optimize_insn_for_size_p ())
19033 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19037 (define_expand "ceil<mode>2"
19038 [(use (match_operand:MODEF 0 "register_operand" ""))
19039 (use (match_operand:MODEF 1 "register_operand" ""))]
19040 "(TARGET_USE_FANCY_MATH_387
19041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19042 || TARGET_MIX_SSE_I387)
19043 && flag_unsafe_math_optimizations)
19044 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19045 && !flag_trapping_math)"
19047 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19048 && !flag_trapping_math
19049 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19052 emit_insn (gen_sse4_1_round<mode>2
19053 (operands[0], operands[1], GEN_INT (0x02)));
19054 else if (optimize_insn_for_size_p ())
19056 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19057 ix86_expand_floorceil (operand0, operand1, false);
19059 ix86_expand_floorceildf_32 (operand0, operand1, false);
19065 if (optimize_insn_for_size_p ())
19068 op0 = gen_reg_rtx (XFmode);
19069 op1 = gen_reg_rtx (XFmode);
19070 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19071 emit_insn (gen_frndintxf2_ceil (op0, op1));
19073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19078 (define_insn_and_split "*fist<mode>2_ceil_1"
19079 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19080 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19082 (clobber (reg:CC FLAGS_REG))]
19083 "TARGET_USE_FANCY_MATH_387
19084 && flag_unsafe_math_optimizations
19085 && !(reload_completed || reload_in_progress)"
19090 ix86_optimize_mode_switching[I387_CEIL] = 1;
19092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19094 if (memory_operand (operands[0], VOIDmode))
19095 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19096 operands[2], operands[3]));
19099 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19100 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19101 operands[2], operands[3],
19106 [(set_attr "type" "fistp")
19107 (set_attr "i387_cw" "ceil")
19108 (set_attr "mode" "<MODE>")])
19110 (define_insn "fistdi2_ceil"
19111 [(set (match_operand:DI 0 "memory_operand" "=m")
19112 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19114 (use (match_operand:HI 2 "memory_operand" "m"))
19115 (use (match_operand:HI 3 "memory_operand" "m"))
19116 (clobber (match_scratch:XF 4 "=&1f"))]
19117 "TARGET_USE_FANCY_MATH_387
19118 && flag_unsafe_math_optimizations"
19119 "* return output_fix_trunc (insn, operands, 0);"
19120 [(set_attr "type" "fistp")
19121 (set_attr "i387_cw" "ceil")
19122 (set_attr "mode" "DI")])
19124 (define_insn "fistdi2_ceil_with_temp"
19125 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19126 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19128 (use (match_operand:HI 2 "memory_operand" "m,m"))
19129 (use (match_operand:HI 3 "memory_operand" "m,m"))
19130 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19131 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19132 "TARGET_USE_FANCY_MATH_387
19133 && flag_unsafe_math_optimizations"
19135 [(set_attr "type" "fistp")
19136 (set_attr "i387_cw" "ceil")
19137 (set_attr "mode" "DI")])
19140 [(set (match_operand:DI 0 "register_operand" "")
19141 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19143 (use (match_operand:HI 2 "memory_operand" ""))
19144 (use (match_operand:HI 3 "memory_operand" ""))
19145 (clobber (match_operand:DI 4 "memory_operand" ""))
19146 (clobber (match_scratch 5 ""))]
19148 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19149 (use (match_dup 2))
19150 (use (match_dup 3))
19151 (clobber (match_dup 5))])
19152 (set (match_dup 0) (match_dup 4))]
19156 [(set (match_operand:DI 0 "memory_operand" "")
19157 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19159 (use (match_operand:HI 2 "memory_operand" ""))
19160 (use (match_operand:HI 3 "memory_operand" ""))
19161 (clobber (match_operand:DI 4 "memory_operand" ""))
19162 (clobber (match_scratch 5 ""))]
19164 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19165 (use (match_dup 2))
19166 (use (match_dup 3))
19167 (clobber (match_dup 5))])]
19170 (define_insn "fist<mode>2_ceil"
19171 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19172 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19174 (use (match_operand:HI 2 "memory_operand" "m"))
19175 (use (match_operand:HI 3 "memory_operand" "m"))]
19176 "TARGET_USE_FANCY_MATH_387
19177 && flag_unsafe_math_optimizations"
19178 "* return output_fix_trunc (insn, operands, 0);"
19179 [(set_attr "type" "fistp")
19180 (set_attr "i387_cw" "ceil")
19181 (set_attr "mode" "<MODE>")])
19183 (define_insn "fist<mode>2_ceil_with_temp"
19184 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19185 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19187 (use (match_operand:HI 2 "memory_operand" "m,m"))
19188 (use (match_operand:HI 3 "memory_operand" "m,m"))
19189 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19190 "TARGET_USE_FANCY_MATH_387
19191 && flag_unsafe_math_optimizations"
19193 [(set_attr "type" "fistp")
19194 (set_attr "i387_cw" "ceil")
19195 (set_attr "mode" "<MODE>")])
19198 [(set (match_operand:X87MODEI12 0 "register_operand" "")
19199 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19201 (use (match_operand:HI 2 "memory_operand" ""))
19202 (use (match_operand:HI 3 "memory_operand" ""))
19203 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19205 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19207 (use (match_dup 2))
19208 (use (match_dup 3))])
19209 (set (match_dup 0) (match_dup 4))]
19213 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19214 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19216 (use (match_operand:HI 2 "memory_operand" ""))
19217 (use (match_operand:HI 3 "memory_operand" ""))
19218 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19220 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19222 (use (match_dup 2))
19223 (use (match_dup 3))])]
19226 (define_expand "lceilxf<mode>2"
19227 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19228 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19230 (clobber (reg:CC FLAGS_REG))])]
19231 "TARGET_USE_FANCY_MATH_387
19232 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19233 && flag_unsafe_math_optimizations"
19236 (define_expand "lceil<mode>di2"
19237 [(match_operand:DI 0 "nonimmediate_operand" "")
19238 (match_operand:MODEF 1 "register_operand" "")]
19239 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19240 && !flag_trapping_math"
19242 ix86_expand_lfloorceil (operand0, operand1, false);
19246 (define_expand "lceil<mode>si2"
19247 [(match_operand:SI 0 "nonimmediate_operand" "")
19248 (match_operand:MODEF 1 "register_operand" "")]
19249 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19250 && !flag_trapping_math"
19252 ix86_expand_lfloorceil (operand0, operand1, false);
19256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19257 (define_insn_and_split "frndintxf2_trunc"
19258 [(set (match_operand:XF 0 "register_operand" "")
19259 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19260 UNSPEC_FRNDINT_TRUNC))
19261 (clobber (reg:CC FLAGS_REG))]
19262 "TARGET_USE_FANCY_MATH_387
19263 && flag_unsafe_math_optimizations
19264 && !(reload_completed || reload_in_progress)"
19269 ix86_optimize_mode_switching[I387_TRUNC] = 1;
19271 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19272 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19274 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19275 operands[2], operands[3]));
19278 [(set_attr "type" "frndint")
19279 (set_attr "i387_cw" "trunc")
19280 (set_attr "mode" "XF")])
19282 (define_insn "frndintxf2_trunc_i387"
19283 [(set (match_operand:XF 0 "register_operand" "=f")
19284 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19285 UNSPEC_FRNDINT_TRUNC))
19286 (use (match_operand:HI 2 "memory_operand" "m"))
19287 (use (match_operand:HI 3 "memory_operand" "m"))]
19288 "TARGET_USE_FANCY_MATH_387
19289 && flag_unsafe_math_optimizations"
19290 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19291 [(set_attr "type" "frndint")
19292 (set_attr "i387_cw" "trunc")
19293 (set_attr "mode" "XF")])
19295 (define_expand "btruncxf2"
19296 [(use (match_operand:XF 0 "register_operand" ""))
19297 (use (match_operand:XF 1 "register_operand" ""))]
19298 "TARGET_USE_FANCY_MATH_387
19299 && flag_unsafe_math_optimizations"
19301 if (optimize_insn_for_size_p ())
19303 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19307 (define_expand "btrunc<mode>2"
19308 [(use (match_operand:MODEF 0 "register_operand" ""))
19309 (use (match_operand:MODEF 1 "register_operand" ""))]
19310 "(TARGET_USE_FANCY_MATH_387
19311 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19312 || TARGET_MIX_SSE_I387)
19313 && flag_unsafe_math_optimizations)
19314 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19315 && !flag_trapping_math)"
19317 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19318 && !flag_trapping_math
19319 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19322 emit_insn (gen_sse4_1_round<mode>2
19323 (operands[0], operands[1], GEN_INT (0x03)));
19324 else if (optimize_insn_for_size_p ())
19326 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19327 ix86_expand_trunc (operand0, operand1);
19329 ix86_expand_truncdf_32 (operand0, operand1);
19335 if (optimize_insn_for_size_p ())
19338 op0 = gen_reg_rtx (XFmode);
19339 op1 = gen_reg_rtx (XFmode);
19340 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19341 emit_insn (gen_frndintxf2_trunc (op0, op1));
19343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19349 (define_insn_and_split "frndintxf2_mask_pm"
19350 [(set (match_operand:XF 0 "register_operand" "")
19351 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19352 UNSPEC_FRNDINT_MASK_PM))
19353 (clobber (reg:CC FLAGS_REG))]
19354 "TARGET_USE_FANCY_MATH_387
19355 && flag_unsafe_math_optimizations
19356 && !(reload_completed || reload_in_progress)"
19361 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19363 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19364 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19366 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19367 operands[2], operands[3]));
19370 [(set_attr "type" "frndint")
19371 (set_attr "i387_cw" "mask_pm")
19372 (set_attr "mode" "XF")])
19374 (define_insn "frndintxf2_mask_pm_i387"
19375 [(set (match_operand:XF 0 "register_operand" "=f")
19376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19377 UNSPEC_FRNDINT_MASK_PM))
19378 (use (match_operand:HI 2 "memory_operand" "m"))
19379 (use (match_operand:HI 3 "memory_operand" "m"))]
19380 "TARGET_USE_FANCY_MATH_387
19381 && flag_unsafe_math_optimizations"
19382 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19383 [(set_attr "type" "frndint")
19384 (set_attr "i387_cw" "mask_pm")
19385 (set_attr "mode" "XF")])
19387 (define_expand "nearbyintxf2"
19388 [(use (match_operand:XF 0 "register_operand" ""))
19389 (use (match_operand:XF 1 "register_operand" ""))]
19390 "TARGET_USE_FANCY_MATH_387
19391 && flag_unsafe_math_optimizations"
19393 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19398 (define_expand "nearbyint<mode>2"
19399 [(use (match_operand:MODEF 0 "register_operand" ""))
19400 (use (match_operand:MODEF 1 "register_operand" ""))]
19401 "TARGET_USE_FANCY_MATH_387
19402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19403 || TARGET_MIX_SSE_I387)
19404 && flag_unsafe_math_optimizations"
19406 rtx op0 = gen_reg_rtx (XFmode);
19407 rtx op1 = gen_reg_rtx (XFmode);
19409 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19410 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19416 (define_insn "fxam<mode>2_i387"
19417 [(set (match_operand:HI 0 "register_operand" "=a")
19419 [(match_operand:X87MODEF 1 "register_operand" "f")]
19421 "TARGET_USE_FANCY_MATH_387"
19422 "fxam\n\tfnstsw\t%0"
19423 [(set_attr "type" "multi")
19424 (set_attr "length" "4")
19425 (set_attr "unit" "i387")
19426 (set_attr "mode" "<MODE>")])
19428 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19429 [(set (match_operand:HI 0 "register_operand" "")
19431 [(match_operand:MODEF 1 "memory_operand" "")]
19433 "TARGET_USE_FANCY_MATH_387
19434 && !(reload_completed || reload_in_progress)"
19437 [(set (match_dup 2)(match_dup 1))
19439 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19441 operands[2] = gen_reg_rtx (<MODE>mode);
19443 MEM_VOLATILE_P (operands[1]) = 1;
19445 [(set_attr "type" "multi")
19446 (set_attr "unit" "i387")
19447 (set_attr "mode" "<MODE>")])
19449 (define_expand "isinfxf2"
19450 [(use (match_operand:SI 0 "register_operand" ""))
19451 (use (match_operand:XF 1 "register_operand" ""))]
19452 "TARGET_USE_FANCY_MATH_387
19453 && TARGET_C99_FUNCTIONS"
19455 rtx mask = GEN_INT (0x45);
19456 rtx val = GEN_INT (0x05);
19460 rtx scratch = gen_reg_rtx (HImode);
19461 rtx res = gen_reg_rtx (QImode);
19463 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19465 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19466 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19467 cond = gen_rtx_fmt_ee (EQ, QImode,
19468 gen_rtx_REG (CCmode, FLAGS_REG),
19470 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19471 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19475 (define_expand "isinf<mode>2"
19476 [(use (match_operand:SI 0 "register_operand" ""))
19477 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19478 "TARGET_USE_FANCY_MATH_387
19479 && TARGET_C99_FUNCTIONS
19480 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19482 rtx mask = GEN_INT (0x45);
19483 rtx val = GEN_INT (0x05);
19487 rtx scratch = gen_reg_rtx (HImode);
19488 rtx res = gen_reg_rtx (QImode);
19490 /* Remove excess precision by forcing value through memory. */
19491 if (memory_operand (operands[1], VOIDmode))
19492 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19495 enum ix86_stack_slot slot = (virtuals_instantiated
19498 rtx temp = assign_386_stack_local (<MODE>mode, slot);
19500 emit_move_insn (temp, operands[1]);
19501 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19504 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19505 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19506 cond = gen_rtx_fmt_ee (EQ, QImode,
19507 gen_rtx_REG (CCmode, FLAGS_REG),
19509 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19510 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19514 (define_expand "signbit<mode>2"
19515 [(use (match_operand:SI 0 "register_operand" ""))
19516 (use (match_operand:X87MODEF 1 "register_operand" ""))]
19517 "TARGET_USE_FANCY_MATH_387
19518 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19520 rtx mask = GEN_INT (0x0200);
19522 rtx scratch = gen_reg_rtx (HImode);
19524 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19525 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19529 ;; Block operation instructions
19532 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19535 [(set_attr "length" "1")
19536 (set_attr "length_immediate" "0")
19537 (set_attr "modrm" "0")])
19539 (define_expand "movmemsi"
19540 [(use (match_operand:BLK 0 "memory_operand" ""))
19541 (use (match_operand:BLK 1 "memory_operand" ""))
19542 (use (match_operand:SI 2 "nonmemory_operand" ""))
19543 (use (match_operand:SI 3 "const_int_operand" ""))
19544 (use (match_operand:SI 4 "const_int_operand" ""))
19545 (use (match_operand:SI 5 "const_int_operand" ""))]
19548 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19549 operands[4], operands[5]))
19555 (define_expand "movmemdi"
19556 [(use (match_operand:BLK 0 "memory_operand" ""))
19557 (use (match_operand:BLK 1 "memory_operand" ""))
19558 (use (match_operand:DI 2 "nonmemory_operand" ""))
19559 (use (match_operand:DI 3 "const_int_operand" ""))
19560 (use (match_operand:SI 4 "const_int_operand" ""))
19561 (use (match_operand:SI 5 "const_int_operand" ""))]
19564 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19565 operands[4], operands[5]))
19571 ;; Most CPUs don't like single string operations
19572 ;; Handle this case here to simplify previous expander.
19574 (define_expand "strmov"
19575 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19576 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19577 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19578 (clobber (reg:CC FLAGS_REG))])
19579 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19580 (clobber (reg:CC FLAGS_REG))])]
19583 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19585 /* If .md ever supports :P for Pmode, these can be directly
19586 in the pattern above. */
19587 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19588 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19590 /* Can't use this if the user has appropriated esi or edi. */
19591 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19592 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19594 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19595 operands[2], operands[3],
19596 operands[5], operands[6]));
19600 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19603 (define_expand "strmov_singleop"
19604 [(parallel [(set (match_operand 1 "memory_operand" "")
19605 (match_operand 3 "memory_operand" ""))
19606 (set (match_operand 0 "register_operand" "")
19607 (match_operand 4 "" ""))
19608 (set (match_operand 2 "register_operand" "")
19609 (match_operand 5 "" ""))])]
19611 "ix86_current_function_needs_cld = 1;")
19613 (define_insn "*strmovdi_rex_1"
19614 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19615 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19616 (set (match_operand:DI 0 "register_operand" "=D")
19617 (plus:DI (match_dup 2)
19619 (set (match_operand:DI 1 "register_operand" "=S")
19620 (plus:DI (match_dup 3)
19624 [(set_attr "type" "str")
19625 (set_attr "mode" "DI")
19626 (set_attr "memory" "both")])
19628 (define_insn "*strmovsi_1"
19629 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19630 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19631 (set (match_operand:SI 0 "register_operand" "=D")
19632 (plus:SI (match_dup 2)
19634 (set (match_operand:SI 1 "register_operand" "=S")
19635 (plus:SI (match_dup 3)
19639 [(set_attr "type" "str")
19640 (set_attr "mode" "SI")
19641 (set_attr "memory" "both")])
19643 (define_insn "*strmovsi_rex_1"
19644 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19645 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19646 (set (match_operand:DI 0 "register_operand" "=D")
19647 (plus:DI (match_dup 2)
19649 (set (match_operand:DI 1 "register_operand" "=S")
19650 (plus:DI (match_dup 3)
19654 [(set_attr "type" "str")
19655 (set_attr "mode" "SI")
19656 (set_attr "memory" "both")])
19658 (define_insn "*strmovhi_1"
19659 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19660 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19661 (set (match_operand:SI 0 "register_operand" "=D")
19662 (plus:SI (match_dup 2)
19664 (set (match_operand:SI 1 "register_operand" "=S")
19665 (plus:SI (match_dup 3)
19669 [(set_attr "type" "str")
19670 (set_attr "memory" "both")
19671 (set_attr "mode" "HI")])
19673 (define_insn "*strmovhi_rex_1"
19674 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19675 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19676 (set (match_operand:DI 0 "register_operand" "=D")
19677 (plus:DI (match_dup 2)
19679 (set (match_operand:DI 1 "register_operand" "=S")
19680 (plus:DI (match_dup 3)
19684 [(set_attr "type" "str")
19685 (set_attr "memory" "both")
19686 (set_attr "mode" "HI")])
19688 (define_insn "*strmovqi_1"
19689 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19690 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19691 (set (match_operand:SI 0 "register_operand" "=D")
19692 (plus:SI (match_dup 2)
19694 (set (match_operand:SI 1 "register_operand" "=S")
19695 (plus:SI (match_dup 3)
19699 [(set_attr "type" "str")
19700 (set_attr "memory" "both")
19701 (set_attr "mode" "QI")])
19703 (define_insn "*strmovqi_rex_1"
19704 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19705 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19706 (set (match_operand:DI 0 "register_operand" "=D")
19707 (plus:DI (match_dup 2)
19709 (set (match_operand:DI 1 "register_operand" "=S")
19710 (plus:DI (match_dup 3)
19714 [(set_attr "type" "str")
19715 (set_attr "memory" "both")
19716 (set_attr "prefix_rex" "0")
19717 (set_attr "mode" "QI")])
19719 (define_expand "rep_mov"
19720 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19721 (set (match_operand 0 "register_operand" "")
19722 (match_operand 5 "" ""))
19723 (set (match_operand 2 "register_operand" "")
19724 (match_operand 6 "" ""))
19725 (set (match_operand 1 "memory_operand" "")
19726 (match_operand 3 "memory_operand" ""))
19727 (use (match_dup 4))])]
19729 "ix86_current_function_needs_cld = 1;")
19731 (define_insn "*rep_movdi_rex64"
19732 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19733 (set (match_operand:DI 0 "register_operand" "=D")
19734 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19736 (match_operand:DI 3 "register_operand" "0")))
19737 (set (match_operand:DI 1 "register_operand" "=S")
19738 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19739 (match_operand:DI 4 "register_operand" "1")))
19740 (set (mem:BLK (match_dup 3))
19741 (mem:BLK (match_dup 4)))
19742 (use (match_dup 5))]
19745 [(set_attr "type" "str")
19746 (set_attr "prefix_rep" "1")
19747 (set_attr "memory" "both")
19748 (set_attr "mode" "DI")])
19750 (define_insn "*rep_movsi"
19751 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19752 (set (match_operand:SI 0 "register_operand" "=D")
19753 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19755 (match_operand:SI 3 "register_operand" "0")))
19756 (set (match_operand:SI 1 "register_operand" "=S")
19757 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19758 (match_operand:SI 4 "register_operand" "1")))
19759 (set (mem:BLK (match_dup 3))
19760 (mem:BLK (match_dup 4)))
19761 (use (match_dup 5))]
19764 [(set_attr "type" "str")
19765 (set_attr "prefix_rep" "1")
19766 (set_attr "memory" "both")
19767 (set_attr "mode" "SI")])
19769 (define_insn "*rep_movsi_rex64"
19770 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19771 (set (match_operand:DI 0 "register_operand" "=D")
19772 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19774 (match_operand:DI 3 "register_operand" "0")))
19775 (set (match_operand:DI 1 "register_operand" "=S")
19776 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19777 (match_operand:DI 4 "register_operand" "1")))
19778 (set (mem:BLK (match_dup 3))
19779 (mem:BLK (match_dup 4)))
19780 (use (match_dup 5))]
19783 [(set_attr "type" "str")
19784 (set_attr "prefix_rep" "1")
19785 (set_attr "memory" "both")
19786 (set_attr "mode" "SI")])
19788 (define_insn "*rep_movqi"
19789 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19790 (set (match_operand:SI 0 "register_operand" "=D")
19791 (plus:SI (match_operand:SI 3 "register_operand" "0")
19792 (match_operand:SI 5 "register_operand" "2")))
19793 (set (match_operand:SI 1 "register_operand" "=S")
19794 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19795 (set (mem:BLK (match_dup 3))
19796 (mem:BLK (match_dup 4)))
19797 (use (match_dup 5))]
19800 [(set_attr "type" "str")
19801 (set_attr "prefix_rep" "1")
19802 (set_attr "memory" "both")
19803 (set_attr "mode" "SI")])
19805 (define_insn "*rep_movqi_rex64"
19806 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19807 (set (match_operand:DI 0 "register_operand" "=D")
19808 (plus:DI (match_operand:DI 3 "register_operand" "0")
19809 (match_operand:DI 5 "register_operand" "2")))
19810 (set (match_operand:DI 1 "register_operand" "=S")
19811 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19812 (set (mem:BLK (match_dup 3))
19813 (mem:BLK (match_dup 4)))
19814 (use (match_dup 5))]
19817 [(set_attr "type" "str")
19818 (set_attr "prefix_rep" "1")
19819 (set_attr "memory" "both")
19820 (set_attr "mode" "SI")])
19822 (define_expand "setmemsi"
19823 [(use (match_operand:BLK 0 "memory_operand" ""))
19824 (use (match_operand:SI 1 "nonmemory_operand" ""))
19825 (use (match_operand 2 "const_int_operand" ""))
19826 (use (match_operand 3 "const_int_operand" ""))
19827 (use (match_operand:SI 4 "const_int_operand" ""))
19828 (use (match_operand:SI 5 "const_int_operand" ""))]
19831 if (ix86_expand_setmem (operands[0], operands[1],
19832 operands[2], operands[3],
19833 operands[4], operands[5]))
19839 (define_expand "setmemdi"
19840 [(use (match_operand:BLK 0 "memory_operand" ""))
19841 (use (match_operand:DI 1 "nonmemory_operand" ""))
19842 (use (match_operand 2 "const_int_operand" ""))
19843 (use (match_operand 3 "const_int_operand" ""))
19844 (use (match_operand 4 "const_int_operand" ""))
19845 (use (match_operand 5 "const_int_operand" ""))]
19848 if (ix86_expand_setmem (operands[0], operands[1],
19849 operands[2], operands[3],
19850 operands[4], operands[5]))
19856 ;; Most CPUs don't like single string operations
19857 ;; Handle this case here to simplify previous expander.
19859 (define_expand "strset"
19860 [(set (match_operand 1 "memory_operand" "")
19861 (match_operand 2 "register_operand" ""))
19862 (parallel [(set (match_operand 0 "register_operand" "")
19864 (clobber (reg:CC FLAGS_REG))])]
19867 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19868 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19870 /* If .md ever supports :P for Pmode, this can be directly
19871 in the pattern above. */
19872 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19873 GEN_INT (GET_MODE_SIZE (GET_MODE
19875 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19877 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19883 (define_expand "strset_singleop"
19884 [(parallel [(set (match_operand 1 "memory_operand" "")
19885 (match_operand 2 "register_operand" ""))
19886 (set (match_operand 0 "register_operand" "")
19887 (match_operand 3 "" ""))])]
19889 "ix86_current_function_needs_cld = 1;")
19891 (define_insn "*strsetdi_rex_1"
19892 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19893 (match_operand:DI 2 "register_operand" "a"))
19894 (set (match_operand:DI 0 "register_operand" "=D")
19895 (plus:DI (match_dup 1)
19899 [(set_attr "type" "str")
19900 (set_attr "memory" "store")
19901 (set_attr "mode" "DI")])
19903 (define_insn "*strsetsi_1"
19904 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19905 (match_operand:SI 2 "register_operand" "a"))
19906 (set (match_operand:SI 0 "register_operand" "=D")
19907 (plus:SI (match_dup 1)
19911 [(set_attr "type" "str")
19912 (set_attr "memory" "store")
19913 (set_attr "mode" "SI")])
19915 (define_insn "*strsetsi_rex_1"
19916 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19917 (match_operand:SI 2 "register_operand" "a"))
19918 (set (match_operand:DI 0 "register_operand" "=D")
19919 (plus:DI (match_dup 1)
19923 [(set_attr "type" "str")
19924 (set_attr "memory" "store")
19925 (set_attr "mode" "SI")])
19927 (define_insn "*strsethi_1"
19928 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19929 (match_operand:HI 2 "register_operand" "a"))
19930 (set (match_operand:SI 0 "register_operand" "=D")
19931 (plus:SI (match_dup 1)
19935 [(set_attr "type" "str")
19936 (set_attr "memory" "store")
19937 (set_attr "mode" "HI")])
19939 (define_insn "*strsethi_rex_1"
19940 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19941 (match_operand:HI 2 "register_operand" "a"))
19942 (set (match_operand:DI 0 "register_operand" "=D")
19943 (plus:DI (match_dup 1)
19947 [(set_attr "type" "str")
19948 (set_attr "memory" "store")
19949 (set_attr "mode" "HI")])
19951 (define_insn "*strsetqi_1"
19952 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19953 (match_operand:QI 2 "register_operand" "a"))
19954 (set (match_operand:SI 0 "register_operand" "=D")
19955 (plus:SI (match_dup 1)
19959 [(set_attr "type" "str")
19960 (set_attr "memory" "store")
19961 (set_attr "mode" "QI")])
19963 (define_insn "*strsetqi_rex_1"
19964 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19965 (match_operand:QI 2 "register_operand" "a"))
19966 (set (match_operand:DI 0 "register_operand" "=D")
19967 (plus:DI (match_dup 1)
19971 [(set_attr "type" "str")
19972 (set_attr "memory" "store")
19973 (set_attr "prefix_rex" "0")
19974 (set_attr "mode" "QI")])
19976 (define_expand "rep_stos"
19977 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19978 (set (match_operand 0 "register_operand" "")
19979 (match_operand 4 "" ""))
19980 (set (match_operand 2 "memory_operand" "") (const_int 0))
19981 (use (match_operand 3 "register_operand" ""))
19982 (use (match_dup 1))])]
19984 "ix86_current_function_needs_cld = 1;")
19986 (define_insn "*rep_stosdi_rex64"
19987 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19988 (set (match_operand:DI 0 "register_operand" "=D")
19989 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19991 (match_operand:DI 3 "register_operand" "0")))
19992 (set (mem:BLK (match_dup 3))
19994 (use (match_operand:DI 2 "register_operand" "a"))
19995 (use (match_dup 4))]
19998 [(set_attr "type" "str")
19999 (set_attr "prefix_rep" "1")
20000 (set_attr "memory" "store")
20001 (set_attr "mode" "DI")])
20003 (define_insn "*rep_stossi"
20004 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20005 (set (match_operand:SI 0 "register_operand" "=D")
20006 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
20008 (match_operand:SI 3 "register_operand" "0")))
20009 (set (mem:BLK (match_dup 3))
20011 (use (match_operand:SI 2 "register_operand" "a"))
20012 (use (match_dup 4))]
20015 [(set_attr "type" "str")
20016 (set_attr "prefix_rep" "1")
20017 (set_attr "memory" "store")
20018 (set_attr "mode" "SI")])
20020 (define_insn "*rep_stossi_rex64"
20021 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20022 (set (match_operand:DI 0 "register_operand" "=D")
20023 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20025 (match_operand:DI 3 "register_operand" "0")))
20026 (set (mem:BLK (match_dup 3))
20028 (use (match_operand:SI 2 "register_operand" "a"))
20029 (use (match_dup 4))]
20032 [(set_attr "type" "str")
20033 (set_attr "prefix_rep" "1")
20034 (set_attr "memory" "store")
20035 (set_attr "mode" "SI")])
20037 (define_insn "*rep_stosqi"
20038 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20039 (set (match_operand:SI 0 "register_operand" "=D")
20040 (plus:SI (match_operand:SI 3 "register_operand" "0")
20041 (match_operand:SI 4 "register_operand" "1")))
20042 (set (mem:BLK (match_dup 3))
20044 (use (match_operand:QI 2 "register_operand" "a"))
20045 (use (match_dup 4))]
20048 [(set_attr "type" "str")
20049 (set_attr "prefix_rep" "1")
20050 (set_attr "memory" "store")
20051 (set_attr "mode" "QI")])
20053 (define_insn "*rep_stosqi_rex64"
20054 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20055 (set (match_operand:DI 0 "register_operand" "=D")
20056 (plus:DI (match_operand:DI 3 "register_operand" "0")
20057 (match_operand:DI 4 "register_operand" "1")))
20058 (set (mem:BLK (match_dup 3))
20060 (use (match_operand:QI 2 "register_operand" "a"))
20061 (use (match_dup 4))]
20064 [(set_attr "type" "str")
20065 (set_attr "prefix_rep" "1")
20066 (set_attr "memory" "store")
20067 (set_attr "prefix_rex" "0")
20068 (set_attr "mode" "QI")])
20070 (define_expand "cmpstrnsi"
20071 [(set (match_operand:SI 0 "register_operand" "")
20072 (compare:SI (match_operand:BLK 1 "general_operand" "")
20073 (match_operand:BLK 2 "general_operand" "")))
20074 (use (match_operand 3 "general_operand" ""))
20075 (use (match_operand 4 "immediate_operand" ""))]
20078 rtx addr1, addr2, out, outlow, count, countreg, align;
20080 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20083 /* Can't use this if the user has appropriated esi or edi. */
20084 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20089 out = gen_reg_rtx (SImode);
20091 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20092 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20093 if (addr1 != XEXP (operands[1], 0))
20094 operands[1] = replace_equiv_address_nv (operands[1], addr1);
20095 if (addr2 != XEXP (operands[2], 0))
20096 operands[2] = replace_equiv_address_nv (operands[2], addr2);
20098 count = operands[3];
20099 countreg = ix86_zero_extend_to_Pmode (count);
20101 /* %%% Iff we are testing strict equality, we can use known alignment
20102 to good advantage. This may be possible with combine, particularly
20103 once cc0 is dead. */
20104 align = operands[4];
20106 if (CONST_INT_P (count))
20108 if (INTVAL (count) == 0)
20110 emit_move_insn (operands[0], const0_rtx);
20113 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20114 operands[1], operands[2]));
20119 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20121 emit_insn (gen_cmpsi_1 (countreg, countreg));
20122 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20123 operands[1], operands[2]));
20126 outlow = gen_lowpart (QImode, out);
20127 emit_insn (gen_cmpintqi (outlow));
20128 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20130 if (operands[0] != out)
20131 emit_move_insn (operands[0], out);
20136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20138 (define_expand "cmpintqi"
20139 [(set (match_dup 1)
20140 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20142 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20143 (parallel [(set (match_operand:QI 0 "register_operand" "")
20144 (minus:QI (match_dup 1)
20146 (clobber (reg:CC FLAGS_REG))])]
20148 "operands[1] = gen_reg_rtx (QImode);
20149 operands[2] = gen_reg_rtx (QImode);")
20151 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
20152 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
20154 (define_expand "cmpstrnqi_nz_1"
20155 [(parallel [(set (reg:CC FLAGS_REG)
20156 (compare:CC (match_operand 4 "memory_operand" "")
20157 (match_operand 5 "memory_operand" "")))
20158 (use (match_operand 2 "register_operand" ""))
20159 (use (match_operand:SI 3 "immediate_operand" ""))
20160 (clobber (match_operand 0 "register_operand" ""))
20161 (clobber (match_operand 1 "register_operand" ""))
20162 (clobber (match_dup 2))])]
20164 "ix86_current_function_needs_cld = 1;")
20166 (define_insn "*cmpstrnqi_nz_1"
20167 [(set (reg:CC FLAGS_REG)
20168 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20169 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20170 (use (match_operand:SI 6 "register_operand" "2"))
20171 (use (match_operand:SI 3 "immediate_operand" "i"))
20172 (clobber (match_operand:SI 0 "register_operand" "=S"))
20173 (clobber (match_operand:SI 1 "register_operand" "=D"))
20174 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20177 [(set_attr "type" "str")
20178 (set_attr "mode" "QI")
20179 (set_attr "prefix_rep" "1")])
20181 (define_insn "*cmpstrnqi_nz_rex_1"
20182 [(set (reg:CC FLAGS_REG)
20183 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20184 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20185 (use (match_operand:DI 6 "register_operand" "2"))
20186 (use (match_operand:SI 3 "immediate_operand" "i"))
20187 (clobber (match_operand:DI 0 "register_operand" "=S"))
20188 (clobber (match_operand:DI 1 "register_operand" "=D"))
20189 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20192 [(set_attr "type" "str")
20193 (set_attr "mode" "QI")
20194 (set_attr "prefix_rex" "0")
20195 (set_attr "prefix_rep" "1")])
20197 ;; The same, but the count is not known to not be zero.
20199 (define_expand "cmpstrnqi_1"
20200 [(parallel [(set (reg:CC FLAGS_REG)
20201 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20203 (compare:CC (match_operand 4 "memory_operand" "")
20204 (match_operand 5 "memory_operand" ""))
20206 (use (match_operand:SI 3 "immediate_operand" ""))
20207 (use (reg:CC FLAGS_REG))
20208 (clobber (match_operand 0 "register_operand" ""))
20209 (clobber (match_operand 1 "register_operand" ""))
20210 (clobber (match_dup 2))])]
20212 "ix86_current_function_needs_cld = 1;")
20214 (define_insn "*cmpstrnqi_1"
20215 [(set (reg:CC FLAGS_REG)
20216 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20218 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20219 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20221 (use (match_operand:SI 3 "immediate_operand" "i"))
20222 (use (reg:CC FLAGS_REG))
20223 (clobber (match_operand:SI 0 "register_operand" "=S"))
20224 (clobber (match_operand:SI 1 "register_operand" "=D"))
20225 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20228 [(set_attr "type" "str")
20229 (set_attr "mode" "QI")
20230 (set_attr "prefix_rep" "1")])
20232 (define_insn "*cmpstrnqi_rex_1"
20233 [(set (reg:CC FLAGS_REG)
20234 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20236 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20237 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20239 (use (match_operand:SI 3 "immediate_operand" "i"))
20240 (use (reg:CC FLAGS_REG))
20241 (clobber (match_operand:DI 0 "register_operand" "=S"))
20242 (clobber (match_operand:DI 1 "register_operand" "=D"))
20243 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20246 [(set_attr "type" "str")
20247 (set_attr "mode" "QI")
20248 (set_attr "prefix_rex" "0")
20249 (set_attr "prefix_rep" "1")])
20251 (define_expand "strlensi"
20252 [(set (match_operand:SI 0 "register_operand" "")
20253 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20254 (match_operand:QI 2 "immediate_operand" "")
20255 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20258 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20264 (define_expand "strlendi"
20265 [(set (match_operand:DI 0 "register_operand" "")
20266 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20267 (match_operand:QI 2 "immediate_operand" "")
20268 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20271 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20277 (define_expand "strlenqi_1"
20278 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20279 (clobber (match_operand 1 "register_operand" ""))
20280 (clobber (reg:CC FLAGS_REG))])]
20282 "ix86_current_function_needs_cld = 1;")
20284 (define_insn "*strlenqi_1"
20285 [(set (match_operand:SI 0 "register_operand" "=&c")
20286 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20287 (match_operand:QI 2 "register_operand" "a")
20288 (match_operand:SI 3 "immediate_operand" "i")
20289 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20290 (clobber (match_operand:SI 1 "register_operand" "=D"))
20291 (clobber (reg:CC FLAGS_REG))]
20294 [(set_attr "type" "str")
20295 (set_attr "mode" "QI")
20296 (set_attr "prefix_rep" "1")])
20298 (define_insn "*strlenqi_rex_1"
20299 [(set (match_operand:DI 0 "register_operand" "=&c")
20300 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20301 (match_operand:QI 2 "register_operand" "a")
20302 (match_operand:DI 3 "immediate_operand" "i")
20303 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20304 (clobber (match_operand:DI 1 "register_operand" "=D"))
20305 (clobber (reg:CC FLAGS_REG))]
20308 [(set_attr "type" "str")
20309 (set_attr "mode" "QI")
20310 (set_attr "prefix_rex" "0")
20311 (set_attr "prefix_rep" "1")])
20313 ;; Peephole optimizations to clean up after cmpstrn*. This should be
20314 ;; handled in combine, but it is not currently up to the task.
20315 ;; When used for their truth value, the cmpstrn* expanders generate
20324 ;; The intermediate three instructions are unnecessary.
20326 ;; This one handles cmpstrn*_nz_1...
20329 (set (reg:CC FLAGS_REG)
20330 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20331 (mem:BLK (match_operand 5 "register_operand" ""))))
20332 (use (match_operand 6 "register_operand" ""))
20333 (use (match_operand:SI 3 "immediate_operand" ""))
20334 (clobber (match_operand 0 "register_operand" ""))
20335 (clobber (match_operand 1 "register_operand" ""))
20336 (clobber (match_operand 2 "register_operand" ""))])
20337 (set (match_operand:QI 7 "register_operand" "")
20338 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20339 (set (match_operand:QI 8 "register_operand" "")
20340 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20341 (set (reg FLAGS_REG)
20342 (compare (match_dup 7) (match_dup 8)))
20344 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20346 (set (reg:CC FLAGS_REG)
20347 (compare:CC (mem:BLK (match_dup 4))
20348 (mem:BLK (match_dup 5))))
20349 (use (match_dup 6))
20350 (use (match_dup 3))
20351 (clobber (match_dup 0))
20352 (clobber (match_dup 1))
20353 (clobber (match_dup 2))])]
20356 ;; ...and this one handles cmpstrn*_1.
20359 (set (reg:CC FLAGS_REG)
20360 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20362 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20363 (mem:BLK (match_operand 5 "register_operand" "")))
20365 (use (match_operand:SI 3 "immediate_operand" ""))
20366 (use (reg:CC FLAGS_REG))
20367 (clobber (match_operand 0 "register_operand" ""))
20368 (clobber (match_operand 1 "register_operand" ""))
20369 (clobber (match_operand 2 "register_operand" ""))])
20370 (set (match_operand:QI 7 "register_operand" "")
20371 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20372 (set (match_operand:QI 8 "register_operand" "")
20373 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20374 (set (reg FLAGS_REG)
20375 (compare (match_dup 7) (match_dup 8)))
20377 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20379 (set (reg:CC FLAGS_REG)
20380 (if_then_else:CC (ne (match_dup 6)
20382 (compare:CC (mem:BLK (match_dup 4))
20383 (mem:BLK (match_dup 5)))
20385 (use (match_dup 3))
20386 (use (reg:CC FLAGS_REG))
20387 (clobber (match_dup 0))
20388 (clobber (match_dup 1))
20389 (clobber (match_dup 2))])]
20394 ;; Conditional move instructions.
20396 (define_expand "movdicc"
20397 [(set (match_operand:DI 0 "register_operand" "")
20398 (if_then_else:DI (match_operand 1 "comparison_operator" "")
20399 (match_operand:DI 2 "general_operand" "")
20400 (match_operand:DI 3 "general_operand" "")))]
20402 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20404 (define_insn "x86_movdicc_0_m1_rex64"
20405 [(set (match_operand:DI 0 "register_operand" "=r")
20406 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20409 (clobber (reg:CC FLAGS_REG))]
20412 ; Since we don't have the proper number of operands for an alu insn,
20413 ; fill in all the blanks.
20414 [(set_attr "type" "alu")
20415 (set_attr "use_carry" "1")
20416 (set_attr "pent_pair" "pu")
20417 (set_attr "memory" "none")
20418 (set_attr "imm_disp" "false")
20419 (set_attr "mode" "DI")
20420 (set_attr "length_immediate" "0")])
20422 (define_insn "*x86_movdicc_0_m1_se"
20423 [(set (match_operand:DI 0 "register_operand" "=r")
20424 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20427 (clobber (reg:CC FLAGS_REG))]
20430 [(set_attr "type" "alu")
20431 (set_attr "use_carry" "1")
20432 (set_attr "pent_pair" "pu")
20433 (set_attr "memory" "none")
20434 (set_attr "imm_disp" "false")
20435 (set_attr "mode" "DI")
20436 (set_attr "length_immediate" "0")])
20438 (define_insn "*movdicc_c_rex64"
20439 [(set (match_operand:DI 0 "register_operand" "=r,r")
20440 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20441 [(reg FLAGS_REG) (const_int 0)])
20442 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20443 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20444 "TARGET_64BIT && TARGET_CMOVE
20445 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20447 cmov%O2%C1\t{%2, %0|%0, %2}
20448 cmov%O2%c1\t{%3, %0|%0, %3}"
20449 [(set_attr "type" "icmov")
20450 (set_attr "mode" "DI")])
20452 (define_expand "movsicc"
20453 [(set (match_operand:SI 0 "register_operand" "")
20454 (if_then_else:SI (match_operand 1 "comparison_operator" "")
20455 (match_operand:SI 2 "general_operand" "")
20456 (match_operand:SI 3 "general_operand" "")))]
20458 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20460 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20461 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20462 ;; So just document what we're doing explicitly.
20464 (define_insn "x86_movsicc_0_m1"
20465 [(set (match_operand:SI 0 "register_operand" "=r")
20466 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20469 (clobber (reg:CC FLAGS_REG))]
20472 ; Since we don't have the proper number of operands for an alu insn,
20473 ; fill in all the blanks.
20474 [(set_attr "type" "alu")
20475 (set_attr "use_carry" "1")
20476 (set_attr "pent_pair" "pu")
20477 (set_attr "memory" "none")
20478 (set_attr "imm_disp" "false")
20479 (set_attr "mode" "SI")
20480 (set_attr "length_immediate" "0")])
20482 (define_insn "*x86_movsicc_0_m1_se"
20483 [(set (match_operand:SI 0 "register_operand" "=r")
20484 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20487 (clobber (reg:CC FLAGS_REG))]
20490 [(set_attr "type" "alu")
20491 (set_attr "use_carry" "1")
20492 (set_attr "pent_pair" "pu")
20493 (set_attr "memory" "none")
20494 (set_attr "imm_disp" "false")
20495 (set_attr "mode" "SI")
20496 (set_attr "length_immediate" "0")])
20498 (define_insn "*movsicc_noc"
20499 [(set (match_operand:SI 0 "register_operand" "=r,r")
20500 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20501 [(reg FLAGS_REG) (const_int 0)])
20502 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20503 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20505 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20507 cmov%O2%C1\t{%2, %0|%0, %2}
20508 cmov%O2%c1\t{%3, %0|%0, %3}"
20509 [(set_attr "type" "icmov")
20510 (set_attr "mode" "SI")])
20512 (define_expand "movhicc"
20513 [(set (match_operand:HI 0 "register_operand" "")
20514 (if_then_else:HI (match_operand 1 "comparison_operator" "")
20515 (match_operand:HI 2 "general_operand" "")
20516 (match_operand:HI 3 "general_operand" "")))]
20517 "TARGET_HIMODE_MATH"
20518 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20520 (define_insn "*movhicc_noc"
20521 [(set (match_operand:HI 0 "register_operand" "=r,r")
20522 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20523 [(reg FLAGS_REG) (const_int 0)])
20524 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20525 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20527 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20529 cmov%O2%C1\t{%2, %0|%0, %2}
20530 cmov%O2%c1\t{%3, %0|%0, %3}"
20531 [(set_attr "type" "icmov")
20532 (set_attr "mode" "HI")])
20534 (define_expand "movqicc"
20535 [(set (match_operand:QI 0 "register_operand" "")
20536 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20537 (match_operand:QI 2 "general_operand" "")
20538 (match_operand:QI 3 "general_operand" "")))]
20539 "TARGET_QIMODE_MATH"
20540 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20542 (define_insn_and_split "*movqicc_noc"
20543 [(set (match_operand:QI 0 "register_operand" "=r,r")
20544 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20545 [(match_operand 4 "flags_reg_operand" "")
20547 (match_operand:QI 2 "register_operand" "r,0")
20548 (match_operand:QI 3 "register_operand" "0,r")))]
20549 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20551 "&& reload_completed"
20552 [(set (match_dup 0)
20553 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20556 "operands[0] = gen_lowpart (SImode, operands[0]);
20557 operands[2] = gen_lowpart (SImode, operands[2]);
20558 operands[3] = gen_lowpart (SImode, operands[3]);"
20559 [(set_attr "type" "icmov")
20560 (set_attr "mode" "SI")])
20562 (define_expand "mov<mode>cc"
20563 [(set (match_operand:X87MODEF 0 "register_operand" "")
20564 (if_then_else:X87MODEF
20565 (match_operand 1 "ix86_fp_comparison_operator" "")
20566 (match_operand:X87MODEF 2 "register_operand" "")
20567 (match_operand:X87MODEF 3 "register_operand" "")))]
20568 "(TARGET_80387 && TARGET_CMOVE)
20569 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20570 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20572 (define_insn "*movsfcc_1_387"
20573 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20574 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20575 [(reg FLAGS_REG) (const_int 0)])
20576 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20577 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20578 "TARGET_80387 && TARGET_CMOVE
20579 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20581 fcmov%F1\t{%2, %0|%0, %2}
20582 fcmov%f1\t{%3, %0|%0, %3}
20583 cmov%O2%C1\t{%2, %0|%0, %2}
20584 cmov%O2%c1\t{%3, %0|%0, %3}"
20585 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20586 (set_attr "mode" "SF,SF,SI,SI")])
20588 (define_insn "*movdfcc_1"
20589 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20590 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20591 [(reg FLAGS_REG) (const_int 0)])
20592 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20593 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20594 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20595 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20597 fcmov%F1\t{%2, %0|%0, %2}
20598 fcmov%f1\t{%3, %0|%0, %3}
20601 [(set_attr "type" "fcmov,fcmov,multi,multi")
20602 (set_attr "mode" "DF")])
20604 (define_insn "*movdfcc_1_rex64"
20605 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20606 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20607 [(reg FLAGS_REG) (const_int 0)])
20608 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20609 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20610 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20611 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20613 fcmov%F1\t{%2, %0|%0, %2}
20614 fcmov%f1\t{%3, %0|%0, %3}
20615 cmov%O2%C1\t{%2, %0|%0, %2}
20616 cmov%O2%c1\t{%3, %0|%0, %3}"
20617 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20618 (set_attr "mode" "DF")])
20621 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20622 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20623 [(match_operand 4 "flags_reg_operand" "")
20625 (match_operand:DF 2 "nonimmediate_operand" "")
20626 (match_operand:DF 3 "nonimmediate_operand" "")))]
20627 "!TARGET_64BIT && reload_completed"
20628 [(set (match_dup 2)
20629 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20633 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20636 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20637 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20639 (define_insn "*movxfcc_1"
20640 [(set (match_operand:XF 0 "register_operand" "=f,f")
20641 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20642 [(reg FLAGS_REG) (const_int 0)])
20643 (match_operand:XF 2 "register_operand" "f,0")
20644 (match_operand:XF 3 "register_operand" "0,f")))]
20645 "TARGET_80387 && TARGET_CMOVE"
20647 fcmov%F1\t{%2, %0|%0, %2}
20648 fcmov%f1\t{%3, %0|%0, %3}"
20649 [(set_attr "type" "fcmov")
20650 (set_attr "mode" "XF")])
20652 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20653 ;; the scalar versions to have only XMM registers as operands.
20655 ;; SSE5 conditional move
20656 (define_insn "*sse5_pcmov_<mode>"
20657 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20658 (if_then_else:MODEF
20659 (match_operand:MODEF 1 "register_operand" "x,0")
20660 (match_operand:MODEF 2 "register_operand" "0,x")
20661 (match_operand:MODEF 3 "register_operand" "x,x")))]
20662 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20663 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20664 [(set_attr "type" "sse4arg")])
20666 ;; These versions of the min/max patterns are intentionally ignorant of
20667 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20668 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20669 ;; are undefined in this condition, we're certain this is correct.
20671 (define_insn "*avx_<code><mode>3"
20672 [(set (match_operand:MODEF 0 "register_operand" "=x")
20674 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20675 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20676 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20677 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20678 [(set_attr "type" "sseadd")
20679 (set_attr "prefix" "vex")
20680 (set_attr "mode" "<MODE>")])
20682 (define_insn "<code><mode>3"
20683 [(set (match_operand:MODEF 0 "register_operand" "=x")
20685 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20686 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20687 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20688 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20689 [(set_attr "type" "sseadd")
20690 (set_attr "mode" "<MODE>")])
20692 ;; These versions of the min/max patterns implement exactly the operations
20693 ;; min = (op1 < op2 ? op1 : op2)
20694 ;; max = (!(op1 < op2) ? op1 : op2)
20695 ;; Their operands are not commutative, and thus they may be used in the
20696 ;; presence of -0.0 and NaN.
20698 (define_insn "*avx_ieee_smin<mode>3"
20699 [(set (match_operand:MODEF 0 "register_operand" "=x")
20701 [(match_operand:MODEF 1 "register_operand" "x")
20702 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20704 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20705 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20706 [(set_attr "type" "sseadd")
20707 (set_attr "prefix" "vex")
20708 (set_attr "mode" "<MODE>")])
20710 (define_insn "*ieee_smin<mode>3"
20711 [(set (match_operand:MODEF 0 "register_operand" "=x")
20713 [(match_operand:MODEF 1 "register_operand" "0")
20714 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20716 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20717 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20718 [(set_attr "type" "sseadd")
20719 (set_attr "mode" "<MODE>")])
20721 (define_insn "*avx_ieee_smax<mode>3"
20722 [(set (match_operand:MODEF 0 "register_operand" "=x")
20724 [(match_operand:MODEF 1 "register_operand" "0")
20725 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20727 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20728 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20729 [(set_attr "type" "sseadd")
20730 (set_attr "prefix" "vex")
20731 (set_attr "mode" "<MODE>")])
20733 (define_insn "*ieee_smax<mode>3"
20734 [(set (match_operand:MODEF 0 "register_operand" "=x")
20736 [(match_operand:MODEF 1 "register_operand" "0")
20737 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20739 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20740 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20741 [(set_attr "type" "sseadd")
20742 (set_attr "mode" "<MODE>")])
20744 ;; Make two stack loads independent:
20746 ;; fld %st(0) -> fld bb
20747 ;; fmul bb fmul %st(1), %st
20749 ;; Actually we only match the last two instructions for simplicity.
20751 [(set (match_operand 0 "fp_register_operand" "")
20752 (match_operand 1 "fp_register_operand" ""))
20754 (match_operator 2 "binary_fp_operator"
20756 (match_operand 3 "memory_operand" "")]))]
20757 "REGNO (operands[0]) != REGNO (operands[1])"
20758 [(set (match_dup 0) (match_dup 3))
20759 (set (match_dup 0) (match_dup 4))]
20761 ;; The % modifier is not operational anymore in peephole2's, so we have to
20762 ;; swap the operands manually in the case of addition and multiplication.
20763 "if (COMMUTATIVE_ARITH_P (operands[2]))
20764 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20765 operands[0], operands[1]);
20767 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20768 operands[1], operands[0]);")
20770 ;; Conditional addition patterns
20771 (define_expand "add<mode>cc"
20772 [(match_operand:SWI 0 "register_operand" "")
20773 (match_operand 1 "comparison_operator" "")
20774 (match_operand:SWI 2 "register_operand" "")
20775 (match_operand:SWI 3 "const_int_operand" "")]
20777 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20780 ;; Misc patterns (?)
20782 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20783 ;; Otherwise there will be nothing to keep
20785 ;; [(set (reg ebp) (reg esp))]
20786 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20787 ;; (clobber (eflags)]
20788 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20790 ;; in proper program order.
20791 (define_insn "pro_epilogue_adjust_stack_1"
20792 [(set (match_operand:SI 0 "register_operand" "=r,r")
20793 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20794 (match_operand:SI 2 "immediate_operand" "i,i")))
20795 (clobber (reg:CC FLAGS_REG))
20796 (clobber (mem:BLK (scratch)))]
20799 switch (get_attr_type (insn))
20802 return "mov{l}\t{%1, %0|%0, %1}";
20805 if (CONST_INT_P (operands[2])
20806 && (INTVAL (operands[2]) == 128
20807 || (INTVAL (operands[2]) < 0
20808 && INTVAL (operands[2]) != -128)))
20810 operands[2] = GEN_INT (-INTVAL (operands[2]));
20811 return "sub{l}\t{%2, %0|%0, %2}";
20813 return "add{l}\t{%2, %0|%0, %2}";
20816 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20817 return "lea{l}\t{%a2, %0|%0, %a2}";
20820 gcc_unreachable ();
20823 [(set (attr "type")
20824 (cond [(and (eq_attr "alternative" "0")
20825 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20826 (const_string "alu")
20827 (match_operand:SI 2 "const0_operand" "")
20828 (const_string "imov")
20830 (const_string "lea")))
20831 (set (attr "length_immediate")
20832 (cond [(eq_attr "type" "imov")
20834 (and (eq_attr "type" "alu")
20835 (match_operand 2 "const128_operand" ""))
20838 (const_string "*")))
20839 (set_attr "mode" "SI")])
20841 (define_insn "pro_epilogue_adjust_stack_rex64"
20842 [(set (match_operand:DI 0 "register_operand" "=r,r")
20843 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20844 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20845 (clobber (reg:CC FLAGS_REG))
20846 (clobber (mem:BLK (scratch)))]
20849 switch (get_attr_type (insn))
20852 return "mov{q}\t{%1, %0|%0, %1}";
20855 if (CONST_INT_P (operands[2])
20856 /* Avoid overflows. */
20857 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20858 && (INTVAL (operands[2]) == 128
20859 || (INTVAL (operands[2]) < 0
20860 && INTVAL (operands[2]) != -128)))
20862 operands[2] = GEN_INT (-INTVAL (operands[2]));
20863 return "sub{q}\t{%2, %0|%0, %2}";
20865 return "add{q}\t{%2, %0|%0, %2}";
20868 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20869 return "lea{q}\t{%a2, %0|%0, %a2}";
20872 gcc_unreachable ();
20875 [(set (attr "type")
20876 (cond [(and (eq_attr "alternative" "0")
20877 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20878 (const_string "alu")
20879 (match_operand:DI 2 "const0_operand" "")
20880 (const_string "imov")
20882 (const_string "lea")))
20883 (set (attr "length_immediate")
20884 (cond [(eq_attr "type" "imov")
20886 (and (eq_attr "type" "alu")
20887 (match_operand 2 "const128_operand" ""))
20890 (const_string "*")))
20891 (set_attr "mode" "DI")])
20893 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20894 [(set (match_operand:DI 0 "register_operand" "=r,r")
20895 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20896 (match_operand:DI 3 "immediate_operand" "i,i")))
20897 (use (match_operand:DI 2 "register_operand" "r,r"))
20898 (clobber (reg:CC FLAGS_REG))
20899 (clobber (mem:BLK (scratch)))]
20902 switch (get_attr_type (insn))
20905 return "add{q}\t{%2, %0|%0, %2}";
20908 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20909 return "lea{q}\t{%a2, %0|%0, %a2}";
20912 gcc_unreachable ();
20915 [(set_attr "type" "alu,lea")
20916 (set_attr "mode" "DI")])
20918 (define_insn "allocate_stack_worker_32"
20919 [(set (match_operand:SI 0 "register_operand" "=a")
20920 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20921 UNSPECV_STACK_PROBE))
20922 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20923 (clobber (reg:CC FLAGS_REG))]
20924 "!TARGET_64BIT && TARGET_STACK_PROBE"
20926 [(set_attr "type" "multi")
20927 (set_attr "length" "5")])
20929 (define_insn "allocate_stack_worker_64"
20930 [(set (match_operand:DI 0 "register_operand" "=a")
20931 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20932 UNSPECV_STACK_PROBE))
20933 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20934 (clobber (reg:DI R10_REG))
20935 (clobber (reg:DI R11_REG))
20936 (clobber (reg:CC FLAGS_REG))]
20937 "TARGET_64BIT && TARGET_STACK_PROBE"
20939 [(set_attr "type" "multi")
20940 (set_attr "length" "5")])
20942 (define_expand "allocate_stack"
20943 [(match_operand 0 "register_operand" "")
20944 (match_operand 1 "general_operand" "")]
20945 "TARGET_STACK_PROBE"
20949 #ifndef CHECK_STACK_LIMIT
20950 #define CHECK_STACK_LIMIT 0
20953 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20954 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20956 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20957 stack_pointer_rtx, 0, OPTAB_DIRECT);
20958 if (x != stack_pointer_rtx)
20959 emit_move_insn (stack_pointer_rtx, x);
20963 x = copy_to_mode_reg (Pmode, operands[1]);
20965 x = gen_allocate_stack_worker_64 (x, x);
20967 x = gen_allocate_stack_worker_32 (x, x);
20971 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20975 (define_expand "builtin_setjmp_receiver"
20976 [(label_ref (match_operand 0 "" ""))]
20977 "!TARGET_64BIT && flag_pic"
20983 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20984 rtx label_rtx = gen_label_rtx ();
20985 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20986 xops[0] = xops[1] = picreg;
20987 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20988 ix86_expand_binary_operator (MINUS, SImode, xops);
20992 emit_insn (gen_set_got (pic_offset_table_rtx));
20996 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20999 [(set (match_operand 0 "register_operand" "")
21000 (match_operator 3 "promotable_binary_operator"
21001 [(match_operand 1 "register_operand" "")
21002 (match_operand 2 "aligned_operand" "")]))
21003 (clobber (reg:CC FLAGS_REG))]
21004 "! TARGET_PARTIAL_REG_STALL && reload_completed
21005 && ((GET_MODE (operands[0]) == HImode
21006 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
21007 /* ??? next two lines just !satisfies_constraint_K (...) */
21008 || !CONST_INT_P (operands[2])
21009 || satisfies_constraint_K (operands[2])))
21010 || (GET_MODE (operands[0]) == QImode
21011 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21012 [(parallel [(set (match_dup 0)
21013 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21014 (clobber (reg:CC FLAGS_REG))])]
21015 "operands[0] = gen_lowpart (SImode, operands[0]);
21016 operands[1] = gen_lowpart (SImode, operands[1]);
21017 if (GET_CODE (operands[3]) != ASHIFT)
21018 operands[2] = gen_lowpart (SImode, operands[2]);
21019 PUT_MODE (operands[3], SImode);")
21021 ; Promote the QImode tests, as i386 has encoding of the AND
21022 ; instruction with 32-bit sign-extended immediate and thus the
21023 ; instruction size is unchanged, except in the %eax case for
21024 ; which it is increased by one byte, hence the ! optimize_size.
21026 [(set (match_operand 0 "flags_reg_operand" "")
21027 (match_operator 2 "compare_operator"
21028 [(and (match_operand 3 "aligned_operand" "")
21029 (match_operand 4 "const_int_operand" ""))
21031 (set (match_operand 1 "register_operand" "")
21032 (and (match_dup 3) (match_dup 4)))]
21033 "! TARGET_PARTIAL_REG_STALL && reload_completed
21034 && optimize_insn_for_speed_p ()
21035 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21036 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21037 /* Ensure that the operand will remain sign-extended immediate. */
21038 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21039 [(parallel [(set (match_dup 0)
21040 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21043 (and:SI (match_dup 3) (match_dup 4)))])]
21046 = gen_int_mode (INTVAL (operands[4])
21047 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21048 operands[1] = gen_lowpart (SImode, operands[1]);
21049 operands[3] = gen_lowpart (SImode, operands[3]);
21052 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21053 ; the TEST instruction with 32-bit sign-extended immediate and thus
21054 ; the instruction size would at least double, which is not what we
21055 ; want even with ! optimize_size.
21057 [(set (match_operand 0 "flags_reg_operand" "")
21058 (match_operator 1 "compare_operator"
21059 [(and (match_operand:HI 2 "aligned_operand" "")
21060 (match_operand:HI 3 "const_int_operand" ""))
21062 "! TARGET_PARTIAL_REG_STALL && reload_completed
21063 && ! TARGET_FAST_PREFIX
21064 && optimize_insn_for_speed_p ()
21065 /* Ensure that the operand will remain sign-extended immediate. */
21066 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21067 [(set (match_dup 0)
21068 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21072 = gen_int_mode (INTVAL (operands[3])
21073 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21074 operands[2] = gen_lowpart (SImode, operands[2]);
21078 [(set (match_operand 0 "register_operand" "")
21079 (neg (match_operand 1 "register_operand" "")))
21080 (clobber (reg:CC FLAGS_REG))]
21081 "! TARGET_PARTIAL_REG_STALL && reload_completed
21082 && (GET_MODE (operands[0]) == HImode
21083 || (GET_MODE (operands[0]) == QImode
21084 && (TARGET_PROMOTE_QImode
21085 || optimize_insn_for_size_p ())))"
21086 [(parallel [(set (match_dup 0)
21087 (neg:SI (match_dup 1)))
21088 (clobber (reg:CC FLAGS_REG))])]
21089 "operands[0] = gen_lowpart (SImode, operands[0]);
21090 operands[1] = gen_lowpart (SImode, operands[1]);")
21093 [(set (match_operand 0 "register_operand" "")
21094 (not (match_operand 1 "register_operand" "")))]
21095 "! TARGET_PARTIAL_REG_STALL && reload_completed
21096 && (GET_MODE (operands[0]) == HImode
21097 || (GET_MODE (operands[0]) == QImode
21098 && (TARGET_PROMOTE_QImode
21099 || optimize_insn_for_size_p ())))"
21100 [(set (match_dup 0)
21101 (not:SI (match_dup 1)))]
21102 "operands[0] = gen_lowpart (SImode, operands[0]);
21103 operands[1] = gen_lowpart (SImode, operands[1]);")
21106 [(set (match_operand 0 "register_operand" "")
21107 (if_then_else (match_operator 1 "comparison_operator"
21108 [(reg FLAGS_REG) (const_int 0)])
21109 (match_operand 2 "register_operand" "")
21110 (match_operand 3 "register_operand" "")))]
21111 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21112 && (GET_MODE (operands[0]) == HImode
21113 || (GET_MODE (operands[0]) == QImode
21114 && (TARGET_PROMOTE_QImode
21115 || optimize_insn_for_size_p ())))"
21116 [(set (match_dup 0)
21117 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21118 "operands[0] = gen_lowpart (SImode, operands[0]);
21119 operands[2] = gen_lowpart (SImode, operands[2]);
21120 operands[3] = gen_lowpart (SImode, operands[3]);")
21123 ;; RTL Peephole optimizations, run before sched2. These primarily look to
21124 ;; transform a complex memory operation into two memory to register operations.
21126 ;; Don't push memory operands
21128 [(set (match_operand:SI 0 "push_operand" "")
21129 (match_operand:SI 1 "memory_operand" ""))
21130 (match_scratch:SI 2 "r")]
21131 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21132 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21133 [(set (match_dup 2) (match_dup 1))
21134 (set (match_dup 0) (match_dup 2))]
21138 [(set (match_operand:DI 0 "push_operand" "")
21139 (match_operand:DI 1 "memory_operand" ""))
21140 (match_scratch:DI 2 "r")]
21141 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21142 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21143 [(set (match_dup 2) (match_dup 1))
21144 (set (match_dup 0) (match_dup 2))]
21147 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21150 [(set (match_operand:SF 0 "push_operand" "")
21151 (match_operand:SF 1 "memory_operand" ""))
21152 (match_scratch:SF 2 "r")]
21153 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21154 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21155 [(set (match_dup 2) (match_dup 1))
21156 (set (match_dup 0) (match_dup 2))]
21160 [(set (match_operand:HI 0 "push_operand" "")
21161 (match_operand:HI 1 "memory_operand" ""))
21162 (match_scratch:HI 2 "r")]
21163 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21164 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21165 [(set (match_dup 2) (match_dup 1))
21166 (set (match_dup 0) (match_dup 2))]
21170 [(set (match_operand:QI 0 "push_operand" "")
21171 (match_operand:QI 1 "memory_operand" ""))
21172 (match_scratch:QI 2 "q")]
21173 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21174 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21175 [(set (match_dup 2) (match_dup 1))
21176 (set (match_dup 0) (match_dup 2))]
21179 ;; Don't move an immediate directly to memory when the instruction
21182 [(match_scratch:SI 1 "r")
21183 (set (match_operand:SI 0 "memory_operand" "")
21185 "optimize_insn_for_speed_p ()
21186 && ! TARGET_USE_MOV0
21187 && TARGET_SPLIT_LONG_MOVES
21188 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21189 && peep2_regno_dead_p (0, FLAGS_REG)"
21190 [(parallel [(set (match_dup 1) (const_int 0))
21191 (clobber (reg:CC FLAGS_REG))])
21192 (set (match_dup 0) (match_dup 1))]
21196 [(match_scratch:HI 1 "r")
21197 (set (match_operand:HI 0 "memory_operand" "")
21199 "optimize_insn_for_speed_p ()
21200 && ! TARGET_USE_MOV0
21201 && TARGET_SPLIT_LONG_MOVES
21202 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21203 && peep2_regno_dead_p (0, FLAGS_REG)"
21204 [(parallel [(set (match_dup 2) (const_int 0))
21205 (clobber (reg:CC FLAGS_REG))])
21206 (set (match_dup 0) (match_dup 1))]
21207 "operands[2] = gen_lowpart (SImode, operands[1]);")
21210 [(match_scratch:QI 1 "q")
21211 (set (match_operand:QI 0 "memory_operand" "")
21213 "optimize_insn_for_speed_p ()
21214 && ! TARGET_USE_MOV0
21215 && TARGET_SPLIT_LONG_MOVES
21216 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21217 && peep2_regno_dead_p (0, FLAGS_REG)"
21218 [(parallel [(set (match_dup 2) (const_int 0))
21219 (clobber (reg:CC FLAGS_REG))])
21220 (set (match_dup 0) (match_dup 1))]
21221 "operands[2] = gen_lowpart (SImode, operands[1]);")
21224 [(match_scratch:SI 2 "r")
21225 (set (match_operand:SI 0 "memory_operand" "")
21226 (match_operand:SI 1 "immediate_operand" ""))]
21227 "optimize_insn_for_speed_p ()
21228 && TARGET_SPLIT_LONG_MOVES
21229 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21230 [(set (match_dup 2) (match_dup 1))
21231 (set (match_dup 0) (match_dup 2))]
21235 [(match_scratch:HI 2 "r")
21236 (set (match_operand:HI 0 "memory_operand" "")
21237 (match_operand:HI 1 "immediate_operand" ""))]
21238 "optimize_insn_for_speed_p ()
21239 && TARGET_SPLIT_LONG_MOVES
21240 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21241 [(set (match_dup 2) (match_dup 1))
21242 (set (match_dup 0) (match_dup 2))]
21246 [(match_scratch:QI 2 "q")
21247 (set (match_operand:QI 0 "memory_operand" "")
21248 (match_operand:QI 1 "immediate_operand" ""))]
21249 "optimize_insn_for_speed_p ()
21250 && TARGET_SPLIT_LONG_MOVES
21251 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21252 [(set (match_dup 2) (match_dup 1))
21253 (set (match_dup 0) (match_dup 2))]
21256 ;; Don't compare memory with zero, load and use a test instead.
21258 [(set (match_operand 0 "flags_reg_operand" "")
21259 (match_operator 1 "compare_operator"
21260 [(match_operand:SI 2 "memory_operand" "")
21262 (match_scratch:SI 3 "r")]
21263 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21264 [(set (match_dup 3) (match_dup 2))
21265 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21268 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21269 ;; Don't split NOTs with a displacement operand, because resulting XOR
21270 ;; will not be pairable anyway.
21272 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21273 ;; represented using a modRM byte. The XOR replacement is long decoded,
21274 ;; so this split helps here as well.
21276 ;; Note: Can't do this as a regular split because we can't get proper
21277 ;; lifetime information then.
21280 [(set (match_operand:SI 0 "nonimmediate_operand" "")
21281 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21282 "optimize_insn_for_speed_p ()
21283 && ((TARGET_NOT_UNPAIRABLE
21284 && (!MEM_P (operands[0])
21285 || !memory_displacement_operand (operands[0], SImode)))
21286 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21287 && peep2_regno_dead_p (0, FLAGS_REG)"
21288 [(parallel [(set (match_dup 0)
21289 (xor:SI (match_dup 1) (const_int -1)))
21290 (clobber (reg:CC FLAGS_REG))])]
21294 [(set (match_operand:HI 0 "nonimmediate_operand" "")
21295 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21296 "optimize_insn_for_speed_p ()
21297 && ((TARGET_NOT_UNPAIRABLE
21298 && (!MEM_P (operands[0])
21299 || !memory_displacement_operand (operands[0], HImode)))
21300 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21301 && peep2_regno_dead_p (0, FLAGS_REG)"
21302 [(parallel [(set (match_dup 0)
21303 (xor:HI (match_dup 1) (const_int -1)))
21304 (clobber (reg:CC FLAGS_REG))])]
21308 [(set (match_operand:QI 0 "nonimmediate_operand" "")
21309 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21310 "optimize_insn_for_speed_p ()
21311 && ((TARGET_NOT_UNPAIRABLE
21312 && (!MEM_P (operands[0])
21313 || !memory_displacement_operand (operands[0], QImode)))
21314 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21315 && peep2_regno_dead_p (0, FLAGS_REG)"
21316 [(parallel [(set (match_dup 0)
21317 (xor:QI (match_dup 1) (const_int -1)))
21318 (clobber (reg:CC FLAGS_REG))])]
21321 ;; Non pairable "test imm, reg" instructions can be translated to
21322 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
21323 ;; byte opcode instead of two, have a short form for byte operands),
21324 ;; so do it for other CPUs as well. Given that the value was dead,
21325 ;; this should not create any new dependencies. Pass on the sub-word
21326 ;; versions if we're concerned about partial register stalls.
21329 [(set (match_operand 0 "flags_reg_operand" "")
21330 (match_operator 1 "compare_operator"
21331 [(and:SI (match_operand:SI 2 "register_operand" "")
21332 (match_operand:SI 3 "immediate_operand" ""))
21334 "ix86_match_ccmode (insn, CCNOmode)
21335 && (true_regnum (operands[2]) != AX_REG
21336 || satisfies_constraint_K (operands[3]))
21337 && peep2_reg_dead_p (1, operands[2])"
21339 [(set (match_dup 0)
21340 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21343 (and:SI (match_dup 2) (match_dup 3)))])]
21346 ;; We don't need to handle HImode case, because it will be promoted to SImode
21347 ;; on ! TARGET_PARTIAL_REG_STALL
21350 [(set (match_operand 0 "flags_reg_operand" "")
21351 (match_operator 1 "compare_operator"
21352 [(and:QI (match_operand:QI 2 "register_operand" "")
21353 (match_operand:QI 3 "immediate_operand" ""))
21355 "! TARGET_PARTIAL_REG_STALL
21356 && ix86_match_ccmode (insn, CCNOmode)
21357 && true_regnum (operands[2]) != AX_REG
21358 && peep2_reg_dead_p (1, operands[2])"
21360 [(set (match_dup 0)
21361 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21364 (and:QI (match_dup 2) (match_dup 3)))])]
21368 [(set (match_operand 0 "flags_reg_operand" "")
21369 (match_operator 1 "compare_operator"
21372 (match_operand 2 "ext_register_operand" "")
21375 (match_operand 3 "const_int_operand" ""))
21377 "! TARGET_PARTIAL_REG_STALL
21378 && ix86_match_ccmode (insn, CCNOmode)
21379 && true_regnum (operands[2]) != AX_REG
21380 && peep2_reg_dead_p (1, operands[2])"
21381 [(parallel [(set (match_dup 0)
21390 (set (zero_extract:SI (match_dup 2)
21401 ;; Don't do logical operations with memory inputs.
21403 [(match_scratch:SI 2 "r")
21404 (parallel [(set (match_operand:SI 0 "register_operand" "")
21405 (match_operator:SI 3 "arith_or_logical_operator"
21407 (match_operand:SI 1 "memory_operand" "")]))
21408 (clobber (reg:CC FLAGS_REG))])]
21409 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21410 [(set (match_dup 2) (match_dup 1))
21411 (parallel [(set (match_dup 0)
21412 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21413 (clobber (reg:CC FLAGS_REG))])]
21417 [(match_scratch:SI 2 "r")
21418 (parallel [(set (match_operand:SI 0 "register_operand" "")
21419 (match_operator:SI 3 "arith_or_logical_operator"
21420 [(match_operand:SI 1 "memory_operand" "")
21422 (clobber (reg:CC FLAGS_REG))])]
21423 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21424 [(set (match_dup 2) (match_dup 1))
21425 (parallel [(set (match_dup 0)
21426 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21427 (clobber (reg:CC FLAGS_REG))])]
21430 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
21431 ;; refers to the destination of the load!
21434 [(set (match_operand:SI 0 "register_operand" "")
21435 (match_operand:SI 1 "register_operand" ""))
21436 (parallel [(set (match_dup 0)
21437 (match_operator:SI 3 "commutative_operator"
21439 (match_operand:SI 2 "memory_operand" "")]))
21440 (clobber (reg:CC FLAGS_REG))])]
21441 "REGNO (operands[0]) != REGNO (operands[1])
21442 && GENERAL_REGNO_P (REGNO (operands[0]))
21443 && GENERAL_REGNO_P (REGNO (operands[1]))"
21444 [(set (match_dup 0) (match_dup 4))
21445 (parallel [(set (match_dup 0)
21446 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21447 (clobber (reg:CC FLAGS_REG))])]
21448 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21451 [(set (match_operand 0 "register_operand" "")
21452 (match_operand 1 "register_operand" ""))
21454 (match_operator 3 "commutative_operator"
21456 (match_operand 2 "memory_operand" "")]))]
21457 "REGNO (operands[0]) != REGNO (operands[1])
21458 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
21459 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21460 [(set (match_dup 0) (match_dup 2))
21462 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21465 ; Don't do logical operations with memory outputs
21467 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21468 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
21469 ; the same decoder scheduling characteristics as the original.
21472 [(match_scratch:SI 2 "r")
21473 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21474 (match_operator:SI 3 "arith_or_logical_operator"
21476 (match_operand:SI 1 "nonmemory_operand" "")]))
21477 (clobber (reg:CC FLAGS_REG))])]
21478 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21479 [(set (match_dup 2) (match_dup 0))
21480 (parallel [(set (match_dup 2)
21481 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21482 (clobber (reg:CC FLAGS_REG))])
21483 (set (match_dup 0) (match_dup 2))]
21487 [(match_scratch:SI 2 "r")
21488 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21489 (match_operator:SI 3 "arith_or_logical_operator"
21490 [(match_operand:SI 1 "nonmemory_operand" "")
21492 (clobber (reg:CC FLAGS_REG))])]
21493 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21494 [(set (match_dup 2) (match_dup 0))
21495 (parallel [(set (match_dup 2)
21496 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21497 (clobber (reg:CC FLAGS_REG))])
21498 (set (match_dup 0) (match_dup 2))]
21501 ;; Attempt to always use XOR for zeroing registers.
21503 [(set (match_operand 0 "register_operand" "")
21504 (match_operand 1 "const0_operand" ""))]
21505 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21506 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21507 && GENERAL_REG_P (operands[0])
21508 && peep2_regno_dead_p (0, FLAGS_REG)"
21509 [(parallel [(set (match_dup 0) (const_int 0))
21510 (clobber (reg:CC FLAGS_REG))])]
21512 operands[0] = gen_lowpart (word_mode, operands[0]);
21516 [(set (strict_low_part (match_operand 0 "register_operand" ""))
21518 "(GET_MODE (operands[0]) == QImode
21519 || GET_MODE (operands[0]) == HImode)
21520 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21521 && peep2_regno_dead_p (0, FLAGS_REG)"
21522 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21523 (clobber (reg:CC FLAGS_REG))])])
21525 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21527 [(set (match_operand 0 "register_operand" "")
21529 "(GET_MODE (operands[0]) == HImode
21530 || GET_MODE (operands[0]) == SImode
21531 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21532 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21533 && peep2_regno_dead_p (0, FLAGS_REG)"
21534 [(parallel [(set (match_dup 0) (const_int -1))
21535 (clobber (reg:CC FLAGS_REG))])]
21536 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21539 ;; Attempt to convert simple leas to adds. These can be created by
21542 [(set (match_operand:SI 0 "register_operand" "")
21543 (plus:SI (match_dup 0)
21544 (match_operand:SI 1 "nonmemory_operand" "")))]
21545 "peep2_regno_dead_p (0, FLAGS_REG)"
21546 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21547 (clobber (reg:CC FLAGS_REG))])]
21551 [(set (match_operand:SI 0 "register_operand" "")
21552 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21553 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21554 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21555 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21556 (clobber (reg:CC FLAGS_REG))])]
21557 "operands[2] = gen_lowpart (SImode, operands[2]);")
21560 [(set (match_operand:DI 0 "register_operand" "")
21561 (plus:DI (match_dup 0)
21562 (match_operand:DI 1 "x86_64_general_operand" "")))]
21563 "peep2_regno_dead_p (0, FLAGS_REG)"
21564 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21565 (clobber (reg:CC FLAGS_REG))])]
21569 [(set (match_operand:SI 0 "register_operand" "")
21570 (mult:SI (match_dup 0)
21571 (match_operand:SI 1 "const_int_operand" "")))]
21572 "exact_log2 (INTVAL (operands[1])) >= 0
21573 && peep2_regno_dead_p (0, FLAGS_REG)"
21574 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21575 (clobber (reg:CC FLAGS_REG))])]
21576 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21579 [(set (match_operand:DI 0 "register_operand" "")
21580 (mult:DI (match_dup 0)
21581 (match_operand:DI 1 "const_int_operand" "")))]
21582 "exact_log2 (INTVAL (operands[1])) >= 0
21583 && peep2_regno_dead_p (0, FLAGS_REG)"
21584 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21585 (clobber (reg:CC FLAGS_REG))])]
21586 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21589 [(set (match_operand:SI 0 "register_operand" "")
21590 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21591 (match_operand:DI 2 "const_int_operand" "")) 0))]
21592 "exact_log2 (INTVAL (operands[2])) >= 0
21593 && REGNO (operands[0]) == REGNO (operands[1])
21594 && peep2_regno_dead_p (0, FLAGS_REG)"
21595 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21596 (clobber (reg:CC FLAGS_REG))])]
21597 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21599 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21600 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21601 ;; many CPUs it is also faster, since special hardware to avoid esp
21602 ;; dependencies is present.
21604 ;; While some of these conversions may be done using splitters, we use peepholes
21605 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21607 ;; Convert prologue esp subtractions to push.
21608 ;; We need register to push. In order to keep verify_flow_info happy we have
21610 ;; - use scratch and clobber it in order to avoid dependencies
21611 ;; - use already live register
21612 ;; We can't use the second way right now, since there is no reliable way how to
21613 ;; verify that given register is live. First choice will also most likely in
21614 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21615 ;; call clobbered registers are dead. We may want to use base pointer as an
21616 ;; alternative when no register is available later.
21619 [(match_scratch:SI 0 "r")
21620 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21621 (clobber (reg:CC FLAGS_REG))
21622 (clobber (mem:BLK (scratch)))])]
21623 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21624 [(clobber (match_dup 0))
21625 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21626 (clobber (mem:BLK (scratch)))])])
21629 [(match_scratch:SI 0 "r")
21630 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21631 (clobber (reg:CC FLAGS_REG))
21632 (clobber (mem:BLK (scratch)))])]
21633 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21634 [(clobber (match_dup 0))
21635 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21636 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21637 (clobber (mem:BLK (scratch)))])])
21639 ;; Convert esp subtractions to push.
21641 [(match_scratch:SI 0 "r")
21642 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21643 (clobber (reg:CC FLAGS_REG))])]
21644 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21645 [(clobber (match_dup 0))
21646 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21649 [(match_scratch:SI 0 "r")
21650 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21651 (clobber (reg:CC FLAGS_REG))])]
21652 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21653 [(clobber (match_dup 0))
21654 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21655 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21657 ;; Convert epilogue deallocator to pop.
21659 [(match_scratch:SI 0 "r")
21660 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21661 (clobber (reg:CC FLAGS_REG))
21662 (clobber (mem:BLK (scratch)))])]
21663 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21664 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21665 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21666 (clobber (mem:BLK (scratch)))])]
21669 ;; Two pops case is tricky, since pop causes dependency on destination register.
21670 ;; We use two registers if available.
21672 [(match_scratch:SI 0 "r")
21673 (match_scratch:SI 1 "r")
21674 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21675 (clobber (reg:CC FLAGS_REG))
21676 (clobber (mem:BLK (scratch)))])]
21677 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21678 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21679 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21680 (clobber (mem:BLK (scratch)))])
21681 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21682 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21686 [(match_scratch:SI 0 "r")
21687 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21688 (clobber (reg:CC FLAGS_REG))
21689 (clobber (mem:BLK (scratch)))])]
21690 "optimize_insn_for_size_p ()"
21691 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21692 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21693 (clobber (mem:BLK (scratch)))])
21694 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21695 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21698 ;; Convert esp additions to pop.
21700 [(match_scratch:SI 0 "r")
21701 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21702 (clobber (reg:CC FLAGS_REG))])]
21704 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21705 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21708 ;; Two pops case is tricky, since pop causes dependency on destination register.
21709 ;; We use two registers if available.
21711 [(match_scratch:SI 0 "r")
21712 (match_scratch:SI 1 "r")
21713 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21714 (clobber (reg:CC FLAGS_REG))])]
21716 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21717 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21718 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21723 [(match_scratch:SI 0 "r")
21724 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21725 (clobber (reg:CC FLAGS_REG))])]
21726 "optimize_insn_for_size_p ()"
21727 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21728 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21729 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21730 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21733 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21734 ;; required and register dies. Similarly for 128 to -128.
21736 [(set (match_operand 0 "flags_reg_operand" "")
21737 (match_operator 1 "compare_operator"
21738 [(match_operand 2 "register_operand" "")
21739 (match_operand 3 "const_int_operand" "")]))]
21740 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21741 && incdec_operand (operands[3], GET_MODE (operands[3])))
21742 || (!TARGET_FUSE_CMP_AND_BRANCH
21743 && INTVAL (operands[3]) == 128))
21744 && ix86_match_ccmode (insn, CCGCmode)
21745 && peep2_reg_dead_p (1, operands[2])"
21746 [(parallel [(set (match_dup 0)
21747 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21748 (clobber (match_dup 2))])]
21752 [(match_scratch:DI 0 "r")
21753 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21754 (clobber (reg:CC FLAGS_REG))
21755 (clobber (mem:BLK (scratch)))])]
21756 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21757 [(clobber (match_dup 0))
21758 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21759 (clobber (mem:BLK (scratch)))])])
21762 [(match_scratch:DI 0 "r")
21763 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21764 (clobber (reg:CC FLAGS_REG))
21765 (clobber (mem:BLK (scratch)))])]
21766 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21767 [(clobber (match_dup 0))
21768 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21769 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21770 (clobber (mem:BLK (scratch)))])])
21772 ;; Convert esp subtractions to push.
21774 [(match_scratch:DI 0 "r")
21775 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21776 (clobber (reg:CC FLAGS_REG))])]
21777 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21778 [(clobber (match_dup 0))
21779 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21782 [(match_scratch:DI 0 "r")
21783 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21784 (clobber (reg:CC FLAGS_REG))])]
21785 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21786 [(clobber (match_dup 0))
21787 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21788 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21790 ;; Convert epilogue deallocator to pop.
21792 [(match_scratch:DI 0 "r")
21793 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21794 (clobber (reg:CC FLAGS_REG))
21795 (clobber (mem:BLK (scratch)))])]
21796 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21797 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21798 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21799 (clobber (mem:BLK (scratch)))])]
21802 ;; Two pops case is tricky, since pop causes dependency on destination register.
21803 ;; We use two registers if available.
21805 [(match_scratch:DI 0 "r")
21806 (match_scratch:DI 1 "r")
21807 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21808 (clobber (reg:CC FLAGS_REG))
21809 (clobber (mem:BLK (scratch)))])]
21810 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21811 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21812 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21813 (clobber (mem:BLK (scratch)))])
21814 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21815 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21819 [(match_scratch:DI 0 "r")
21820 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21821 (clobber (reg:CC FLAGS_REG))
21822 (clobber (mem:BLK (scratch)))])]
21823 "optimize_insn_for_size_p ()"
21824 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21825 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21826 (clobber (mem:BLK (scratch)))])
21827 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21828 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21831 ;; Convert esp additions to pop.
21833 [(match_scratch:DI 0 "r")
21834 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21835 (clobber (reg:CC FLAGS_REG))])]
21837 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21838 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21841 ;; Two pops case is tricky, since pop causes dependency on destination register.
21842 ;; We use two registers if available.
21844 [(match_scratch:DI 0 "r")
21845 (match_scratch:DI 1 "r")
21846 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21847 (clobber (reg:CC FLAGS_REG))])]
21849 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21850 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21851 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21856 [(match_scratch:DI 0 "r")
21857 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21858 (clobber (reg:CC FLAGS_REG))])]
21859 "optimize_insn_for_size_p ()"
21860 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21861 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21862 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21863 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21866 ;; Convert imul by three, five and nine into lea
21869 [(set (match_operand:SI 0 "register_operand" "")
21870 (mult:SI (match_operand:SI 1 "register_operand" "")
21871 (match_operand:SI 2 "const_int_operand" "")))
21872 (clobber (reg:CC FLAGS_REG))])]
21873 "INTVAL (operands[2]) == 3
21874 || INTVAL (operands[2]) == 5
21875 || INTVAL (operands[2]) == 9"
21876 [(set (match_dup 0)
21877 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21879 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21883 [(set (match_operand:SI 0 "register_operand" "")
21884 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21885 (match_operand:SI 2 "const_int_operand" "")))
21886 (clobber (reg:CC FLAGS_REG))])]
21887 "optimize_insn_for_speed_p ()
21888 && (INTVAL (operands[2]) == 3
21889 || INTVAL (operands[2]) == 5
21890 || INTVAL (operands[2]) == 9)"
21891 [(set (match_dup 0) (match_dup 1))
21893 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21895 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21899 [(set (match_operand:DI 0 "register_operand" "")
21900 (mult:DI (match_operand:DI 1 "register_operand" "")
21901 (match_operand:DI 2 "const_int_operand" "")))
21902 (clobber (reg:CC FLAGS_REG))])]
21904 && (INTVAL (operands[2]) == 3
21905 || INTVAL (operands[2]) == 5
21906 || INTVAL (operands[2]) == 9)"
21907 [(set (match_dup 0)
21908 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21910 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21914 [(set (match_operand:DI 0 "register_operand" "")
21915 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21916 (match_operand:DI 2 "const_int_operand" "")))
21917 (clobber (reg:CC FLAGS_REG))])]
21919 && optimize_insn_for_speed_p ()
21920 && (INTVAL (operands[2]) == 3
21921 || INTVAL (operands[2]) == 5
21922 || INTVAL (operands[2]) == 9)"
21923 [(set (match_dup 0) (match_dup 1))
21925 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21927 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21929 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21930 ;; imul $32bit_imm, reg, reg is direct decoded.
21932 [(match_scratch:DI 3 "r")
21933 (parallel [(set (match_operand:DI 0 "register_operand" "")
21934 (mult:DI (match_operand:DI 1 "memory_operand" "")
21935 (match_operand:DI 2 "immediate_operand" "")))
21936 (clobber (reg:CC FLAGS_REG))])]
21937 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21938 && !satisfies_constraint_K (operands[2])"
21939 [(set (match_dup 3) (match_dup 1))
21940 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21941 (clobber (reg:CC FLAGS_REG))])]
21945 [(match_scratch:SI 3 "r")
21946 (parallel [(set (match_operand:SI 0 "register_operand" "")
21947 (mult:SI (match_operand:SI 1 "memory_operand" "")
21948 (match_operand:SI 2 "immediate_operand" "")))
21949 (clobber (reg:CC FLAGS_REG))])]
21950 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21951 && !satisfies_constraint_K (operands[2])"
21952 [(set (match_dup 3) (match_dup 1))
21953 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21954 (clobber (reg:CC FLAGS_REG))])]
21958 [(match_scratch:SI 3 "r")
21959 (parallel [(set (match_operand:DI 0 "register_operand" "")
21961 (mult:SI (match_operand:SI 1 "memory_operand" "")
21962 (match_operand:SI 2 "immediate_operand" ""))))
21963 (clobber (reg:CC FLAGS_REG))])]
21964 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21965 && !satisfies_constraint_K (operands[2])"
21966 [(set (match_dup 3) (match_dup 1))
21967 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21968 (clobber (reg:CC FLAGS_REG))])]
21971 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21972 ;; Convert it into imul reg, reg
21973 ;; It would be better to force assembler to encode instruction using long
21974 ;; immediate, but there is apparently no way to do so.
21976 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21977 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21978 (match_operand:DI 2 "const_int_operand" "")))
21979 (clobber (reg:CC FLAGS_REG))])
21980 (match_scratch:DI 3 "r")]
21981 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21982 && satisfies_constraint_K (operands[2])"
21983 [(set (match_dup 3) (match_dup 2))
21984 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21985 (clobber (reg:CC FLAGS_REG))])]
21987 if (!rtx_equal_p (operands[0], operands[1]))
21988 emit_move_insn (operands[0], operands[1]);
21992 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21993 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21994 (match_operand:SI 2 "const_int_operand" "")))
21995 (clobber (reg:CC FLAGS_REG))])
21996 (match_scratch:SI 3 "r")]
21997 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21998 && satisfies_constraint_K (operands[2])"
21999 [(set (match_dup 3) (match_dup 2))
22000 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
22001 (clobber (reg:CC FLAGS_REG))])]
22003 if (!rtx_equal_p (operands[0], operands[1]))
22004 emit_move_insn (operands[0], operands[1]);
22008 [(parallel [(set (match_operand:HI 0 "register_operand" "")
22009 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22010 (match_operand:HI 2 "immediate_operand" "")))
22011 (clobber (reg:CC FLAGS_REG))])
22012 (match_scratch:HI 3 "r")]
22013 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22014 [(set (match_dup 3) (match_dup 2))
22015 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22016 (clobber (reg:CC FLAGS_REG))])]
22018 if (!rtx_equal_p (operands[0], operands[1]))
22019 emit_move_insn (operands[0], operands[1]);
22022 ;; After splitting up read-modify operations, array accesses with memory
22023 ;; operands might end up in form:
22025 ;; movl 4(%esp), %edx
22027 ;; instead of pre-splitting:
22029 ;; addl 4(%esp), %eax
22031 ;; movl 4(%esp), %edx
22032 ;; leal (%edx,%eax,4), %eax
22035 [(parallel [(set (match_operand 0 "register_operand" "")
22036 (ashift (match_operand 1 "register_operand" "")
22037 (match_operand 2 "const_int_operand" "")))
22038 (clobber (reg:CC FLAGS_REG))])
22039 (set (match_operand 3 "register_operand")
22040 (match_operand 4 "x86_64_general_operand" ""))
22041 (parallel [(set (match_operand 5 "register_operand" "")
22042 (plus (match_operand 6 "register_operand" "")
22043 (match_operand 7 "register_operand" "")))
22044 (clobber (reg:CC FLAGS_REG))])]
22045 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22046 /* Validate MODE for lea. */
22047 && ((!TARGET_PARTIAL_REG_STALL
22048 && (GET_MODE (operands[0]) == QImode
22049 || GET_MODE (operands[0]) == HImode))
22050 || GET_MODE (operands[0]) == SImode
22051 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22052 /* We reorder load and the shift. */
22053 && !rtx_equal_p (operands[1], operands[3])
22054 && !reg_overlap_mentioned_p (operands[0], operands[4])
22055 /* Last PLUS must consist of operand 0 and 3. */
22056 && !rtx_equal_p (operands[0], operands[3])
22057 && (rtx_equal_p (operands[3], operands[6])
22058 || rtx_equal_p (operands[3], operands[7]))
22059 && (rtx_equal_p (operands[0], operands[6])
22060 || rtx_equal_p (operands[0], operands[7]))
22061 /* The intermediate operand 0 must die or be same as output. */
22062 && (rtx_equal_p (operands[0], operands[5])
22063 || peep2_reg_dead_p (3, operands[0]))"
22064 [(set (match_dup 3) (match_dup 4))
22065 (set (match_dup 0) (match_dup 1))]
22067 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22068 int scale = 1 << INTVAL (operands[2]);
22069 rtx index = gen_lowpart (Pmode, operands[1]);
22070 rtx base = gen_lowpart (Pmode, operands[3]);
22071 rtx dest = gen_lowpart (mode, operands[5]);
22073 operands[1] = gen_rtx_PLUS (Pmode, base,
22074 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22076 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22077 operands[0] = dest;
22080 ;; Call-value patterns last so that the wildcard operand does not
22081 ;; disrupt insn-recog's switch tables.
22083 (define_insn "*call_value_pop_0"
22084 [(set (match_operand 0 "" "")
22085 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22086 (match_operand:SI 2 "" "")))
22087 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22088 (match_operand:SI 3 "immediate_operand" "")))]
22091 if (SIBLING_CALL_P (insn))
22094 return "call\t%P1";
22096 [(set_attr "type" "callv")])
22098 (define_insn "*call_value_pop_1"
22099 [(set (match_operand 0 "" "")
22100 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22101 (match_operand:SI 2 "" "")))
22102 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22103 (match_operand:SI 3 "immediate_operand" "i")))]
22106 if (constant_call_address_operand (operands[1], Pmode))
22108 if (SIBLING_CALL_P (insn))
22111 return "call\t%P1";
22113 if (SIBLING_CALL_P (insn))
22116 return "call\t%A1";
22118 [(set_attr "type" "callv")])
22120 (define_insn "*call_value_0"
22121 [(set (match_operand 0 "" "")
22122 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22123 (match_operand:SI 2 "" "")))]
22126 if (SIBLING_CALL_P (insn))
22129 return "call\t%P1";
22131 [(set_attr "type" "callv")])
22133 (define_insn "*call_value_0_rex64"
22134 [(set (match_operand 0 "" "")
22135 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22136 (match_operand:DI 2 "const_int_operand" "")))]
22139 if (SIBLING_CALL_P (insn))
22142 return "call\t%P1";
22144 [(set_attr "type" "callv")])
22146 (define_insn "*call_value_0_rex64_ms_sysv"
22147 [(set (match_operand 0 "" "")
22148 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22149 (match_operand:DI 2 "const_int_operand" "")))
22150 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22151 (clobber (reg:TI XMM6_REG))
22152 (clobber (reg:TI XMM7_REG))
22153 (clobber (reg:TI XMM8_REG))
22154 (clobber (reg:TI XMM9_REG))
22155 (clobber (reg:TI XMM10_REG))
22156 (clobber (reg:TI XMM11_REG))
22157 (clobber (reg:TI XMM12_REG))
22158 (clobber (reg:TI XMM13_REG))
22159 (clobber (reg:TI XMM14_REG))
22160 (clobber (reg:TI XMM15_REG))
22161 (clobber (reg:DI SI_REG))
22162 (clobber (reg:DI DI_REG))]
22163 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22165 if (SIBLING_CALL_P (insn))
22168 return "call\t%P1";
22170 [(set_attr "type" "callv")])
22172 (define_insn "*call_value_1"
22173 [(set (match_operand 0 "" "")
22174 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22175 (match_operand:SI 2 "" "")))]
22176 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22178 if (constant_call_address_operand (operands[1], Pmode))
22179 return "call\t%P1";
22180 return "call\t%A1";
22182 [(set_attr "type" "callv")])
22184 (define_insn "*sibcall_value_1"
22185 [(set (match_operand 0 "" "")
22186 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
22187 (match_operand:SI 2 "" "")))]
22188 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22190 if (constant_call_address_operand (operands[1], Pmode))
22194 [(set_attr "type" "callv")])
22196 (define_insn "*call_value_1_rex64"
22197 [(set (match_operand 0 "" "")
22198 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22199 (match_operand:DI 2 "" "")))]
22200 "!SIBLING_CALL_P (insn) && TARGET_64BIT
22201 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22203 if (constant_call_address_operand (operands[1], Pmode))
22204 return "call\t%P1";
22205 return "call\t%A1";
22207 [(set_attr "type" "callv")])
22209 (define_insn "*call_value_1_rex64_ms_sysv"
22210 [(set (match_operand 0 "" "")
22211 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22212 (match_operand:DI 2 "" "")))
22213 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22214 (clobber (reg:TI 27))
22215 (clobber (reg:TI 28))
22216 (clobber (reg:TI 45))
22217 (clobber (reg:TI 46))
22218 (clobber (reg:TI 47))
22219 (clobber (reg:TI 48))
22220 (clobber (reg:TI 49))
22221 (clobber (reg:TI 50))
22222 (clobber (reg:TI 51))
22223 (clobber (reg:TI 52))
22224 (clobber (reg:DI SI_REG))
22225 (clobber (reg:DI DI_REG))]
22226 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22228 if (constant_call_address_operand (operands[1], Pmode))
22229 return "call\t%P1";
22230 return "call\t%A1";
22232 [(set_attr "type" "callv")])
22234 (define_insn "*call_value_1_rex64_large"
22235 [(set (match_operand 0 "" "")
22236 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22237 (match_operand:DI 2 "" "")))]
22238 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22240 [(set_attr "type" "callv")])
22242 (define_insn "*sibcall_value_1_rex64"
22243 [(set (match_operand 0 "" "")
22244 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22245 (match_operand:DI 2 "" "")))]
22246 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22248 [(set_attr "type" "callv")])
22250 (define_insn "*sibcall_value_1_rex64_v"
22251 [(set (match_operand 0 "" "")
22252 (call (mem:QI (reg:DI R11_REG))
22253 (match_operand:DI 1 "" "")))]
22254 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22256 [(set_attr "type" "callv")])
22258 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22259 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22260 ;; caught for use by garbage collectors and the like. Using an insn that
22261 ;; maps to SIGILL makes it more likely the program will rightfully die.
22262 ;; Keeping with tradition, "6" is in honor of #UD.
22263 (define_insn "trap"
22264 [(trap_if (const_int 1) (const_int 6))]
22266 { return ASM_SHORT "0x0b0f"; }
22267 [(set_attr "length" "2")])
22269 (define_expand "sse_prologue_save"
22270 [(parallel [(set (match_operand:BLK 0 "" "")
22271 (unspec:BLK [(reg:DI 21)
22278 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22279 (use (match_operand:DI 1 "register_operand" ""))
22280 (use (match_operand:DI 2 "immediate_operand" ""))
22281 (use (label_ref:DI (match_operand 3 "" "")))])]
22285 (define_insn "*sse_prologue_save_insn"
22286 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22287 (match_operand:DI 4 "const_int_operand" "n")))
22288 (unspec:BLK [(reg:DI 21)
22295 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22296 (use (match_operand:DI 1 "register_operand" "r"))
22297 (use (match_operand:DI 2 "const_int_operand" "i"))
22298 (use (label_ref:DI (match_operand 3 "" "X")))]
22300 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22301 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22304 operands[0] = gen_rtx_MEM (Pmode,
22305 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22306 /* VEX instruction with a REX prefix will #UD. */
22307 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22308 gcc_unreachable ();
22310 output_asm_insn ("jmp\t%A1", operands);
22311 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22313 operands[4] = adjust_address (operands[0], DImode, i*16);
22314 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22315 PUT_MODE (operands[4], TImode);
22316 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22317 output_asm_insn ("rex", operands);
22318 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22320 (*targetm.asm_out.internal_label) (asm_out_file, "L",
22321 CODE_LABEL_NUMBER (operands[3]));
22324 [(set_attr "type" "other")
22325 (set_attr "length_immediate" "0")
22326 (set_attr "length_address" "0")
22327 (set (attr "length")
22329 (eq (symbol_ref "TARGET_AVX") (const_int 0))
22330 (const_string "34")
22331 (const_string "42")))
22332 (set_attr "memory" "store")
22333 (set_attr "modrm" "0")
22334 (set_attr "prefix" "maybe_vex")
22335 (set_attr "mode" "DI")])
22337 (define_expand "prefetch"
22338 [(prefetch (match_operand 0 "address_operand" "")
22339 (match_operand:SI 1 "const_int_operand" "")
22340 (match_operand:SI 2 "const_int_operand" ""))]
22341 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22343 int rw = INTVAL (operands[1]);
22344 int locality = INTVAL (operands[2]);
22346 gcc_assert (rw == 0 || rw == 1);
22347 gcc_assert (locality >= 0 && locality <= 3);
22348 gcc_assert (GET_MODE (operands[0]) == Pmode
22349 || GET_MODE (operands[0]) == VOIDmode);
22351 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22352 supported by SSE counterpart or the SSE prefetch is not available
22353 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22355 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22356 operands[2] = GEN_INT (3);
22358 operands[1] = const0_rtx;
22361 (define_insn "*prefetch_sse"
22362 [(prefetch (match_operand:SI 0 "address_operand" "p")
22364 (match_operand:SI 1 "const_int_operand" ""))]
22365 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22367 static const char * const patterns[4] = {
22368 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22371 int locality = INTVAL (operands[1]);
22372 gcc_assert (locality >= 0 && locality <= 3);
22374 return patterns[locality];
22376 [(set_attr "type" "sse")
22377 (set_attr "atom_sse_attr" "prefetch")
22378 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22379 (set_attr "memory" "none")])
22381 (define_insn "*prefetch_sse_rex"
22382 [(prefetch (match_operand:DI 0 "address_operand" "p")
22384 (match_operand:SI 1 "const_int_operand" ""))]
22385 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22387 static const char * const patterns[4] = {
22388 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22391 int locality = INTVAL (operands[1]);
22392 gcc_assert (locality >= 0 && locality <= 3);
22394 return patterns[locality];
22396 [(set_attr "type" "sse")
22397 (set_attr "atom_sse_attr" "prefetch")
22398 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22399 (set_attr "memory" "none")])
22401 (define_insn "*prefetch_3dnow"
22402 [(prefetch (match_operand:SI 0 "address_operand" "p")
22403 (match_operand:SI 1 "const_int_operand" "n")
22405 "TARGET_3DNOW && !TARGET_64BIT"
22407 if (INTVAL (operands[1]) == 0)
22408 return "prefetch\t%a0";
22410 return "prefetchw\t%a0";
22412 [(set_attr "type" "mmx")
22413 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22414 (set_attr "memory" "none")])
22416 (define_insn "*prefetch_3dnow_rex"
22417 [(prefetch (match_operand:DI 0 "address_operand" "p")
22418 (match_operand:SI 1 "const_int_operand" "n")
22420 "TARGET_3DNOW && TARGET_64BIT"
22422 if (INTVAL (operands[1]) == 0)
22423 return "prefetch\t%a0";
22425 return "prefetchw\t%a0";
22427 [(set_attr "type" "mmx")
22428 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22429 (set_attr "memory" "none")])
22431 (define_expand "stack_protect_set"
22432 [(match_operand 0 "memory_operand" "")
22433 (match_operand 1 "memory_operand" "")]
22436 #ifdef TARGET_THREAD_SSP_OFFSET
22438 emit_insn (gen_stack_tls_protect_set_di (operands[0],
22439 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22441 emit_insn (gen_stack_tls_protect_set_si (operands[0],
22442 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22445 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22447 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22452 (define_insn "stack_protect_set_si"
22453 [(set (match_operand:SI 0 "memory_operand" "=m")
22454 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22455 (set (match_scratch:SI 2 "=&r") (const_int 0))
22456 (clobber (reg:CC FLAGS_REG))]
22458 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22459 [(set_attr "type" "multi")])
22461 (define_insn "stack_protect_set_di"
22462 [(set (match_operand:DI 0 "memory_operand" "=m")
22463 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22464 (set (match_scratch:DI 2 "=&r") (const_int 0))
22465 (clobber (reg:CC FLAGS_REG))]
22467 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22468 [(set_attr "type" "multi")])
22470 (define_insn "stack_tls_protect_set_si"
22471 [(set (match_operand:SI 0 "memory_operand" "=m")
22472 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22473 (set (match_scratch:SI 2 "=&r") (const_int 0))
22474 (clobber (reg:CC FLAGS_REG))]
22476 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22477 [(set_attr "type" "multi")])
22479 (define_insn "stack_tls_protect_set_di"
22480 [(set (match_operand:DI 0 "memory_operand" "=m")
22481 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22482 (set (match_scratch:DI 2 "=&r") (const_int 0))
22483 (clobber (reg:CC FLAGS_REG))]
22486 /* The kernel uses a different segment register for performance reasons; a
22487 system call would not have to trash the userspace segment register,
22488 which would be expensive */
22489 if (ix86_cmodel != CM_KERNEL)
22490 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22492 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22494 [(set_attr "type" "multi")])
22496 (define_expand "stack_protect_test"
22497 [(match_operand 0 "memory_operand" "")
22498 (match_operand 1 "memory_operand" "")
22499 (match_operand 2 "" "")]
22502 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22504 #ifdef TARGET_THREAD_SSP_OFFSET
22506 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22507 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22509 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22510 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22513 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22515 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22518 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22519 flags, const0_rtx, operands[2]));
22523 (define_insn "stack_protect_test_si"
22524 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22525 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22526 (match_operand:SI 2 "memory_operand" "m")]
22528 (clobber (match_scratch:SI 3 "=&r"))]
22530 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22531 [(set_attr "type" "multi")])
22533 (define_insn "stack_protect_test_di"
22534 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22535 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22536 (match_operand:DI 2 "memory_operand" "m")]
22538 (clobber (match_scratch:DI 3 "=&r"))]
22540 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22541 [(set_attr "type" "multi")])
22543 (define_insn "stack_tls_protect_test_si"
22544 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22545 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22546 (match_operand:SI 2 "const_int_operand" "i")]
22547 UNSPEC_SP_TLS_TEST))
22548 (clobber (match_scratch:SI 3 "=r"))]
22550 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22551 [(set_attr "type" "multi")])
22553 (define_insn "stack_tls_protect_test_di"
22554 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22555 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22556 (match_operand:DI 2 "const_int_operand" "i")]
22557 UNSPEC_SP_TLS_TEST))
22558 (clobber (match_scratch:DI 3 "=r"))]
22561 /* The kernel uses a different segment register for performance reasons; a
22562 system call would not have to trash the userspace segment register,
22563 which would be expensive */
22564 if (ix86_cmodel != CM_KERNEL)
22565 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22567 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22569 [(set_attr "type" "multi")])
22571 (define_mode_iterator CRC32MODE [QI HI SI])
22572 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22573 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22575 (define_insn "sse4_2_crc32<mode>"
22576 [(set (match_operand:SI 0 "register_operand" "=r")
22578 [(match_operand:SI 1 "register_operand" "0")
22579 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22581 "TARGET_SSE4_2 || TARGET_CRC32"
22582 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22583 [(set_attr "type" "sselog1")
22584 (set_attr "prefix_rep" "1")
22585 (set_attr "prefix_extra" "1")
22586 (set (attr "prefix_data16")
22587 (if_then_else (match_operand:HI 2 "" "")
22589 (const_string "*")))
22590 (set (attr "prefix_rex")
22591 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22593 (const_string "*")))
22594 (set_attr "mode" "SI")])
22596 (define_insn "sse4_2_crc32di"
22597 [(set (match_operand:DI 0 "register_operand" "=r")
22599 [(match_operand:DI 1 "register_operand" "0")
22600 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22602 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22603 "crc32q\t{%2, %0|%0, %2}"
22604 [(set_attr "type" "sselog1")
22605 (set_attr "prefix_rep" "1")
22606 (set_attr "prefix_extra" "1")
22607 (set_attr "mode" "DI")])
22609 (define_expand "rdpmc"
22610 [(match_operand:DI 0 "register_operand" "")
22611 (match_operand:SI 1 "register_operand" "")]
22614 rtx reg = gen_reg_rtx (DImode);
22617 /* Force operand 1 into ECX. */
22618 rtx ecx = gen_rtx_REG (SImode, CX_REG);
22619 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
22620 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
22625 rtvec vec = rtvec_alloc (2);
22626 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22627 rtx upper = gen_reg_rtx (DImode);
22628 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22629 gen_rtvec (1, const0_rtx),
22631 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
22632 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22634 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22635 NULL, 1, OPTAB_DIRECT);
22636 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22640 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
22641 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22645 (define_insn "*rdpmc"
22646 [(set (match_operand:DI 0 "register_operand" "=A")
22647 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
22651 [(set_attr "type" "other")
22652 (set_attr "length" "2")])
22654 (define_insn "*rdpmc_rex64"
22655 [(set (match_operand:DI 0 "register_operand" "=a")
22656 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
22658 (set (match_operand:DI 1 "register_operand" "=d")
22659 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
22662 [(set_attr "type" "other")
22663 (set_attr "length" "2")])
22665 (define_expand "rdtsc"
22666 [(set (match_operand:DI 0 "register_operand" "")
22667 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22672 rtvec vec = rtvec_alloc (2);
22673 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22674 rtx upper = gen_reg_rtx (DImode);
22675 rtx lower = gen_reg_rtx (DImode);
22676 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
22677 gen_rtvec (1, const0_rtx),
22679 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
22680 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
22682 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22683 NULL, 1, OPTAB_DIRECT);
22684 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
22686 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
22691 (define_insn "*rdtsc"
22692 [(set (match_operand:DI 0 "register_operand" "=A")
22693 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22696 [(set_attr "type" "other")
22697 (set_attr "length" "2")])
22699 (define_insn "*rdtsc_rex64"
22700 [(set (match_operand:DI 0 "register_operand" "=a")
22701 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
22702 (set (match_operand:DI 1 "register_operand" "=d")
22703 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22706 [(set_attr "type" "other")
22707 (set_attr "length" "2")])
22709 (define_expand "rdtscp"
22710 [(match_operand:DI 0 "register_operand" "")
22711 (match_operand:SI 1 "memory_operand" "")]
22714 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22715 gen_rtvec (1, const0_rtx),
22717 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
22718 gen_rtvec (1, const0_rtx),
22720 rtx reg = gen_reg_rtx (DImode);
22721 rtx tmp = gen_reg_rtx (SImode);
22725 rtvec vec = rtvec_alloc (3);
22726 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22727 rtx upper = gen_reg_rtx (DImode);
22728 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22729 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22730 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22732 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22733 NULL, 1, OPTAB_DIRECT);
22734 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22739 rtvec vec = rtvec_alloc (2);
22740 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22741 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22742 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22745 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22746 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22750 (define_insn "*rdtscp"
22751 [(set (match_operand:DI 0 "register_operand" "=A")
22752 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22753 (set (match_operand:SI 1 "register_operand" "=c")
22754 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22757 [(set_attr "type" "other")
22758 (set_attr "length" "3")])
22760 (define_insn "*rdtscp_rex64"
22761 [(set (match_operand:DI 0 "register_operand" "=a")
22762 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22763 (set (match_operand:DI 1 "register_operand" "=d")
22764 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22765 (set (match_operand:SI 2 "register_operand" "=c")
22766 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22769 [(set_attr "type" "other")
22770 (set_attr "length" "3")])
22774 (include "sync.md")