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 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
66 [; Relocation specifiers
77 (UNSPEC_MACHOPIC_OFFSET 10)
80 (UNSPEC_STACK_ALLOC 11)
82 (UNSPEC_SSE_PROLOGUE_SAVE 13)
86 (UNSPEC_SET_GOT_OFFSET 17)
87 (UNSPEC_MEMORY_BLOCKAGE 18)
92 (UNSPEC_TLS_LD_BASE 22)
95 ; Other random patterns
100 (UNSPEC_ADD_CARRY 34)
103 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
104 (UNSPEC_TRUNC_NOOP 39)
106 ; For SSE/MMX support:
107 (UNSPEC_FIX_NOTRUNC 40)
124 (UNSPEC_MS_TO_SYSV_CALL 48)
126 ; Generic math support
128 (UNSPEC_IEEE_MIN 51) ; not commutative
129 (UNSPEC_IEEE_MAX 52) ; not commutative
144 (UNSPEC_FRNDINT_FLOOR 70)
145 (UNSPEC_FRNDINT_CEIL 71)
146 (UNSPEC_FRNDINT_TRUNC 72)
147 (UNSPEC_FRNDINT_MASK_PM 73)
148 (UNSPEC_FIST_FLOOR 74)
149 (UNSPEC_FIST_CEIL 75)
151 ; x87 Double output FP
152 (UNSPEC_SINCOS_COS 80)
153 (UNSPEC_SINCOS_SIN 81)
154 (UNSPEC_XTRACT_FRACT 84)
155 (UNSPEC_XTRACT_EXP 85)
156 (UNSPEC_FSCALE_FRACT 86)
157 (UNSPEC_FSCALE_EXP 87)
169 (UNSPEC_SP_TLS_SET 102)
170 (UNSPEC_SP_TLS_TEST 103)
180 (UNSPEC_INSERTQI 132)
185 (UNSPEC_INSERTPS 135)
187 (UNSPEC_MOVNTDQA 137)
189 (UNSPEC_PHMINPOSUW 139)
195 (UNSPEC_PCMPESTR 144)
196 (UNSPEC_PCMPISTR 145)
199 (UNSPEC_FMA4_INTRINSIC 150)
200 (UNSPEC_FMA4_FMADDSUB 151)
201 (UNSPEC_FMA4_FMSUBADD 152)
204 (UNSPEC_AESENCLAST 160)
206 (UNSPEC_AESDECLAST 162)
208 (UNSPEC_AESKEYGENASSIST 164)
216 (UNSPEC_VPERMIL2F128 168)
217 (UNSPEC_MASKLOAD 169)
218 (UNSPEC_MASKSTORE 170)
224 [(UNSPECV_BLOCKAGE 0)
225 (UNSPECV_STACK_PROBE 1)
237 (UNSPECV_PROLOGUE_USE 14)
239 (UNSPECV_VZEROALL 16)
240 (UNSPECV_VZEROUPPER 17)
246 ;; Constants to represent pcomtrue/pcomfalse variants
256 ;; Registers by name.
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first. This allows for better optimization. For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
321 (const (symbol_ref "ix86_schedule")))
323 ;; A basic instruction type. Refinements due to arguments to be
324 ;; provided in other attributes.
327 alu,alu1,negnot,imov,imovx,lea,
328 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329 icmp,test,ibr,setcc,icmov,
330 push,pop,call,callv,leave,
332 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
336 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337 (const_string "other"))
339 ;; Main data type used by the insn
341 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342 (const_string "unknown"))
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347 (const_string "i387")
348 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
352 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
354 (eq_attr "type" "other")
355 (const_string "unknown")]
356 (const_string "integer")))
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
363 (eq_attr "unit" "i387,sse,mmx")
365 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
367 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368 (eq_attr "type" "imov,test")
369 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370 (eq_attr "type" "call")
371 (if_then_else (match_operand 0 "constant_call_address_operand" "")
374 (eq_attr "type" "callv")
375 (if_then_else (match_operand 1 "constant_call_address_operand" "")
378 ;; We don't know the size before shorten_branches. Expect
379 ;; the instruction to fit for better scheduling.
380 (eq_attr "type" "ibr")
383 (symbol_ref "/* Update immediate_length and other attributes! */
384 gcc_unreachable (),1")))
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388 (cond [(eq_attr "type" "str,other,multi,fxch")
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
397 (symbol_ref "ix86_attr_length_address_default (insn)")))
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
403 (eq_attr "mode" "HI")
405 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
410 ;; Set when string REP prefix is used.
411 (define_attr "prefix_rep" ""
412 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
414 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
419 ;; Set when 0f opcode prefix is used.
420 (define_attr "prefix_0f" ""
422 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
423 (eq_attr "unit" "sse,mmx"))
427 ;; Set when REX opcode prefix is used.
428 (define_attr "prefix_rex" ""
429 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
431 (and (eq_attr "mode" "DI")
432 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
433 (eq_attr "unit" "!mmx")))
435 (and (eq_attr "mode" "QI")
436 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
439 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
442 (and (eq_attr "type" "imovx")
443 (match_operand:QI 1 "ext_QIreg_operand" ""))
448 ;; There are also additional prefixes in 3DNOW, SSSE3.
449 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
450 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
451 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
452 (define_attr "prefix_extra" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg")
455 (eq_attr "type" "sseiadd1,ssecvt1")
460 ;; Prefix used: original, VEX or maybe VEX.
461 (define_attr "prefix" "orig,vex,maybe_vex"
462 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
464 (const_string "orig")))
466 ;; VEX W bit is used.
467 (define_attr "prefix_vex_w" "" (const_int 0))
469 ;; The length of VEX prefix
470 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
471 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
472 ;; still prefix_0f 1, with prefix_extra 1.
473 (define_attr "length_vex" ""
474 (if_then_else (and (eq_attr "prefix_0f" "1")
475 (eq_attr "prefix_extra" "0"))
476 (if_then_else (eq_attr "prefix_vex_w" "1")
477 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
478 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
479 (if_then_else (eq_attr "prefix_vex_w" "1")
480 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
481 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
483 ;; Set when modrm byte is used.
484 (define_attr "modrm" ""
485 (cond [(eq_attr "type" "str,leave")
487 (eq_attr "unit" "i387")
489 (and (eq_attr "type" "incdec")
490 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
491 (ior (match_operand:SI 1 "register_operand" "")
492 (match_operand:HI 1 "register_operand" ""))))
494 (and (eq_attr "type" "push")
495 (not (match_operand 1 "memory_operand" "")))
497 (and (eq_attr "type" "pop")
498 (not (match_operand 0 "memory_operand" "")))
500 (and (eq_attr "type" "imov")
501 (and (not (eq_attr "mode" "DI"))
502 (ior (and (match_operand 0 "register_operand" "")
503 (match_operand 1 "immediate_operand" ""))
504 (ior (and (match_operand 0 "ax_reg_operand" "")
505 (match_operand 1 "memory_displacement_only_operand" ""))
506 (and (match_operand 0 "memory_displacement_only_operand" "")
507 (match_operand 1 "ax_reg_operand" ""))))))
509 (and (eq_attr "type" "call")
510 (match_operand 0 "constant_call_address_operand" ""))
512 (and (eq_attr "type" "callv")
513 (match_operand 1 "constant_call_address_operand" ""))
515 (and (eq_attr "type" "alu,alu1,icmp,test")
516 (match_operand 0 "ax_reg_operand" ""))
517 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
521 ;; The (bounding maximum) length of an instruction in bytes.
522 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
523 ;; Later we may want to split them and compute proper length as for
525 (define_attr "length" ""
526 (cond [(eq_attr "type" "other,multi,fistp,frndint")
528 (eq_attr "type" "fcmp")
530 (eq_attr "unit" "i387")
532 (plus (attr "prefix_data16")
533 (attr "length_address")))
534 (ior (eq_attr "prefix" "vex")
535 (and (eq_attr "prefix" "maybe_vex")
536 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
537 (plus (attr "length_vex")
538 (plus (attr "length_immediate")
540 (attr "length_address"))))]
541 (plus (plus (attr "modrm")
542 (plus (attr "prefix_0f")
543 (plus (attr "prefix_rex")
544 (plus (attr "prefix_extra")
546 (plus (attr "prefix_rep")
547 (plus (attr "prefix_data16")
548 (plus (attr "length_immediate")
549 (attr "length_address")))))))
551 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
552 ;; `store' if there is a simple memory reference therein, or `unknown'
553 ;; if the instruction is complex.
555 (define_attr "memory" "none,load,store,both,unknown"
556 (cond [(eq_attr "type" "other,multi,str")
557 (const_string "unknown")
558 (eq_attr "type" "lea,fcmov,fpspc")
559 (const_string "none")
560 (eq_attr "type" "fistp,leave")
561 (const_string "both")
562 (eq_attr "type" "frndint")
563 (const_string "load")
564 (eq_attr "type" "push")
565 (if_then_else (match_operand 1 "memory_operand" "")
566 (const_string "both")
567 (const_string "store"))
568 (eq_attr "type" "pop")
569 (if_then_else (match_operand 0 "memory_operand" "")
570 (const_string "both")
571 (const_string "load"))
572 (eq_attr "type" "setcc")
573 (if_then_else (match_operand 0 "memory_operand" "")
574 (const_string "store")
575 (const_string "none"))
576 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
577 (if_then_else (ior (match_operand 0 "memory_operand" "")
578 (match_operand 1 "memory_operand" ""))
579 (const_string "load")
580 (const_string "none"))
581 (eq_attr "type" "ibr")
582 (if_then_else (match_operand 0 "memory_operand" "")
583 (const_string "load")
584 (const_string "none"))
585 (eq_attr "type" "call")
586 (if_then_else (match_operand 0 "constant_call_address_operand" "")
587 (const_string "none")
588 (const_string "load"))
589 (eq_attr "type" "callv")
590 (if_then_else (match_operand 1 "constant_call_address_operand" "")
591 (const_string "none")
592 (const_string "load"))
593 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
594 (match_operand 1 "memory_operand" ""))
595 (const_string "both")
596 (and (match_operand 0 "memory_operand" "")
597 (match_operand 1 "memory_operand" ""))
598 (const_string "both")
599 (match_operand 0 "memory_operand" "")
600 (const_string "store")
601 (match_operand 1 "memory_operand" "")
602 (const_string "load")
604 "!alu1,negnot,ishift1,
605 imov,imovx,icmp,test,bitmanip,
607 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
608 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
609 (match_operand 2 "memory_operand" ""))
610 (const_string "load")
611 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
612 (match_operand 3 "memory_operand" ""))
613 (const_string "load")
615 (const_string "none")))
617 ;; Indicates if an instruction has both an immediate and a displacement.
619 (define_attr "imm_disp" "false,true,unknown"
620 (cond [(eq_attr "type" "other,multi")
621 (const_string "unknown")
622 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
623 (and (match_operand 0 "memory_displacement_operand" "")
624 (match_operand 1 "immediate_operand" "")))
625 (const_string "true")
626 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
627 (and (match_operand 0 "memory_displacement_operand" "")
628 (match_operand 2 "immediate_operand" "")))
629 (const_string "true")
631 (const_string "false")))
633 ;; Indicates if an FP operation has an integer source.
635 (define_attr "fp_int_src" "false,true"
636 (const_string "false"))
638 ;; Defines rounding mode of an FP operation.
640 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
641 (const_string "any"))
643 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
644 (define_attr "use_carry" "0,1" (const_string "0"))
646 ;; Define attribute to indicate unaligned ssemov insns
647 (define_attr "movu" "0,1" (const_string "0"))
649 ;; Describe a user's asm statement.
650 (define_asm_attributes
651 [(set_attr "length" "128")
652 (set_attr "type" "multi")])
654 ;; All integer comparison codes.
655 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
657 ;; All floating-point comparison codes.
658 (define_code_iterator fp_cond [unordered ordered
659 uneq unge ungt unle unlt ltgt ])
661 (define_code_iterator plusminus [plus minus])
663 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
665 ;; Base name for define_insn
666 (define_code_attr plusminus_insn
667 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
668 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
670 ;; Base name for insn mnemonic.
671 (define_code_attr plusminus_mnemonic
672 [(plus "add") (ss_plus "adds") (us_plus "addus")
673 (minus "sub") (ss_minus "subs") (us_minus "subus")])
675 ;; Mark commutative operators as such in constraints.
676 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
677 (minus "") (ss_minus "") (us_minus "")])
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
685 ;; Mapping of signed/unsigned max and min
686 (define_code_iterator maxmin [smax smin umax umin])
688 ;; Base name for integer and FP insn mnemonic
689 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
690 (umax "maxu") (umin "minu")])
691 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
693 ;; Mapping of parallel logic operators
694 (define_code_iterator plogic [and ior xor])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
699 ;; Mapping of abs neg operators
700 (define_code_iterator absneg [abs neg])
702 ;; Base name for x87 insn mnemonic.
703 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
705 ;; All single word integer modes.
706 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
708 ;; Single word integer modes without QImode.
709 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
711 ;; Single word integer modes without QImode and HImode.
712 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
714 ;; All math-dependant single and double word integer modes.
715 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
716 (HI "TARGET_HIMODE_MATH")
717 SI DI (TI "TARGET_64BIT")])
719 ;; Math-dependant single word integer modes without QImode.
720 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
721 SI (DI "TARGET_64BIT")])
723 ;; Double word integer modes.
724 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
725 (TI "TARGET_64BIT")])
727 ;; Half mode for double word integer modes.
728 (define_mode_attr DWIH [(DI "SI") (TI "DI")])
730 ;; Instruction suffix for integer modes.
731 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
733 ;; Register class for integer modes.
734 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
736 ;; Immediate operand constraint for integer modes.
737 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
739 ;; General operand constraint for word modes.
740 (define_mode_attr g [(SI "g") (DI "rme")])
742 ;; Immediate operand constraint for double integer modes.
743 (define_mode_attr di [(DI "iF") (TI "e")])
745 ;; General operand predicate for integer modes.
746 (define_mode_attr general_operand
747 [(QI "general_operand")
748 (HI "general_operand")
749 (SI "general_operand")
750 (DI "x86_64_general_operand")
751 (TI "x86_64_general_operand")])
753 ;; General operand predicate for double integer modes.
754 (define_mode_attr doubleint_general_operand
755 [(DI "general_operand")
756 (TI "x86_64_general_operand")])
758 ;; SSE and x87 SFmode and DFmode floating point modes
759 (define_mode_iterator MODEF [SF DF])
761 ;; All x87 floating point modes
762 (define_mode_iterator X87MODEF [SF DF XF])
764 ;; All integer modes handled by x87 fisttp operator.
765 (define_mode_iterator X87MODEI [HI SI DI])
767 ;; All integer modes handled by integer x87 operators.
768 (define_mode_iterator X87MODEI12 [HI SI])
770 ;; All integer modes handled by SSE cvtts?2si* operators.
771 (define_mode_iterator SSEMODEI24 [SI DI])
773 ;; SSE asm suffix for floating point modes
774 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
776 ;; SSE vector mode corresponding to a scalar mode
777 (define_mode_attr ssevecmode
778 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
780 ;; Instruction suffix for REX 64bit operators.
781 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
783 ;; This mode iterator allows :P to be used for patterns that operate on
784 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
785 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
788 ;; Scheduling descriptions
790 (include "pentium.md")
793 (include "athlon.md")
798 ;; Operand and operator predicates and constraints
800 (include "predicates.md")
801 (include "constraints.md")
804 ;; Compare and branch/compare and store instructions.
806 (define_expand "cbranchti4"
807 [(set (reg:CC FLAGS_REG)
808 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
809 (match_operand:TI 2 "x86_64_general_operand" "")))
810 (set (pc) (if_then_else
811 (match_operator 0 "comparison_operator"
814 (label_ref (match_operand 3 "" ""))
818 if (MEM_P (operands[1]) && MEM_P (operands[2]))
819 operands[1] = force_reg (TImode, operands[1]);
820 ix86_compare_op0 = operands[1];
821 ix86_compare_op1 = operands[2];
822 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
826 (define_expand "cbranchdi4"
827 [(set (reg:CC FLAGS_REG)
828 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
829 (match_operand:DI 2 "x86_64_general_operand" "")))
830 (set (pc) (if_then_else
831 (match_operator 0 "comparison_operator"
834 (label_ref (match_operand 3 "" ""))
838 if (MEM_P (operands[1]) && MEM_P (operands[2]))
839 operands[1] = force_reg (DImode, operands[1]);
840 ix86_compare_op0 = operands[1];
841 ix86_compare_op1 = operands[2];
842 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
846 (define_expand "cstoredi4"
847 [(set (reg:CC FLAGS_REG)
848 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
849 (match_operand:DI 3 "x86_64_general_operand" "")))
850 (set (match_operand:QI 0 "register_operand" "")
851 (match_operator 1 "comparison_operator"
856 if (MEM_P (operands[2]) && MEM_P (operands[3]))
857 operands[2] = force_reg (DImode, operands[2]);
858 ix86_compare_op0 = operands[2];
859 ix86_compare_op1 = operands[3];
860 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
864 (define_expand "cbranchsi4"
865 [(set (reg:CC FLAGS_REG)
866 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
867 (match_operand:SI 2 "general_operand" "")))
868 (set (pc) (if_then_else
869 (match_operator 0 "comparison_operator"
872 (label_ref (match_operand 3 "" ""))
876 if (MEM_P (operands[1]) && MEM_P (operands[2]))
877 operands[1] = force_reg (SImode, operands[1]);
878 ix86_compare_op0 = operands[1];
879 ix86_compare_op1 = operands[2];
880 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
884 (define_expand "cstoresi4"
885 [(set (reg:CC FLAGS_REG)
886 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
887 (match_operand:SI 3 "general_operand" "")))
888 (set (match_operand:QI 0 "register_operand" "")
889 (match_operator 1 "comparison_operator"
894 if (MEM_P (operands[2]) && MEM_P (operands[3]))
895 operands[2] = force_reg (SImode, operands[2]);
896 ix86_compare_op0 = operands[2];
897 ix86_compare_op1 = operands[3];
898 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
902 (define_expand "cbranchhi4"
903 [(set (reg:CC FLAGS_REG)
904 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
905 (match_operand:HI 2 "general_operand" "")))
906 (set (pc) (if_then_else
907 (match_operator 0 "comparison_operator"
910 (label_ref (match_operand 3 "" ""))
914 if (MEM_P (operands[1]) && MEM_P (operands[2]))
915 operands[1] = force_reg (HImode, operands[1]);
916 ix86_compare_op0 = operands[1];
917 ix86_compare_op1 = operands[2];
918 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
922 (define_expand "cstorehi4"
923 [(set (reg:CC FLAGS_REG)
924 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
925 (match_operand:HI 3 "general_operand" "")))
926 (set (match_operand:QI 0 "register_operand" "")
927 (match_operator 1 "comparison_operator"
932 if (MEM_P (operands[2]) && MEM_P (operands[3]))
933 operands[2] = force_reg (HImode, operands[2]);
934 ix86_compare_op0 = operands[2];
935 ix86_compare_op1 = operands[3];
936 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
941 (define_expand "cbranchqi4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
944 (match_operand:QI 2 "general_operand" "")))
945 (set (pc) (if_then_else
946 (match_operator 0 "comparison_operator"
949 (label_ref (match_operand 3 "" ""))
953 if (MEM_P (operands[1]) && MEM_P (operands[2]))
954 operands[1] = force_reg (QImode, operands[1]);
955 ix86_compare_op0 = operands[1];
956 ix86_compare_op1 = operands[2];
957 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
962 (define_expand "cstoreqi4"
963 [(set (reg:CC FLAGS_REG)
964 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
965 (match_operand:QI 3 "general_operand" "")))
966 (set (match_operand:QI 0 "register_operand" "")
967 (match_operator 1 "comparison_operator"
972 if (MEM_P (operands[2]) && MEM_P (operands[3]))
973 operands[2] = force_reg (QImode, operands[2]);
974 ix86_compare_op0 = operands[2];
975 ix86_compare_op1 = operands[3];
976 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
981 (define_insn "cmpdi_ccno_1_rex64"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
984 (match_operand:DI 1 "const0_operand" "")))]
985 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
988 cmp{q}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "test,icmp")
990 (set_attr "length_immediate" "0,1")
991 (set_attr "mode" "DI")])
993 (define_insn "*cmpdi_minus_1_rex64"
994 [(set (reg FLAGS_REG)
995 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
996 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
998 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
999 "cmp{q}\t{%1, %0|%0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "DI")])
1003 (define_expand "cmpdi_1_rex64"
1004 [(set (reg:CC FLAGS_REG)
1005 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1006 (match_operand:DI 1 "general_operand" "")))]
1010 (define_insn "cmpdi_1_insn_rex64"
1011 [(set (reg FLAGS_REG)
1012 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1013 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{q}\t{%1, %0|%0, %1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "DI")])
1020 (define_insn "*cmpsi_ccno_1"
1021 [(set (reg FLAGS_REG)
1022 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1023 (match_operand:SI 1 "const0_operand" "")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1027 cmp{l}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "test,icmp")
1029 (set_attr "length_immediate" "0,1")
1030 (set_attr "mode" "SI")])
1032 (define_insn "*cmpsi_minus_1"
1033 [(set (reg FLAGS_REG)
1034 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1035 (match_operand:SI 1 "general_operand" "ri,mr"))
1037 "ix86_match_ccmode (insn, CCGOCmode)"
1038 "cmp{l}\t{%1, %0|%0, %1}"
1039 [(set_attr "type" "icmp")
1040 (set_attr "mode" "SI")])
1042 (define_expand "cmpsi_1"
1043 [(set (reg:CC FLAGS_REG)
1044 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1045 (match_operand:SI 1 "general_operand" "")))]
1049 (define_insn "*cmpsi_1_insn"
1050 [(set (reg FLAGS_REG)
1051 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1052 (match_operand:SI 1 "general_operand" "ri,mr")))]
1053 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1054 && ix86_match_ccmode (insn, CCmode)"
1055 "cmp{l}\t{%1, %0|%0, %1}"
1056 [(set_attr "type" "icmp")
1057 (set_attr "mode" "SI")])
1059 (define_insn "*cmphi_ccno_1"
1060 [(set (reg FLAGS_REG)
1061 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1062 (match_operand:HI 1 "const0_operand" "")))]
1063 "ix86_match_ccmode (insn, CCNOmode)"
1066 cmp{w}\t{%1, %0|%0, %1}"
1067 [(set_attr "type" "test,icmp")
1068 (set_attr "length_immediate" "0,1")
1069 (set_attr "mode" "HI")])
1071 (define_insn "*cmphi_minus_1"
1072 [(set (reg FLAGS_REG)
1073 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1074 (match_operand:HI 1 "general_operand" "rn,mr"))
1076 "ix86_match_ccmode (insn, CCGOCmode)"
1077 "cmp{w}\t{%1, %0|%0, %1}"
1078 [(set_attr "type" "icmp")
1079 (set_attr "mode" "HI")])
1081 (define_insn "*cmphi_1"
1082 [(set (reg FLAGS_REG)
1083 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1084 (match_operand:HI 1 "general_operand" "rn,mr")))]
1085 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1086 && ix86_match_ccmode (insn, CCmode)"
1087 "cmp{w}\t{%1, %0|%0, %1}"
1088 [(set_attr "type" "icmp")
1089 (set_attr "mode" "HI")])
1091 (define_insn "*cmpqi_ccno_1"
1092 [(set (reg FLAGS_REG)
1093 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1094 (match_operand:QI 1 "const0_operand" "")))]
1095 "ix86_match_ccmode (insn, CCNOmode)"
1098 cmp{b}\t{$0, %0|%0, 0}"
1099 [(set_attr "type" "test,icmp")
1100 (set_attr "length_immediate" "0,1")
1101 (set_attr "mode" "QI")])
1103 (define_insn "*cmpqi_1"
1104 [(set (reg FLAGS_REG)
1105 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1106 (match_operand:QI 1 "general_operand" "qn,mq")))]
1107 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1108 && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %0|%0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "mode" "QI")])
1113 (define_insn "*cmpqi_minus_1"
1114 [(set (reg FLAGS_REG)
1115 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1116 (match_operand:QI 1 "general_operand" "qn,mq"))
1118 "ix86_match_ccmode (insn, CCGOCmode)"
1119 "cmp{b}\t{%1, %0|%0, %1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1123 (define_insn "*cmpqi_ext_1"
1124 [(set (reg FLAGS_REG)
1126 (match_operand:QI 0 "general_operand" "Qm")
1129 (match_operand 1 "ext_register_operand" "Q")
1131 (const_int 8)) 0)))]
1132 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1133 "cmp{b}\t{%h1, %0|%0, %h1}"
1134 [(set_attr "type" "icmp")
1135 (set_attr "mode" "QI")])
1137 (define_insn "*cmpqi_ext_1_rex64"
1138 [(set (reg FLAGS_REG)
1140 (match_operand:QI 0 "register_operand" "Q")
1143 (match_operand 1 "ext_register_operand" "Q")
1145 (const_int 8)) 0)))]
1146 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %0|%0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1151 (define_insn "*cmpqi_ext_2"
1152 [(set (reg FLAGS_REG)
1156 (match_operand 0 "ext_register_operand" "Q")
1159 (match_operand:QI 1 "const0_operand" "")))]
1160 "ix86_match_ccmode (insn, CCNOmode)"
1162 [(set_attr "type" "test")
1163 (set_attr "length_immediate" "0")
1164 (set_attr "mode" "QI")])
1166 (define_expand "cmpqi_ext_3"
1167 [(set (reg:CC FLAGS_REG)
1171 (match_operand 0 "ext_register_operand" "")
1174 (match_operand:QI 1 "general_operand" "")))]
1178 (define_insn "cmpqi_ext_3_insn"
1179 [(set (reg FLAGS_REG)
1183 (match_operand 0 "ext_register_operand" "Q")
1186 (match_operand:QI 1 "general_operand" "Qmn")))]
1187 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1188 "cmp{b}\t{%1, %h0|%h0, %1}"
1189 [(set_attr "type" "icmp")
1190 (set_attr "modrm" "1")
1191 (set_attr "mode" "QI")])
1193 (define_insn "cmpqi_ext_3_insn_rex64"
1194 [(set (reg FLAGS_REG)
1198 (match_operand 0 "ext_register_operand" "Q")
1201 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1202 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1203 "cmp{b}\t{%1, %h0|%h0, %1}"
1204 [(set_attr "type" "icmp")
1205 (set_attr "modrm" "1")
1206 (set_attr "mode" "QI")])
1208 (define_insn "*cmpqi_ext_4"
1209 [(set (reg FLAGS_REG)
1213 (match_operand 0 "ext_register_operand" "Q")
1218 (match_operand 1 "ext_register_operand" "Q")
1220 (const_int 8)) 0)))]
1221 "ix86_match_ccmode (insn, CCmode)"
1222 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1223 [(set_attr "type" "icmp")
1224 (set_attr "mode" "QI")])
1226 ;; These implement float point compares.
1227 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1228 ;; which would allow mix and match FP modes on the compares. Which is what
1229 ;; the old patterns did, but with many more of them.
1231 (define_expand "cbranchxf4"
1232 [(set (reg:CC FLAGS_REG)
1233 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1234 (match_operand:XF 2 "nonmemory_operand" "")))
1235 (set (pc) (if_then_else
1236 (match_operator 0 "ix86_fp_comparison_operator"
1239 (label_ref (match_operand 3 "" ""))
1243 ix86_compare_op0 = operands[1];
1244 ix86_compare_op1 = operands[2];
1245 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1249 (define_expand "cstorexf4"
1250 [(set (reg:CC FLAGS_REG)
1251 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1252 (match_operand:XF 3 "nonmemory_operand" "")))
1253 (set (match_operand:QI 0 "register_operand" "")
1254 (match_operator 1 "ix86_fp_comparison_operator"
1259 ix86_compare_op0 = operands[2];
1260 ix86_compare_op1 = operands[3];
1261 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1265 (define_expand "cbranch<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1268 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1269 (set (pc) (if_then_else
1270 (match_operator 0 "ix86_fp_comparison_operator"
1273 (label_ref (match_operand 3 "" ""))
1275 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1277 ix86_compare_op0 = operands[1];
1278 ix86_compare_op1 = operands[2];
1279 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1283 (define_expand "cstore<mode>4"
1284 [(set (reg:CC FLAGS_REG)
1285 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1286 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1287 (set (match_operand:QI 0 "register_operand" "")
1288 (match_operator 1 "ix86_fp_comparison_operator"
1291 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1293 ix86_compare_op0 = operands[2];
1294 ix86_compare_op1 = operands[3];
1295 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1299 (define_expand "cbranchcc4"
1300 [(set (pc) (if_then_else
1301 (match_operator 0 "comparison_operator"
1302 [(match_operand 1 "flags_reg_operand" "")
1303 (match_operand 2 "const0_operand" "")])
1304 (label_ref (match_operand 3 "" ""))
1308 ix86_compare_op0 = operands[1];
1309 ix86_compare_op1 = operands[2];
1310 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1314 (define_expand "cstorecc4"
1315 [(set (match_operand:QI 0 "register_operand" "")
1316 (match_operator 1 "comparison_operator"
1317 [(match_operand 2 "flags_reg_operand" "")
1318 (match_operand 3 "const0_operand" "")]))]
1321 ix86_compare_op0 = operands[2];
1322 ix86_compare_op1 = operands[3];
1323 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1328 ;; FP compares, step 1:
1329 ;; Set the FP condition codes.
1331 ;; CCFPmode compare with exceptions
1332 ;; CCFPUmode compare with no exceptions
1334 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1335 ;; used to manage the reg stack popping would not be preserved.
1337 (define_insn "*cmpfp_0"
1338 [(set (match_operand:HI 0 "register_operand" "=a")
1341 (match_operand 1 "register_operand" "f")
1342 (match_operand 2 "const0_operand" ""))]
1344 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346 "* return output_fp_compare (insn, operands, 0, 0);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1350 (cond [(match_operand:SF 1 "" "")
1352 (match_operand:DF 1 "" "")
1355 (const_string "XF")))])
1357 (define_insn_and_split "*cmpfp_0_cc"
1358 [(set (reg:CCFP FLAGS_REG)
1360 (match_operand 1 "register_operand" "f")
1361 (match_operand 2 "const0_operand" "")))
1362 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364 && TARGET_SAHF && !TARGET_CMOVE
1365 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1367 "&& reload_completed"
1370 [(compare:CCFP (match_dup 1)(match_dup 2))]
1372 (set (reg:CC FLAGS_REG)
1373 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1378 (cond [(match_operand:SF 1 "" "")
1380 (match_operand:DF 1 "" "")
1383 (const_string "XF")))])
1385 (define_insn "*cmpfp_xf"
1386 [(set (match_operand:HI 0 "register_operand" "=a")
1389 (match_operand:XF 1 "register_operand" "f")
1390 (match_operand:XF 2 "register_operand" "f"))]
1393 "* return output_fp_compare (insn, operands, 0, 0);"
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "mode" "XF")])
1398 (define_insn_and_split "*cmpfp_xf_cc"
1399 [(set (reg:CCFP FLAGS_REG)
1401 (match_operand:XF 1 "register_operand" "f")
1402 (match_operand:XF 2 "register_operand" "f")))
1403 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1405 && TARGET_SAHF && !TARGET_CMOVE"
1407 "&& reload_completed"
1410 [(compare:CCFP (match_dup 1)(match_dup 2))]
1412 (set (reg:CC FLAGS_REG)
1413 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1415 [(set_attr "type" "multi")
1416 (set_attr "unit" "i387")
1417 (set_attr "mode" "XF")])
1419 (define_insn "*cmpfp_<mode>"
1420 [(set (match_operand:HI 0 "register_operand" "=a")
1423 (match_operand:MODEF 1 "register_operand" "f")
1424 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1427 "* return output_fp_compare (insn, operands, 0, 0);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "mode" "<MODE>")])
1432 (define_insn_and_split "*cmpfp_<mode>_cc"
1433 [(set (reg:CCFP FLAGS_REG)
1435 (match_operand:MODEF 1 "register_operand" "f")
1436 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1437 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1439 && TARGET_SAHF && !TARGET_CMOVE"
1441 "&& reload_completed"
1444 [(compare:CCFP (match_dup 1)(match_dup 2))]
1446 (set (reg:CC FLAGS_REG)
1447 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1449 [(set_attr "type" "multi")
1450 (set_attr "unit" "i387")
1451 (set_attr "mode" "<MODE>")])
1453 (define_insn "*cmpfp_u"
1454 [(set (match_operand:HI 0 "register_operand" "=a")
1457 (match_operand 1 "register_operand" "f")
1458 (match_operand 2 "register_operand" "f"))]
1460 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1461 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1462 "* return output_fp_compare (insn, operands, 0, 1);"
1463 [(set_attr "type" "multi")
1464 (set_attr "unit" "i387")
1466 (cond [(match_operand:SF 1 "" "")
1468 (match_operand:DF 1 "" "")
1471 (const_string "XF")))])
1473 (define_insn_and_split "*cmpfp_u_cc"
1474 [(set (reg:CCFPU FLAGS_REG)
1476 (match_operand 1 "register_operand" "f")
1477 (match_operand 2 "register_operand" "f")))
1478 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1479 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1480 && TARGET_SAHF && !TARGET_CMOVE
1481 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1483 "&& reload_completed"
1486 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1488 (set (reg:CC FLAGS_REG)
1489 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1491 [(set_attr "type" "multi")
1492 (set_attr "unit" "i387")
1494 (cond [(match_operand:SF 1 "" "")
1496 (match_operand:DF 1 "" "")
1499 (const_string "XF")))])
1501 (define_insn "*cmpfp_<mode>"
1502 [(set (match_operand:HI 0 "register_operand" "=a")
1505 (match_operand 1 "register_operand" "f")
1506 (match_operator 3 "float_operator"
1507 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1509 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1510 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1511 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1512 "* return output_fp_compare (insn, operands, 0, 0);"
1513 [(set_attr "type" "multi")
1514 (set_attr "unit" "i387")
1515 (set_attr "fp_int_src" "true")
1516 (set_attr "mode" "<MODE>")])
1518 (define_insn_and_split "*cmpfp_<mode>_cc"
1519 [(set (reg:CCFP FLAGS_REG)
1521 (match_operand 1 "register_operand" "f")
1522 (match_operator 3 "float_operator"
1523 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1524 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1526 && TARGET_SAHF && !TARGET_CMOVE
1527 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1528 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1530 "&& reload_completed"
1535 (match_op_dup 3 [(match_dup 2)]))]
1537 (set (reg:CC FLAGS_REG)
1538 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1540 [(set_attr "type" "multi")
1541 (set_attr "unit" "i387")
1542 (set_attr "fp_int_src" "true")
1543 (set_attr "mode" "<MODE>")])
1545 ;; FP compares, step 2
1546 ;; Move the fpsw to ax.
1548 (define_insn "x86_fnstsw_1"
1549 [(set (match_operand:HI 0 "register_operand" "=a")
1550 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1553 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1554 (set_attr "mode" "SI")
1555 (set_attr "unit" "i387")])
1557 ;; FP compares, step 3
1558 ;; Get ax into flags, general case.
1560 (define_insn "x86_sahf_1"
1561 [(set (reg:CC FLAGS_REG)
1562 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1566 #ifdef HAVE_AS_IX86_SAHF
1569 return ASM_BYTE "0x9e";
1572 [(set_attr "length" "1")
1573 (set_attr "athlon_decode" "vector")
1574 (set_attr "amdfam10_decode" "direct")
1575 (set_attr "mode" "SI")])
1577 ;; Pentium Pro can do steps 1 through 3 in one go.
1578 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1579 (define_insn "*cmpfp_i_mixed"
1580 [(set (reg:CCFP FLAGS_REG)
1581 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1582 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1583 "TARGET_MIX_SSE_I387
1584 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1585 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586 "* return output_fp_compare (insn, operands, 1, 0);"
1587 [(set_attr "type" "fcmp,ssecomi")
1588 (set_attr "prefix" "orig,maybe_vex")
1590 (if_then_else (match_operand:SF 1 "" "")
1592 (const_string "DF")))
1593 (set (attr "prefix_rep")
1594 (if_then_else (eq_attr "type" "ssecomi")
1596 (const_string "*")))
1597 (set (attr "prefix_data16")
1598 (cond [(eq_attr "type" "fcmp")
1600 (eq_attr "mode" "DF")
1603 (const_string "0")))
1604 (set_attr "athlon_decode" "vector")
1605 (set_attr "amdfam10_decode" "direct")])
1607 (define_insn "*cmpfp_i_sse"
1608 [(set (reg:CCFP FLAGS_REG)
1609 (compare:CCFP (match_operand 0 "register_operand" "x")
1610 (match_operand 1 "nonimmediate_operand" "xm")))]
1612 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1613 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1614 "* return output_fp_compare (insn, operands, 1, 0);"
1615 [(set_attr "type" "ssecomi")
1616 (set_attr "prefix" "maybe_vex")
1618 (if_then_else (match_operand:SF 1 "" "")
1620 (const_string "DF")))
1621 (set_attr "prefix_rep" "0")
1622 (set (attr "prefix_data16")
1623 (if_then_else (eq_attr "mode" "DF")
1625 (const_string "0")))
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "direct")])
1629 (define_insn "*cmpfp_i_i387"
1630 [(set (reg:CCFP FLAGS_REG)
1631 (compare:CCFP (match_operand 0 "register_operand" "f")
1632 (match_operand 1 "register_operand" "f")))]
1633 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1635 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1636 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1637 "* return output_fp_compare (insn, operands, 1, 0);"
1638 [(set_attr "type" "fcmp")
1640 (cond [(match_operand:SF 1 "" "")
1642 (match_operand:DF 1 "" "")
1645 (const_string "XF")))
1646 (set_attr "athlon_decode" "vector")
1647 (set_attr "amdfam10_decode" "direct")])
1649 (define_insn "*cmpfp_iu_mixed"
1650 [(set (reg:CCFPU FLAGS_REG)
1651 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1652 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1653 "TARGET_MIX_SSE_I387
1654 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1655 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1656 "* return output_fp_compare (insn, operands, 1, 1);"
1657 [(set_attr "type" "fcmp,ssecomi")
1658 (set_attr "prefix" "orig,maybe_vex")
1660 (if_then_else (match_operand:SF 1 "" "")
1662 (const_string "DF")))
1663 (set (attr "prefix_rep")
1664 (if_then_else (eq_attr "type" "ssecomi")
1666 (const_string "*")))
1667 (set (attr "prefix_data16")
1668 (cond [(eq_attr "type" "fcmp")
1670 (eq_attr "mode" "DF")
1673 (const_string "0")))
1674 (set_attr "athlon_decode" "vector")
1675 (set_attr "amdfam10_decode" "direct")])
1677 (define_insn "*cmpfp_iu_sse"
1678 [(set (reg:CCFPU FLAGS_REG)
1679 (compare:CCFPU (match_operand 0 "register_operand" "x")
1680 (match_operand 1 "nonimmediate_operand" "xm")))]
1682 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1683 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1684 "* return output_fp_compare (insn, operands, 1, 1);"
1685 [(set_attr "type" "ssecomi")
1686 (set_attr "prefix" "maybe_vex")
1688 (if_then_else (match_operand:SF 1 "" "")
1690 (const_string "DF")))
1691 (set_attr "prefix_rep" "0")
1692 (set (attr "prefix_data16")
1693 (if_then_else (eq_attr "mode" "DF")
1695 (const_string "0")))
1696 (set_attr "athlon_decode" "vector")
1697 (set_attr "amdfam10_decode" "direct")])
1699 (define_insn "*cmpfp_iu_387"
1700 [(set (reg:CCFPU FLAGS_REG)
1701 (compare:CCFPU (match_operand 0 "register_operand" "f")
1702 (match_operand 1 "register_operand" "f")))]
1703 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1705 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1706 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1707 "* return output_fp_compare (insn, operands, 1, 1);"
1708 [(set_attr "type" "fcmp")
1710 (cond [(match_operand:SF 1 "" "")
1712 (match_operand:DF 1 "" "")
1715 (const_string "XF")))
1716 (set_attr "athlon_decode" "vector")
1717 (set_attr "amdfam10_decode" "direct")])
1719 ;; Move instructions.
1721 ;; General case of fullword move.
1723 (define_expand "movsi"
1724 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1725 (match_operand:SI 1 "general_operand" ""))]
1727 "ix86_expand_move (SImode, operands); DONE;")
1729 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1732 ;; %%% We don't use a post-inc memory reference because x86 is not a
1733 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1734 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1735 ;; targets without our curiosities, and it is just as easy to represent
1736 ;; this differently.
1738 (define_insn "*pushsi2"
1739 [(set (match_operand:SI 0 "push_operand" "=<")
1740 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1743 [(set_attr "type" "push")
1744 (set_attr "mode" "SI")])
1746 ;; For 64BIT abi we always round up to 8 bytes.
1747 (define_insn "*pushsi2_rex64"
1748 [(set (match_operand:SI 0 "push_operand" "=X")
1749 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1752 [(set_attr "type" "push")
1753 (set_attr "mode" "SI")])
1755 (define_insn "*pushsi2_prologue"
1756 [(set (match_operand:SI 0 "push_operand" "=<")
1757 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1758 (clobber (mem:BLK (scratch)))]
1761 [(set_attr "type" "push")
1762 (set_attr "mode" "SI")])
1764 (define_insn "*popsi1_epilogue"
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)))
1769 (clobber (mem:BLK (scratch)))]
1772 [(set_attr "type" "pop")
1773 (set_attr "mode" "SI")])
1775 (define_insn "popsi1"
1776 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1777 (mem:SI (reg:SI SP_REG)))
1778 (set (reg:SI SP_REG)
1779 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1782 [(set_attr "type" "pop")
1783 (set_attr "mode" "SI")])
1785 (define_insn "*movsi_xor"
1786 [(set (match_operand:SI 0 "register_operand" "=r")
1787 (match_operand:SI 1 "const0_operand" ""))
1788 (clobber (reg:CC FLAGS_REG))]
1791 [(set_attr "type" "alu1")
1792 (set_attr "mode" "SI")
1793 (set_attr "length_immediate" "0")])
1795 (define_insn "*movsi_or"
1796 [(set (match_operand:SI 0 "register_operand" "=r")
1797 (match_operand:SI 1 "immediate_operand" "i"))
1798 (clobber (reg:CC FLAGS_REG))]
1800 && operands[1] == constm1_rtx"
1802 operands[1] = constm1_rtx;
1803 return "or{l}\t{%1, %0|%0, %1}";
1805 [(set_attr "type" "alu1")
1806 (set_attr "mode" "SI")
1807 (set_attr "length_immediate" "1")])
1809 (define_insn "*movsi_1"
1810 [(set (match_operand:SI 0 "nonimmediate_operand"
1811 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1812 (match_operand:SI 1 "general_operand"
1813 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1814 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1816 switch (get_attr_type (insn))
1819 if (get_attr_mode (insn) == MODE_TI)
1820 return "%vpxor\t%0, %d0";
1821 return "%vxorps\t%0, %d0";
1824 switch (get_attr_mode (insn))
1827 return "%vmovdqa\t{%1, %0|%0, %1}";
1829 return "%vmovaps\t{%1, %0|%0, %1}";
1831 return "%vmovd\t{%1, %0|%0, %1}";
1833 return "%vmovss\t{%1, %0|%0, %1}";
1839 return "pxor\t%0, %0";
1842 if (get_attr_mode (insn) == MODE_DI)
1843 return "movq\t{%1, %0|%0, %1}";
1844 return "movd\t{%1, %0|%0, %1}";
1847 return "lea{l}\t{%1, %0|%0, %1}";
1850 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1851 return "mov{l}\t{%1, %0|%0, %1}";
1855 (cond [(eq_attr "alternative" "2")
1856 (const_string "mmx")
1857 (eq_attr "alternative" "3,4,5")
1858 (const_string "mmxmov")
1859 (eq_attr "alternative" "6")
1860 (const_string "sselog1")
1861 (eq_attr "alternative" "7,8,9,10,11")
1862 (const_string "ssemov")
1863 (match_operand:DI 1 "pic_32bit_operand" "")
1864 (const_string "lea")
1866 (const_string "imov")))
1867 (set (attr "prefix")
1868 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1869 (const_string "orig")
1870 (const_string "maybe_vex")))
1871 (set (attr "prefix_data16")
1872 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1874 (const_string "*")))
1876 (cond [(eq_attr "alternative" "2,3")
1878 (eq_attr "alternative" "6,7")
1880 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1881 (const_string "V4SF")
1882 (const_string "TI"))
1883 (and (eq_attr "alternative" "8,9,10,11")
1884 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1887 (const_string "SI")))])
1889 ;; Stores and loads of ax to arbitrary constant address.
1890 ;; We fake an second form of instruction to force reload to load address
1891 ;; into register when rax is not available
1892 (define_insn "*movabssi_1_rex64"
1893 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1894 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1895 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1897 movabs{l}\t{%1, %P0|%P0, %1}
1898 mov{l}\t{%1, %a0|%a0, %1}"
1899 [(set_attr "type" "imov")
1900 (set_attr "modrm" "0,*")
1901 (set_attr "length_address" "8,0")
1902 (set_attr "length_immediate" "0,*")
1903 (set_attr "memory" "store")
1904 (set_attr "mode" "SI")])
1906 (define_insn "*movabssi_2_rex64"
1907 [(set (match_operand:SI 0 "register_operand" "=a,r")
1908 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1909 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1911 movabs{l}\t{%P1, %0|%0, %P1}
1912 mov{l}\t{%a1, %0|%0, %a1}"
1913 [(set_attr "type" "imov")
1914 (set_attr "modrm" "0,*")
1915 (set_attr "length_address" "8,0")
1916 (set_attr "length_immediate" "0")
1917 (set_attr "memory" "load")
1918 (set_attr "mode" "SI")])
1920 (define_insn "*swapsi"
1921 [(set (match_operand:SI 0 "register_operand" "+r")
1922 (match_operand:SI 1 "register_operand" "+r"))
1927 [(set_attr "type" "imov")
1928 (set_attr "mode" "SI")
1929 (set_attr "pent_pair" "np")
1930 (set_attr "athlon_decode" "vector")
1931 (set_attr "amdfam10_decode" "double")])
1933 (define_expand "movhi"
1934 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1935 (match_operand:HI 1 "general_operand" ""))]
1937 "ix86_expand_move (HImode, operands); DONE;")
1939 (define_insn "*pushhi2"
1940 [(set (match_operand:HI 0 "push_operand" "=X")
1941 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1944 [(set_attr "type" "push")
1945 (set_attr "mode" "SI")])
1947 ;; For 64BIT abi we always round up to 8 bytes.
1948 (define_insn "*pushhi2_rex64"
1949 [(set (match_operand:HI 0 "push_operand" "=X")
1950 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1953 [(set_attr "type" "push")
1954 (set_attr "mode" "DI")])
1956 (define_insn "*movhi_1"
1957 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1958 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1959 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1961 switch (get_attr_type (insn))
1964 /* movzwl is faster than movw on p2 due to partial word stalls,
1965 though not as fast as an aligned movl. */
1966 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1968 if (get_attr_mode (insn) == MODE_SI)
1969 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1971 return "mov{w}\t{%1, %0|%0, %1}";
1975 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1976 (const_string "imov")
1977 (and (eq_attr "alternative" "0")
1978 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1980 (eq (symbol_ref "TARGET_HIMODE_MATH")
1982 (const_string "imov")
1983 (and (eq_attr "alternative" "1,2")
1984 (match_operand:HI 1 "aligned_operand" ""))
1985 (const_string "imov")
1986 (and (ne (symbol_ref "TARGET_MOVX")
1988 (eq_attr "alternative" "0,2"))
1989 (const_string "imovx")
1991 (const_string "imov")))
1993 (cond [(eq_attr "type" "imovx")
1995 (and (eq_attr "alternative" "1,2")
1996 (match_operand:HI 1 "aligned_operand" ""))
1998 (and (eq_attr "alternative" "0")
1999 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2001 (eq (symbol_ref "TARGET_HIMODE_MATH")
2005 (const_string "HI")))])
2007 ;; Stores and loads of ax to arbitrary constant address.
2008 ;; We fake an second form of instruction to force reload to load address
2009 ;; into register when rax is not available
2010 (define_insn "*movabshi_1_rex64"
2011 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2012 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2013 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2015 movabs{w}\t{%1, %P0|%P0, %1}
2016 mov{w}\t{%1, %a0|%a0, %1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "modrm" "0,*")
2019 (set_attr "length_address" "8,0")
2020 (set_attr "length_immediate" "0,*")
2021 (set_attr "memory" "store")
2022 (set_attr "mode" "HI")])
2024 (define_insn "*movabshi_2_rex64"
2025 [(set (match_operand:HI 0 "register_operand" "=a,r")
2026 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2027 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2029 movabs{w}\t{%P1, %0|%0, %P1}
2030 mov{w}\t{%a1, %0|%0, %a1}"
2031 [(set_attr "type" "imov")
2032 (set_attr "modrm" "0,*")
2033 (set_attr "length_address" "8,0")
2034 (set_attr "length_immediate" "0")
2035 (set_attr "memory" "load")
2036 (set_attr "mode" "HI")])
2038 (define_insn "*swaphi_1"
2039 [(set (match_operand:HI 0 "register_operand" "+r")
2040 (match_operand:HI 1 "register_operand" "+r"))
2043 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2045 [(set_attr "type" "imov")
2046 (set_attr "mode" "SI")
2047 (set_attr "pent_pair" "np")
2048 (set_attr "athlon_decode" "vector")
2049 (set_attr "amdfam10_decode" "double")])
2051 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2052 (define_insn "*swaphi_2"
2053 [(set (match_operand:HI 0 "register_operand" "+r")
2054 (match_operand:HI 1 "register_operand" "+r"))
2057 "TARGET_PARTIAL_REG_STALL"
2059 [(set_attr "type" "imov")
2060 (set_attr "mode" "HI")
2061 (set_attr "pent_pair" "np")
2062 (set_attr "athlon_decode" "vector")])
2064 (define_expand "movstricthi"
2065 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2066 (match_operand:HI 1 "general_operand" ""))]
2069 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2071 /* Don't generate memory->memory moves, go through a register */
2072 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2073 operands[1] = force_reg (HImode, operands[1]);
2076 (define_insn "*movstricthi_1"
2077 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2078 (match_operand:HI 1 "general_operand" "rn,m"))]
2079 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2080 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2081 "mov{w}\t{%1, %0|%0, %1}"
2082 [(set_attr "type" "imov")
2083 (set_attr "mode" "HI")])
2085 (define_insn "*movstricthi_xor"
2086 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2087 (match_operand:HI 1 "const0_operand" ""))
2088 (clobber (reg:CC FLAGS_REG))]
2091 [(set_attr "type" "alu1")
2092 (set_attr "mode" "HI")
2093 (set_attr "length_immediate" "0")])
2095 (define_expand "movqi"
2096 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2097 (match_operand:QI 1 "general_operand" ""))]
2099 "ix86_expand_move (QImode, operands); DONE;")
2101 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2102 ;; "push a byte". But actually we use pushl, which has the effect
2103 ;; of rounding the amount pushed up to a word.
2105 (define_insn "*pushqi2"
2106 [(set (match_operand:QI 0 "push_operand" "=X")
2107 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2110 [(set_attr "type" "push")
2111 (set_attr "mode" "SI")])
2113 ;; For 64BIT abi we always round up to 8 bytes.
2114 (define_insn "*pushqi2_rex64"
2115 [(set (match_operand:QI 0 "push_operand" "=X")
2116 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2119 [(set_attr "type" "push")
2120 (set_attr "mode" "DI")])
2122 ;; Situation is quite tricky about when to choose full sized (SImode) move
2123 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2124 ;; partial register dependency machines (such as AMD Athlon), where QImode
2125 ;; moves issue extra dependency and for partial register stalls machines
2126 ;; that don't use QImode patterns (and QImode move cause stall on the next
2129 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2130 ;; register stall machines with, where we use QImode instructions, since
2131 ;; partial register stall can be caused there. Then we use movzx.
2132 (define_insn "*movqi_1"
2133 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2134 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2135 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2137 switch (get_attr_type (insn))
2140 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2141 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2143 if (get_attr_mode (insn) == MODE_SI)
2144 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2146 return "mov{b}\t{%1, %0|%0, %1}";
2150 (cond [(and (eq_attr "alternative" "5")
2151 (not (match_operand:QI 1 "aligned_operand" "")))
2152 (const_string "imovx")
2153 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2154 (const_string "imov")
2155 (and (eq_attr "alternative" "3")
2156 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2158 (eq (symbol_ref "TARGET_QIMODE_MATH")
2160 (const_string "imov")
2161 (eq_attr "alternative" "3,5")
2162 (const_string "imovx")
2163 (and (ne (symbol_ref "TARGET_MOVX")
2165 (eq_attr "alternative" "2"))
2166 (const_string "imovx")
2168 (const_string "imov")))
2170 (cond [(eq_attr "alternative" "3,4,5")
2172 (eq_attr "alternative" "6")
2174 (eq_attr "type" "imovx")
2176 (and (eq_attr "type" "imov")
2177 (and (eq_attr "alternative" "0,1")
2178 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2180 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2182 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2185 ;; Avoid partial register stalls when not using QImode arithmetic
2186 (and (eq_attr "type" "imov")
2187 (and (eq_attr "alternative" "0,1")
2188 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2190 (eq (symbol_ref "TARGET_QIMODE_MATH")
2194 (const_string "QI")))])
2196 (define_insn "*swapqi_1"
2197 [(set (match_operand:QI 0 "register_operand" "+r")
2198 (match_operand:QI 1 "register_operand" "+r"))
2201 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2203 [(set_attr "type" "imov")
2204 (set_attr "mode" "SI")
2205 (set_attr "pent_pair" "np")
2206 (set_attr "athlon_decode" "vector")
2207 (set_attr "amdfam10_decode" "vector")])
2209 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2210 (define_insn "*swapqi_2"
2211 [(set (match_operand:QI 0 "register_operand" "+q")
2212 (match_operand:QI 1 "register_operand" "+q"))
2215 "TARGET_PARTIAL_REG_STALL"
2217 [(set_attr "type" "imov")
2218 (set_attr "mode" "QI")
2219 (set_attr "pent_pair" "np")
2220 (set_attr "athlon_decode" "vector")])
2222 (define_expand "movstrictqi"
2223 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2224 (match_operand:QI 1 "general_operand" ""))]
2227 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2229 /* Don't generate memory->memory moves, go through a register. */
2230 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2231 operands[1] = force_reg (QImode, operands[1]);
2234 (define_insn "*movstrictqi_1"
2235 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2236 (match_operand:QI 1 "general_operand" "*qn,m"))]
2237 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2238 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2239 "mov{b}\t{%1, %0|%0, %1}"
2240 [(set_attr "type" "imov")
2241 (set_attr "mode" "QI")])
2243 (define_insn "*movstrictqi_xor"
2244 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2245 (match_operand:QI 1 "const0_operand" ""))
2246 (clobber (reg:CC FLAGS_REG))]
2249 [(set_attr "type" "alu1")
2250 (set_attr "mode" "QI")
2251 (set_attr "length_immediate" "0")])
2253 (define_insn "*movsi_extv_1"
2254 [(set (match_operand:SI 0 "register_operand" "=R")
2255 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2259 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2260 [(set_attr "type" "imovx")
2261 (set_attr "mode" "SI")])
2263 (define_insn "*movhi_extv_1"
2264 [(set (match_operand:HI 0 "register_operand" "=R")
2265 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2269 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2270 [(set_attr "type" "imovx")
2271 (set_attr "mode" "SI")])
2273 (define_insn "*movqi_extv_1"
2274 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2275 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2280 switch (get_attr_type (insn))
2283 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2285 return "mov{b}\t{%h1, %0|%0, %h1}";
2289 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2290 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2291 (ne (symbol_ref "TARGET_MOVX")
2293 (const_string "imovx")
2294 (const_string "imov")))
2296 (if_then_else (eq_attr "type" "imovx")
2298 (const_string "QI")))])
2300 (define_insn "*movqi_extv_1_rex64"
2301 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2302 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2307 switch (get_attr_type (insn))
2310 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2312 return "mov{b}\t{%h1, %0|%0, %h1}";
2316 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2317 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2318 (ne (symbol_ref "TARGET_MOVX")
2320 (const_string "imovx")
2321 (const_string "imov")))
2323 (if_then_else (eq_attr "type" "imovx")
2325 (const_string "QI")))])
2327 ;; Stores and loads of ax to arbitrary constant address.
2328 ;; We fake an second form of instruction to force reload to load address
2329 ;; into register when rax is not available
2330 (define_insn "*movabsqi_1_rex64"
2331 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2332 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2333 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2335 movabs{b}\t{%1, %P0|%P0, %1}
2336 mov{b}\t{%1, %a0|%a0, %1}"
2337 [(set_attr "type" "imov")
2338 (set_attr "modrm" "0,*")
2339 (set_attr "length_address" "8,0")
2340 (set_attr "length_immediate" "0,*")
2341 (set_attr "memory" "store")
2342 (set_attr "mode" "QI")])
2344 (define_insn "*movabsqi_2_rex64"
2345 [(set (match_operand:QI 0 "register_operand" "=a,r")
2346 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2347 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2349 movabs{b}\t{%P1, %0|%0, %P1}
2350 mov{b}\t{%a1, %0|%0, %a1}"
2351 [(set_attr "type" "imov")
2352 (set_attr "modrm" "0,*")
2353 (set_attr "length_address" "8,0")
2354 (set_attr "length_immediate" "0")
2355 (set_attr "memory" "load")
2356 (set_attr "mode" "QI")])
2358 (define_insn "*movdi_extzv_1"
2359 [(set (match_operand:DI 0 "register_operand" "=R")
2360 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2364 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2365 [(set_attr "type" "imovx")
2366 (set_attr "mode" "SI")])
2368 (define_insn "*movsi_extzv_1"
2369 [(set (match_operand:SI 0 "register_operand" "=R")
2370 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2374 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2375 [(set_attr "type" "imovx")
2376 (set_attr "mode" "SI")])
2378 (define_insn "*movqi_extzv_2"
2379 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2380 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2385 switch (get_attr_type (insn))
2388 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2390 return "mov{b}\t{%h1, %0|%0, %h1}";
2394 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2395 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2396 (ne (symbol_ref "TARGET_MOVX")
2398 (const_string "imovx")
2399 (const_string "imov")))
2401 (if_then_else (eq_attr "type" "imovx")
2403 (const_string "QI")))])
2405 (define_insn "*movqi_extzv_2_rex64"
2406 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2407 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2412 switch (get_attr_type (insn))
2415 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2417 return "mov{b}\t{%h1, %0|%0, %h1}";
2421 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2422 (ne (symbol_ref "TARGET_MOVX")
2424 (const_string "imovx")
2425 (const_string "imov")))
2427 (if_then_else (eq_attr "type" "imovx")
2429 (const_string "QI")))])
2431 (define_insn "movsi_insv_1"
2432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2435 (match_operand:SI 1 "general_operand" "Qmn"))]
2437 "mov{b}\t{%b1, %h0|%h0, %b1}"
2438 [(set_attr "type" "imov")
2439 (set_attr "mode" "QI")])
2441 (define_insn "*movsi_insv_1_rex64"
2442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2445 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2447 "mov{b}\t{%b1, %h0|%h0, %b1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "mode" "QI")])
2451 (define_insn "movdi_insv_1_rex64"
2452 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2455 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2457 "mov{b}\t{%b1, %h0|%h0, %b1}"
2458 [(set_attr "type" "imov")
2459 (set_attr "mode" "QI")])
2461 (define_insn "*movqi_insv_2"
2462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2465 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2468 "mov{b}\t{%h1, %h0|%h0, %h1}"
2469 [(set_attr "type" "imov")
2470 (set_attr "mode" "QI")])
2472 (define_expand "movdi"
2473 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2474 (match_operand:DI 1 "general_operand" ""))]
2476 "ix86_expand_move (DImode, operands); DONE;")
2478 (define_insn "*pushdi"
2479 [(set (match_operand:DI 0 "push_operand" "=<")
2480 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2484 (define_insn "*pushdi2_rex64"
2485 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2486 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2491 [(set_attr "type" "push,multi")
2492 (set_attr "mode" "DI")])
2494 ;; Convert impossible pushes of immediate to existing instructions.
2495 ;; First try to get scratch register and go through it. In case this
2496 ;; fails, push sign extended lower part first and then overwrite
2497 ;; upper part by 32bit move.
2499 [(match_scratch:DI 2 "r")
2500 (set (match_operand:DI 0 "push_operand" "")
2501 (match_operand:DI 1 "immediate_operand" ""))]
2502 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2503 && !x86_64_immediate_operand (operands[1], DImode)"
2504 [(set (match_dup 2) (match_dup 1))
2505 (set (match_dup 0) (match_dup 2))]
2508 ;; We need to define this as both peepholer and splitter for case
2509 ;; peephole2 pass is not run.
2510 ;; "&& 1" is needed to keep it from matching the previous pattern.
2512 [(set (match_operand:DI 0 "push_operand" "")
2513 (match_operand:DI 1 "immediate_operand" ""))]
2514 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2515 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2516 [(set (match_dup 0) (match_dup 1))
2517 (set (match_dup 2) (match_dup 3))]
2518 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2519 operands[1] = gen_lowpart (DImode, operands[2]);
2520 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2525 [(set (match_operand:DI 0 "push_operand" "")
2526 (match_operand:DI 1 "immediate_operand" ""))]
2527 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2528 ? epilogue_completed : reload_completed)
2529 && !symbolic_operand (operands[1], DImode)
2530 && !x86_64_immediate_operand (operands[1], DImode)"
2531 [(set (match_dup 0) (match_dup 1))
2532 (set (match_dup 2) (match_dup 3))]
2533 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2534 operands[1] = gen_lowpart (DImode, operands[2]);
2535 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2539 (define_insn "*pushdi2_prologue_rex64"
2540 [(set (match_operand:DI 0 "push_operand" "=<")
2541 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2542 (clobber (mem:BLK (scratch)))]
2545 [(set_attr "type" "push")
2546 (set_attr "mode" "DI")])
2548 (define_insn "*popdi1_epilogue_rex64"
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)))
2553 (clobber (mem:BLK (scratch)))]
2556 [(set_attr "type" "pop")
2557 (set_attr "mode" "DI")])
2559 (define_insn "popdi1"
2560 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2561 (mem:DI (reg:DI SP_REG)))
2562 (set (reg:DI SP_REG)
2563 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2566 [(set_attr "type" "pop")
2567 (set_attr "mode" "DI")])
2569 (define_insn "*movdi_xor_rex64"
2570 [(set (match_operand:DI 0 "register_operand" "=r")
2571 (match_operand:DI 1 "const0_operand" ""))
2572 (clobber (reg:CC FLAGS_REG))]
2574 && reload_completed"
2576 [(set_attr "type" "alu1")
2577 (set_attr "mode" "SI")
2578 (set_attr "length_immediate" "0")])
2580 (define_insn "*movdi_or_rex64"
2581 [(set (match_operand:DI 0 "register_operand" "=r")
2582 (match_operand:DI 1 "const_int_operand" "i"))
2583 (clobber (reg:CC FLAGS_REG))]
2586 && operands[1] == constm1_rtx"
2588 operands[1] = constm1_rtx;
2589 return "or{q}\t{%1, %0|%0, %1}";
2591 [(set_attr "type" "alu1")
2592 (set_attr "mode" "DI")
2593 (set_attr "length_immediate" "1")])
2595 (define_insn "*movdi_2"
2596 [(set (match_operand:DI 0 "nonimmediate_operand"
2597 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2598 (match_operand:DI 1 "general_operand"
2599 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2600 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2605 movq\t{%1, %0|%0, %1}
2606 movq\t{%1, %0|%0, %1}
2608 %vmovq\t{%1, %0|%0, %1}
2609 %vmovdqa\t{%1, %0|%0, %1}
2610 %vmovq\t{%1, %0|%0, %1}
2612 movlps\t{%1, %0|%0, %1}
2613 movaps\t{%1, %0|%0, %1}
2614 movlps\t{%1, %0|%0, %1}"
2615 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2616 (set (attr "prefix")
2617 (if_then_else (eq_attr "alternative" "5,6,7,8")
2618 (const_string "vex")
2619 (const_string "orig")))
2620 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2623 [(set (match_operand:DI 0 "push_operand" "")
2624 (match_operand:DI 1 "general_operand" ""))]
2625 "!TARGET_64BIT && reload_completed
2626 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2628 "ix86_split_long_move (operands); DONE;")
2630 ;; %%% This multiword shite has got to go.
2632 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2633 (match_operand:DI 1 "general_operand" ""))]
2634 "!TARGET_64BIT && reload_completed
2635 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2636 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2638 "ix86_split_long_move (operands); DONE;")
2640 (define_insn "*movdi_1_rex64"
2641 [(set (match_operand:DI 0 "nonimmediate_operand"
2642 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2643 (match_operand:DI 1 "general_operand"
2644 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2645 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2647 switch (get_attr_type (insn))
2650 if (SSE_REG_P (operands[0]))
2651 return "movq2dq\t{%1, %0|%0, %1}";
2653 return "movdq2q\t{%1, %0|%0, %1}";
2658 if (get_attr_mode (insn) == MODE_TI)
2659 return "vmovdqa\t{%1, %0|%0, %1}";
2661 return "vmovq\t{%1, %0|%0, %1}";
2664 if (get_attr_mode (insn) == MODE_TI)
2665 return "movdqa\t{%1, %0|%0, %1}";
2669 /* Moves from and into integer register is done using movd
2670 opcode with REX prefix. */
2671 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2672 return "movd\t{%1, %0|%0, %1}";
2673 return "movq\t{%1, %0|%0, %1}";
2676 return "%vpxor\t%0, %d0";
2679 return "pxor\t%0, %0";
2685 return "lea{q}\t{%a1, %0|%0, %a1}";
2688 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2689 if (get_attr_mode (insn) == MODE_SI)
2690 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2691 else if (which_alternative == 2)
2692 return "movabs{q}\t{%1, %0|%0, %1}";
2694 return "mov{q}\t{%1, %0|%0, %1}";
2698 (cond [(eq_attr "alternative" "5")
2699 (const_string "mmx")
2700 (eq_attr "alternative" "6,7,8,9,10")
2701 (const_string "mmxmov")
2702 (eq_attr "alternative" "11")
2703 (const_string "sselog1")
2704 (eq_attr "alternative" "12,13,14,15,16")
2705 (const_string "ssemov")
2706 (eq_attr "alternative" "17,18")
2707 (const_string "ssecvt")
2708 (eq_attr "alternative" "4")
2709 (const_string "multi")
2710 (match_operand:DI 1 "pic_32bit_operand" "")
2711 (const_string "lea")
2713 (const_string "imov")))
2716 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2718 (const_string "*")))
2719 (set (attr "length_immediate")
2721 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2723 (const_string "*")))
2724 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2725 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2726 (set (attr "prefix")
2727 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2728 (const_string "maybe_vex")
2729 (const_string "orig")))
2730 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2732 ;; Stores and loads of ax to arbitrary constant address.
2733 ;; We fake an second form of instruction to force reload to load address
2734 ;; into register when rax is not available
2735 (define_insn "*movabsdi_1_rex64"
2736 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2737 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2738 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2740 movabs{q}\t{%1, %P0|%P0, %1}
2741 mov{q}\t{%1, %a0|%a0, %1}"
2742 [(set_attr "type" "imov")
2743 (set_attr "modrm" "0,*")
2744 (set_attr "length_address" "8,0")
2745 (set_attr "length_immediate" "0,*")
2746 (set_attr "memory" "store")
2747 (set_attr "mode" "DI")])
2749 (define_insn "*movabsdi_2_rex64"
2750 [(set (match_operand:DI 0 "register_operand" "=a,r")
2751 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2752 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2754 movabs{q}\t{%P1, %0|%0, %P1}
2755 mov{q}\t{%a1, %0|%0, %a1}"
2756 [(set_attr "type" "imov")
2757 (set_attr "modrm" "0,*")
2758 (set_attr "length_address" "8,0")
2759 (set_attr "length_immediate" "0")
2760 (set_attr "memory" "load")
2761 (set_attr "mode" "DI")])
2763 ;; Convert impossible stores of immediate to existing instructions.
2764 ;; First try to get scratch register and go through it. In case this
2765 ;; fails, move by 32bit parts.
2767 [(match_scratch:DI 2 "r")
2768 (set (match_operand:DI 0 "memory_operand" "")
2769 (match_operand:DI 1 "immediate_operand" ""))]
2770 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2771 && !x86_64_immediate_operand (operands[1], DImode)"
2772 [(set (match_dup 2) (match_dup 1))
2773 (set (match_dup 0) (match_dup 2))]
2776 ;; We need to define this as both peepholer and splitter for case
2777 ;; peephole2 pass is not run.
2778 ;; "&& 1" is needed to keep it from matching the previous pattern.
2780 [(set (match_operand:DI 0 "memory_operand" "")
2781 (match_operand:DI 1 "immediate_operand" ""))]
2782 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2783 && !x86_64_immediate_operand (operands[1], DImode) && 1"
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]);")
2789 [(set (match_operand:DI 0 "memory_operand" "")
2790 (match_operand:DI 1 "immediate_operand" ""))]
2791 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2792 ? epilogue_completed : reload_completed)
2793 && !symbolic_operand (operands[1], DImode)
2794 && !x86_64_immediate_operand (operands[1], DImode)"
2795 [(set (match_dup 2) (match_dup 3))
2796 (set (match_dup 4) (match_dup 5))]
2797 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2799 (define_insn "*swapdi_rex64"
2800 [(set (match_operand:DI 0 "register_operand" "+r")
2801 (match_operand:DI 1 "register_operand" "+r"))
2806 [(set_attr "type" "imov")
2807 (set_attr "mode" "DI")
2808 (set_attr "pent_pair" "np")
2809 (set_attr "athlon_decode" "vector")
2810 (set_attr "amdfam10_decode" "double")])
2812 (define_expand "movoi"
2813 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2814 (match_operand:OI 1 "general_operand" ""))]
2816 "ix86_expand_move (OImode, operands); DONE;")
2818 (define_insn "*movoi_internal"
2819 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2820 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2822 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2824 switch (which_alternative)
2827 return "vxorps\t%0, %0, %0";
2830 if (misaligned_operand (operands[0], OImode)
2831 || misaligned_operand (operands[1], OImode))
2832 return "vmovdqu\t{%1, %0|%0, %1}";
2834 return "vmovdqa\t{%1, %0|%0, %1}";
2839 [(set_attr "type" "sselog1,ssemov,ssemov")
2840 (set_attr "prefix" "vex")
2841 (set_attr "mode" "OI")])
2843 (define_expand "movti"
2844 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2845 (match_operand:TI 1 "nonimmediate_operand" ""))]
2846 "TARGET_SSE || TARGET_64BIT"
2849 ix86_expand_move (TImode, operands);
2850 else if (push_operand (operands[0], TImode))
2851 ix86_expand_push (TImode, operands[1]);
2853 ix86_expand_vector_move (TImode, operands);
2857 (define_insn "*movti_internal"
2858 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2859 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2860 "TARGET_SSE && !TARGET_64BIT
2861 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2863 switch (which_alternative)
2866 if (get_attr_mode (insn) == MODE_V4SF)
2867 return "%vxorps\t%0, %d0";
2869 return "%vpxor\t%0, %d0";
2872 /* TDmode values are passed as TImode on the stack. Moving them
2873 to stack may result in unaligned memory access. */
2874 if (misaligned_operand (operands[0], TImode)
2875 || misaligned_operand (operands[1], TImode))
2877 if (get_attr_mode (insn) == MODE_V4SF)
2878 return "%vmovups\t{%1, %0|%0, %1}";
2880 return "%vmovdqu\t{%1, %0|%0, %1}";
2884 if (get_attr_mode (insn) == MODE_V4SF)
2885 return "%vmovaps\t{%1, %0|%0, %1}";
2887 return "%vmovdqa\t{%1, %0|%0, %1}";
2893 [(set_attr "type" "sselog1,ssemov,ssemov")
2894 (set_attr "prefix" "maybe_vex")
2896 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2897 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2898 (const_string "V4SF")
2899 (and (eq_attr "alternative" "2")
2900 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2902 (const_string "V4SF")]
2903 (const_string "TI")))])
2905 (define_insn "*movti_rex64"
2906 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2907 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2911 switch (which_alternative)
2917 if (get_attr_mode (insn) == MODE_V4SF)
2918 return "%vxorps\t%0, %d0";
2920 return "%vpxor\t%0, %d0";
2923 /* TDmode values are passed as TImode on the stack. Moving them
2924 to stack may result in unaligned memory access. */
2925 if (misaligned_operand (operands[0], TImode)
2926 || misaligned_operand (operands[1], TImode))
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "%vmovups\t{%1, %0|%0, %1}";
2931 return "%vmovdqu\t{%1, %0|%0, %1}";
2935 if (get_attr_mode (insn) == MODE_V4SF)
2936 return "%vmovaps\t{%1, %0|%0, %1}";
2938 return "%vmovdqa\t{%1, %0|%0, %1}";
2944 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2945 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2947 (cond [(eq_attr "alternative" "2,3")
2949 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2951 (const_string "V4SF")
2952 (const_string "TI"))
2953 (eq_attr "alternative" "4")
2955 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2957 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2959 (const_string "V4SF")
2960 (const_string "TI"))]
2961 (const_string "DI")))])
2964 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2965 (match_operand:TI 1 "general_operand" ""))]
2966 "reload_completed && !SSE_REG_P (operands[0])
2967 && !SSE_REG_P (operands[1])"
2969 "ix86_split_long_move (operands); DONE;")
2971 ;; This expands to what emit_move_complex would generate if we didn't
2972 ;; have a movti pattern. Having this avoids problems with reload on
2973 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2974 ;; to have around all the time.
2975 (define_expand "movcdi"
2976 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2977 (match_operand:CDI 1 "general_operand" ""))]
2980 if (push_operand (operands[0], CDImode))
2981 emit_move_complex_push (CDImode, operands[0], operands[1]);
2983 emit_move_complex_parts (operands[0], operands[1]);
2987 (define_expand "movsf"
2988 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2989 (match_operand:SF 1 "general_operand" ""))]
2991 "ix86_expand_move (SFmode, operands); DONE;")
2993 (define_insn "*pushsf"
2994 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2995 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2998 /* Anything else should be already split before reg-stack. */
2999 gcc_assert (which_alternative == 1);
3000 return "push{l}\t%1";
3002 [(set_attr "type" "multi,push,multi")
3003 (set_attr "unit" "i387,*,*")
3004 (set_attr "mode" "SF,SI,SF")])
3006 (define_insn "*pushsf_rex64"
3007 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3008 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3011 /* Anything else should be already split before reg-stack. */
3012 gcc_assert (which_alternative == 1);
3013 return "push{q}\t%q1";
3015 [(set_attr "type" "multi,push,multi")
3016 (set_attr "unit" "i387,*,*")
3017 (set_attr "mode" "SF,DI,SF")])
3020 [(set (match_operand:SF 0 "push_operand" "")
3021 (match_operand:SF 1 "memory_operand" ""))]
3023 && MEM_P (operands[1])
3024 && (operands[2] = find_constant_src (insn))"
3028 ;; %%% Kill this when call knows how to work this out.
3030 [(set (match_operand:SF 0 "push_operand" "")
3031 (match_operand:SF 1 "any_fp_register_operand" ""))]
3033 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3034 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3037 [(set (match_operand:SF 0 "push_operand" "")
3038 (match_operand:SF 1 "any_fp_register_operand" ""))]
3040 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3041 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3043 (define_insn "*movsf_1"
3044 [(set (match_operand:SF 0 "nonimmediate_operand"
3045 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3046 (match_operand:SF 1 "general_operand"
3047 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3048 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3049 && (reload_in_progress || reload_completed
3050 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3051 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3052 && standard_80387_constant_p (operands[1]))
3053 || GET_CODE (operands[1]) != CONST_DOUBLE
3054 || memory_operand (operands[0], SFmode))"
3056 switch (which_alternative)
3060 return output_387_reg_move (insn, operands);
3063 return standard_80387_constant_opcode (operands[1]);
3067 return "mov{l}\t{%1, %0|%0, %1}";
3069 if (get_attr_mode (insn) == MODE_TI)
3070 return "%vpxor\t%0, %d0";
3072 return "%vxorps\t%0, %d0";
3074 if (get_attr_mode (insn) == MODE_V4SF)
3075 return "%vmovaps\t{%1, %0|%0, %1}";
3077 return "%vmovss\t{%1, %d0|%d0, %1}";
3080 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3081 : "vmovss\t{%1, %0|%0, %1}";
3083 return "movss\t{%1, %0|%0, %1}";
3085 return "%vmovss\t{%1, %0|%0, %1}";
3087 case 9: case 10: case 14: case 15:
3088 return "movd\t{%1, %0|%0, %1}";
3090 return "%vmovd\t{%1, %0|%0, %1}";
3093 return "movq\t{%1, %0|%0, %1}";
3099 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3100 (set (attr "prefix")
3101 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3102 (const_string "maybe_vex")
3103 (const_string "orig")))
3105 (cond [(eq_attr "alternative" "3,4,9,10")
3107 (eq_attr "alternative" "5")
3109 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3111 (ne (symbol_ref "TARGET_SSE2")
3113 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3116 (const_string "V4SF"))
3117 /* For architectures resolving dependencies on
3118 whole SSE registers use APS move to break dependency
3119 chains, otherwise use short move to avoid extra work.
3121 Do the same for architectures resolving dependencies on
3122 the parts. While in DF mode it is better to always handle
3123 just register parts, the SF mode is different due to lack
3124 of instructions to load just part of the register. It is
3125 better to maintain the whole registers in single format
3126 to avoid problems on using packed logical operations. */
3127 (eq_attr "alternative" "6")
3129 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3131 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3133 (const_string "V4SF")
3134 (const_string "SF"))
3135 (eq_attr "alternative" "11")
3136 (const_string "DI")]
3137 (const_string "SF")))])
3139 (define_insn "*swapsf"
3140 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3141 (match_operand:SF 1 "fp_register_operand" "+f"))
3144 "reload_completed || TARGET_80387"
3146 if (STACK_TOP_P (operands[0]))
3151 [(set_attr "type" "fxch")
3152 (set_attr "mode" "SF")])
3154 (define_expand "movdf"
3155 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3156 (match_operand:DF 1 "general_operand" ""))]
3158 "ix86_expand_move (DFmode, operands); DONE;")
3160 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3161 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3162 ;; On the average, pushdf using integers can be still shorter. Allow this
3163 ;; pattern for optimize_size too.
3165 (define_insn "*pushdf_nointeger"
3166 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3167 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3168 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3170 /* This insn should be already split before reg-stack. */
3173 [(set_attr "type" "multi")
3174 (set_attr "unit" "i387,*,*,*")
3175 (set_attr "mode" "DF,SI,SI,DF")])
3177 (define_insn "*pushdf_integer"
3178 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3179 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3180 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3182 /* This insn should be already split before reg-stack. */
3185 [(set_attr "type" "multi")
3186 (set_attr "unit" "i387,*,*")
3187 (set_attr "mode" "DF,SI,DF")])
3189 ;; %%% Kill this when call knows how to work this out.
3191 [(set (match_operand:DF 0 "push_operand" "")
3192 (match_operand:DF 1 "any_fp_register_operand" ""))]
3194 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3195 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3199 [(set (match_operand:DF 0 "push_operand" "")
3200 (match_operand:DF 1 "general_operand" ""))]
3203 "ix86_split_long_move (operands); DONE;")
3205 ;; Moving is usually shorter when only FP registers are used. This separate
3206 ;; movdf pattern avoids the use of integer registers for FP operations
3207 ;; when optimizing for size.
3209 (define_insn "*movdf_nointeger"
3210 [(set (match_operand:DF 0 "nonimmediate_operand"
3211 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3212 (match_operand:DF 1 "general_operand"
3213 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3214 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3215 && ((optimize_function_for_size_p (cfun)
3216 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3217 && (reload_in_progress || reload_completed
3218 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3219 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3220 && optimize_function_for_size_p (cfun)
3221 && !memory_operand (operands[0], DFmode)
3222 && standard_80387_constant_p (operands[1]))
3223 || GET_CODE (operands[1]) != CONST_DOUBLE
3224 || ((optimize_function_for_size_p (cfun)
3225 || !TARGET_MEMORY_MISMATCH_STALL
3226 || reload_in_progress || reload_completed)
3227 && memory_operand (operands[0], DFmode)))"
3229 switch (which_alternative)
3233 return output_387_reg_move (insn, operands);
3236 return standard_80387_constant_opcode (operands[1]);
3242 switch (get_attr_mode (insn))
3245 return "%vxorps\t%0, %d0";
3247 return "%vxorpd\t%0, %d0";
3249 return "%vpxor\t%0, %d0";
3256 switch (get_attr_mode (insn))
3259 return "%vmovaps\t{%1, %0|%0, %1}";
3261 return "%vmovapd\t{%1, %0|%0, %1}";
3263 return "%vmovdqa\t{%1, %0|%0, %1}";
3265 return "%vmovq\t{%1, %0|%0, %1}";
3269 if (REG_P (operands[0]) && REG_P (operands[1]))
3270 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3272 return "vmovsd\t{%1, %0|%0, %1}";
3275 return "movsd\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]))
3280 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovlpd\t{%1, %0|%0, %1}";
3285 return "movlpd\t{%1, %0|%0, %1}";
3289 if (REG_P (operands[0]))
3290 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3292 return "vmovlps\t{%1, %0|%0, %1}";
3295 return "movlps\t{%1, %0|%0, %1}";
3304 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305 (set (attr "prefix")
3306 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307 (const_string "orig")
3308 (const_string "maybe_vex")))
3309 (set (attr "prefix_data16")
3310 (if_then_else (eq_attr "mode" "V1DF")
3312 (const_string "*")))
3314 (cond [(eq_attr "alternative" "0,1,2")
3316 (eq_attr "alternative" "3,4")
3319 /* For SSE1, we have many fewer alternatives. */
3320 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321 (cond [(eq_attr "alternative" "5,6")
3322 (const_string "V4SF")
3324 (const_string "V2SF"))
3326 /* xorps is one byte shorter. */
3327 (eq_attr "alternative" "5")
3328 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3330 (const_string "V4SF")
3331 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3335 (const_string "V2DF"))
3337 /* For architectures resolving dependencies on
3338 whole SSE registers use APD move to break dependency
3339 chains, otherwise use short move to avoid extra work.
3341 movaps encodes one byte shorter. */
3342 (eq_attr "alternative" "6")
3344 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3346 (const_string "V4SF")
3347 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3349 (const_string "V2DF")
3351 (const_string "DF"))
3352 /* For architectures resolving dependencies on register
3353 parts we may avoid extra work to zero out upper part
3355 (eq_attr "alternative" "7")
3357 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3359 (const_string "V1DF")
3360 (const_string "DF"))
3362 (const_string "DF")))])
3364 (define_insn "*movdf_integer_rex64"
3365 [(set (match_operand:DF 0 "nonimmediate_operand"
3366 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3367 (match_operand:DF 1 "general_operand"
3368 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3369 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3370 && (reload_in_progress || reload_completed
3371 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3372 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3373 && optimize_function_for_size_p (cfun)
3374 && standard_80387_constant_p (operands[1]))
3375 || GET_CODE (operands[1]) != CONST_DOUBLE
3376 || memory_operand (operands[0], DFmode))"
3378 switch (which_alternative)
3382 return output_387_reg_move (insn, operands);
3385 return standard_80387_constant_opcode (operands[1]);
3392 switch (get_attr_mode (insn))
3395 return "%vxorps\t%0, %d0";
3397 return "%vxorpd\t%0, %d0";
3399 return "%vpxor\t%0, %d0";
3406 switch (get_attr_mode (insn))
3409 return "%vmovaps\t{%1, %0|%0, %1}";
3411 return "%vmovapd\t{%1, %0|%0, %1}";
3413 return "%vmovdqa\t{%1, %0|%0, %1}";
3415 return "%vmovq\t{%1, %0|%0, %1}";
3419 if (REG_P (operands[0]) && REG_P (operands[1]))
3420 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3422 return "vmovsd\t{%1, %0|%0, %1}";
3425 return "movsd\t{%1, %0|%0, %1}";
3427 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3429 return "%vmovlps\t{%1, %d0|%d0, %1}";
3436 return "%vmovd\t{%1, %0|%0, %1}";
3442 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3443 (set (attr "prefix")
3444 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3445 (const_string "orig")
3446 (const_string "maybe_vex")))
3447 (set (attr "prefix_data16")
3448 (if_then_else (eq_attr "mode" "V1DF")
3450 (const_string "*")))
3452 (cond [(eq_attr "alternative" "0,1,2")
3454 (eq_attr "alternative" "3,4,9,10")
3457 /* For SSE1, we have many fewer alternatives. */
3458 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3459 (cond [(eq_attr "alternative" "5,6")
3460 (const_string "V4SF")
3462 (const_string "V2SF"))
3464 /* xorps is one byte shorter. */
3465 (eq_attr "alternative" "5")
3466 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3468 (const_string "V4SF")
3469 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3473 (const_string "V2DF"))
3475 /* For architectures resolving dependencies on
3476 whole SSE registers use APD move to break dependency
3477 chains, otherwise use short move to avoid extra work.
3479 movaps encodes one byte shorter. */
3480 (eq_attr "alternative" "6")
3482 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3484 (const_string "V4SF")
3485 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3487 (const_string "V2DF")
3489 (const_string "DF"))
3490 /* For architectures resolving dependencies on register
3491 parts we may avoid extra work to zero out upper part
3493 (eq_attr "alternative" "7")
3495 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3497 (const_string "V1DF")
3498 (const_string "DF"))
3500 (const_string "DF")))])
3502 (define_insn "*movdf_integer"
3503 [(set (match_operand:DF 0 "nonimmediate_operand"
3504 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3505 (match_operand:DF 1 "general_operand"
3506 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3507 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3508 && optimize_function_for_speed_p (cfun)
3509 && TARGET_INTEGER_DFMODE_MOVES
3510 && (reload_in_progress || reload_completed
3511 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3512 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3513 && optimize_function_for_size_p (cfun)
3514 && standard_80387_constant_p (operands[1]))
3515 || GET_CODE (operands[1]) != CONST_DOUBLE
3516 || memory_operand (operands[0], DFmode))"
3518 switch (which_alternative)
3522 return output_387_reg_move (insn, operands);
3525 return standard_80387_constant_opcode (operands[1]);
3532 switch (get_attr_mode (insn))
3535 return "xorps\t%0, %0";
3537 return "xorpd\t%0, %0";
3539 return "pxor\t%0, %0";
3546 switch (get_attr_mode (insn))
3549 return "movaps\t{%1, %0|%0, %1}";
3551 return "movapd\t{%1, %0|%0, %1}";
3553 return "movdqa\t{%1, %0|%0, %1}";
3555 return "movq\t{%1, %0|%0, %1}";
3557 return "movsd\t{%1, %0|%0, %1}";
3559 return "movlpd\t{%1, %0|%0, %1}";
3561 return "movlps\t{%1, %0|%0, %1}";
3570 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3571 (set (attr "prefix_data16")
3572 (if_then_else (eq_attr "mode" "V1DF")
3574 (const_string "*")))
3576 (cond [(eq_attr "alternative" "0,1,2")
3578 (eq_attr "alternative" "3,4")
3581 /* For SSE1, we have many fewer alternatives. */
3582 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3583 (cond [(eq_attr "alternative" "5,6")
3584 (const_string "V4SF")
3586 (const_string "V2SF"))
3588 /* xorps is one byte shorter. */
3589 (eq_attr "alternative" "5")
3590 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3592 (const_string "V4SF")
3593 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3597 (const_string "V2DF"))
3599 /* For architectures resolving dependencies on
3600 whole SSE registers use APD move to break dependency
3601 chains, otherwise use short move to avoid extra work.
3603 movaps encodes one byte shorter. */
3604 (eq_attr "alternative" "6")
3606 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3608 (const_string "V4SF")
3609 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3611 (const_string "V2DF")
3613 (const_string "DF"))
3614 /* For architectures resolving dependencies on register
3615 parts we may avoid extra work to zero out upper part
3617 (eq_attr "alternative" "7")
3619 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3621 (const_string "V1DF")
3622 (const_string "DF"))
3624 (const_string "DF")))])
3627 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3628 (match_operand:DF 1 "general_operand" ""))]
3630 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3631 && ! (ANY_FP_REG_P (operands[0]) ||
3632 (GET_CODE (operands[0]) == SUBREG
3633 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3634 && ! (ANY_FP_REG_P (operands[1]) ||
3635 (GET_CODE (operands[1]) == SUBREG
3636 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3638 "ix86_split_long_move (operands); DONE;")
3640 (define_insn "*swapdf"
3641 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3642 (match_operand:DF 1 "fp_register_operand" "+f"))
3645 "reload_completed || TARGET_80387"
3647 if (STACK_TOP_P (operands[0]))
3652 [(set_attr "type" "fxch")
3653 (set_attr "mode" "DF")])
3655 (define_expand "movxf"
3656 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3657 (match_operand:XF 1 "general_operand" ""))]
3659 "ix86_expand_move (XFmode, operands); DONE;")
3661 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3662 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3663 ;; Pushing using integer instructions is longer except for constants
3664 ;; and direct memory references.
3665 ;; (assuming that any given constant is pushed only once, but this ought to be
3666 ;; handled elsewhere).
3668 (define_insn "*pushxf_nointeger"
3669 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3670 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3671 "optimize_function_for_size_p (cfun)"
3673 /* This insn should be already split before reg-stack. */
3676 [(set_attr "type" "multi")
3677 (set_attr "unit" "i387,*,*")
3678 (set_attr "mode" "XF,SI,SI")])
3680 (define_insn "*pushxf_integer"
3681 [(set (match_operand:XF 0 "push_operand" "=<,<")
3682 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3683 "optimize_function_for_speed_p (cfun)"
3685 /* This insn should be already split before reg-stack. */
3688 [(set_attr "type" "multi")
3689 (set_attr "unit" "i387,*")
3690 (set_attr "mode" "XF,SI")])
3693 [(set (match_operand 0 "push_operand" "")
3694 (match_operand 1 "general_operand" ""))]
3696 && (GET_MODE (operands[0]) == XFmode
3697 || GET_MODE (operands[0]) == DFmode)
3698 && !ANY_FP_REG_P (operands[1])"
3700 "ix86_split_long_move (operands); DONE;")
3703 [(set (match_operand:XF 0 "push_operand" "")
3704 (match_operand:XF 1 "any_fp_register_operand" ""))]
3706 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3707 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3708 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3710 ;; Do not use integer registers when optimizing for size
3711 (define_insn "*movxf_nointeger"
3712 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3713 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3714 "optimize_function_for_size_p (cfun)
3715 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3716 && (reload_in_progress || reload_completed
3717 || standard_80387_constant_p (operands[1])
3718 || GET_CODE (operands[1]) != CONST_DOUBLE
3719 || memory_operand (operands[0], XFmode))"
3721 switch (which_alternative)
3725 return output_387_reg_move (insn, operands);
3728 return standard_80387_constant_opcode (operands[1]);
3736 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3737 (set_attr "mode" "XF,XF,XF,SI,SI")])
3739 (define_insn "*movxf_integer"
3740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3741 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3742 "optimize_function_for_speed_p (cfun)
3743 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3744 && (reload_in_progress || reload_completed
3745 || GET_CODE (operands[1]) != CONST_DOUBLE
3746 || memory_operand (operands[0], XFmode))"
3748 switch (which_alternative)
3752 return output_387_reg_move (insn, operands);
3755 return standard_80387_constant_opcode (operands[1]);
3764 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3765 (set_attr "mode" "XF,XF,XF,SI,SI")])
3767 (define_expand "movtf"
3768 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3769 (match_operand:TF 1 "nonimmediate_operand" ""))]
3772 ix86_expand_move (TFmode, operands);
3776 (define_insn "*movtf_internal"
3777 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3778 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3780 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3782 switch (which_alternative)
3786 if (get_attr_mode (insn) == MODE_V4SF)
3787 return "%vmovaps\t{%1, %0|%0, %1}";
3789 return "%vmovdqa\t{%1, %0|%0, %1}";
3791 if (get_attr_mode (insn) == MODE_V4SF)
3792 return "%vxorps\t%0, %d0";
3794 return "%vpxor\t%0, %d0";
3802 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3803 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3805 (cond [(eq_attr "alternative" "0,2")
3807 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3809 (const_string "V4SF")
3810 (const_string "TI"))
3811 (eq_attr "alternative" "1")
3813 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3815 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3817 (const_string "V4SF")
3818 (const_string "TI"))]
3819 (const_string "DI")))])
3821 (define_insn "*pushtf_sse"
3822 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3823 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3826 /* This insn should be already split before reg-stack. */
3829 [(set_attr "type" "multi")
3830 (set_attr "unit" "sse,*,*")
3831 (set_attr "mode" "TF,SI,SI")])
3834 [(set (match_operand:TF 0 "push_operand" "")
3835 (match_operand:TF 1 "general_operand" ""))]
3836 "TARGET_SSE2 && reload_completed
3837 && !SSE_REG_P (operands[1])"
3839 "ix86_split_long_move (operands); DONE;")
3842 [(set (match_operand:TF 0 "push_operand" "")
3843 (match_operand:TF 1 "any_fp_register_operand" ""))]
3845 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3846 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3850 [(set (match_operand 0 "nonimmediate_operand" "")
3851 (match_operand 1 "general_operand" ""))]
3853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3854 && GET_MODE (operands[0]) == XFmode
3855 && ! (ANY_FP_REG_P (operands[0]) ||
3856 (GET_CODE (operands[0]) == SUBREG
3857 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3858 && ! (ANY_FP_REG_P (operands[1]) ||
3859 (GET_CODE (operands[1]) == SUBREG
3860 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3862 "ix86_split_long_move (operands); DONE;")
3865 [(set (match_operand 0 "register_operand" "")
3866 (match_operand 1 "memory_operand" ""))]
3868 && MEM_P (operands[1])
3869 && (GET_MODE (operands[0]) == TFmode
3870 || GET_MODE (operands[0]) == XFmode
3871 || GET_MODE (operands[0]) == SFmode
3872 || GET_MODE (operands[0]) == DFmode)
3873 && (operands[2] = find_constant_src (insn))"
3874 [(set (match_dup 0) (match_dup 2))]
3876 rtx c = operands[2];
3877 rtx r = operands[0];
3879 if (GET_CODE (r) == SUBREG)
3884 if (!standard_sse_constant_p (c))
3887 else if (FP_REG_P (r))
3889 if (!standard_80387_constant_p (c))
3892 else if (MMX_REG_P (r))
3897 [(set (match_operand 0 "register_operand" "")
3898 (float_extend (match_operand 1 "memory_operand" "")))]
3900 && MEM_P (operands[1])
3901 && (GET_MODE (operands[0]) == TFmode
3902 || GET_MODE (operands[0]) == XFmode
3903 || GET_MODE (operands[0]) == SFmode
3904 || GET_MODE (operands[0]) == DFmode)
3905 && (operands[2] = find_constant_src (insn))"
3906 [(set (match_dup 0) (match_dup 2))]
3908 rtx c = operands[2];
3909 rtx r = operands[0];
3911 if (GET_CODE (r) == SUBREG)
3916 if (!standard_sse_constant_p (c))
3919 else if (FP_REG_P (r))
3921 if (!standard_80387_constant_p (c))
3924 else if (MMX_REG_P (r))
3928 (define_insn "swapxf"
3929 [(set (match_operand:XF 0 "register_operand" "+f")
3930 (match_operand:XF 1 "register_operand" "+f"))
3935 if (STACK_TOP_P (operands[0]))
3940 [(set_attr "type" "fxch")
3941 (set_attr "mode" "XF")])
3943 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3945 [(set (match_operand:X87MODEF 0 "register_operand" "")
3946 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3947 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3948 && (standard_80387_constant_p (operands[1]) == 8
3949 || standard_80387_constant_p (operands[1]) == 9)"
3950 [(set (match_dup 0)(match_dup 1))
3952 (neg:X87MODEF (match_dup 0)))]
3956 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3957 if (real_isnegzero (&r))
3958 operands[1] = CONST0_RTX (<MODE>mode);
3960 operands[1] = CONST1_RTX (<MODE>mode);
3964 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3965 (match_operand:TF 1 "general_operand" ""))]
3967 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3969 "ix86_split_long_move (operands); DONE;")
3971 ;; Zero extension instructions
3973 (define_expand "zero_extendhisi2"
3974 [(set (match_operand:SI 0 "register_operand" "")
3975 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3978 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3980 operands[1] = force_reg (HImode, operands[1]);
3981 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3986 (define_insn "zero_extendhisi2_and"
3987 [(set (match_operand:SI 0 "register_operand" "=r")
3988 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3989 (clobber (reg:CC FLAGS_REG))]
3990 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3992 [(set_attr "type" "alu1")
3993 (set_attr "mode" "SI")])
3996 [(set (match_operand:SI 0 "register_operand" "")
3997 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3998 (clobber (reg:CC FLAGS_REG))]
3999 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
4000 && optimize_function_for_speed_p (cfun)"
4001 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
4002 (clobber (reg:CC FLAGS_REG))])]
4005 (define_insn "*zero_extendhisi2_movzwl"
4006 [(set (match_operand:SI 0 "register_operand" "=r")
4007 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4008 "!TARGET_ZERO_EXTEND_WITH_AND
4009 || optimize_function_for_size_p (cfun)"
4010 "movz{wl|x}\t{%1, %0|%0, %1}"
4011 [(set_attr "type" "imovx")
4012 (set_attr "mode" "SI")])
4014 (define_expand "zero_extendqihi2"
4016 [(set (match_operand:HI 0 "register_operand" "")
4017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4018 (clobber (reg:CC FLAGS_REG))])]
4022 (define_insn "*zero_extendqihi2_and"
4023 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4024 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4025 (clobber (reg:CC FLAGS_REG))]
4026 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4028 [(set_attr "type" "alu1")
4029 (set_attr "mode" "HI")])
4031 (define_insn "*zero_extendqihi2_movzbw_and"
4032 [(set (match_operand:HI 0 "register_operand" "=r,r")
4033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4034 (clobber (reg:CC FLAGS_REG))]
4035 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4037 [(set_attr "type" "imovx,alu1")
4038 (set_attr "mode" "HI")])
4040 ; zero extend to SImode here to avoid partial register stalls
4041 (define_insn "*zero_extendqihi2_movzbl"
4042 [(set (match_operand:HI 0 "register_operand" "=r")
4043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4044 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4045 && reload_completed"
4046 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4047 [(set_attr "type" "imovx")
4048 (set_attr "mode" "SI")])
4050 ;; For the movzbw case strip only the clobber
4052 [(set (match_operand:HI 0 "register_operand" "")
4053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4054 (clobber (reg:CC FLAGS_REG))]
4056 && (!TARGET_ZERO_EXTEND_WITH_AND
4057 || optimize_function_for_size_p (cfun))
4058 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4059 [(set (match_operand:HI 0 "register_operand" "")
4060 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4062 ;; When source and destination does not overlap, clear destination
4063 ;; first and then do the movb
4065 [(set (match_operand:HI 0 "register_operand" "")
4066 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4067 (clobber (reg:CC FLAGS_REG))]
4069 && ANY_QI_REG_P (operands[0])
4070 && (TARGET_ZERO_EXTEND_WITH_AND
4071 && optimize_function_for_speed_p (cfun))
4072 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4073 [(set (match_dup 0) (const_int 0))
4074 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4075 "operands[2] = gen_lowpart (QImode, operands[0]);")
4077 ;; Rest is handled by single and.
4079 [(set (match_operand:HI 0 "register_operand" "")
4080 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))]
4083 && true_regnum (operands[0]) == true_regnum (operands[1])"
4084 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4085 (clobber (reg:CC FLAGS_REG))])]
4088 (define_expand "zero_extendqisi2"
4090 [(set (match_operand:SI 0 "register_operand" "")
4091 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4092 (clobber (reg:CC FLAGS_REG))])]
4096 (define_insn "*zero_extendqisi2_and"
4097 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4099 (clobber (reg:CC FLAGS_REG))]
4100 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4102 [(set_attr "type" "alu1")
4103 (set_attr "mode" "SI")])
4105 (define_insn "*zero_extendqisi2_movzbw_and"
4106 [(set (match_operand:SI 0 "register_operand" "=r,r")
4107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4108 (clobber (reg:CC FLAGS_REG))]
4109 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4111 [(set_attr "type" "imovx,alu1")
4112 (set_attr "mode" "SI")])
4114 (define_insn "*zero_extendqisi2_movzbw"
4115 [(set (match_operand:SI 0 "register_operand" "=r")
4116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4117 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4118 && reload_completed"
4119 "movz{bl|x}\t{%1, %0|%0, %1}"
4120 [(set_attr "type" "imovx")
4121 (set_attr "mode" "SI")])
4123 ;; For the movzbl case strip only the clobber
4125 [(set (match_operand:SI 0 "register_operand" "")
4126 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4127 (clobber (reg:CC FLAGS_REG))]
4129 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4130 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4132 (zero_extend:SI (match_dup 1)))])
4134 ;; When source and destination does not overlap, clear destination
4135 ;; first and then do the movb
4137 [(set (match_operand:SI 0 "register_operand" "")
4138 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4139 (clobber (reg:CC FLAGS_REG))]
4141 && ANY_QI_REG_P (operands[0])
4142 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4143 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4144 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4145 [(set (match_dup 0) (const_int 0))
4146 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4147 "operands[2] = gen_lowpart (QImode, operands[0]);")
4149 ;; Rest is handled by single and.
4151 [(set (match_operand:SI 0 "register_operand" "")
4152 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4153 (clobber (reg:CC FLAGS_REG))]
4155 && true_regnum (operands[0]) == true_regnum (operands[1])"
4156 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4157 (clobber (reg:CC FLAGS_REG))])]
4160 ;; %%% Kill me once multi-word ops are sane.
4161 (define_expand "zero_extendsidi2"
4162 [(set (match_operand:DI 0 "register_operand" "")
4163 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4168 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4173 (define_insn "zero_extendsidi2_32"
4174 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4176 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4177 (clobber (reg:CC FLAGS_REG))]
4183 movd\t{%1, %0|%0, %1}
4184 movd\t{%1, %0|%0, %1}
4185 %vmovd\t{%1, %0|%0, %1}
4186 %vmovd\t{%1, %0|%0, %1}"
4187 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4188 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4189 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4191 (define_insn "zero_extendsidi2_rex64"
4192 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4194 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4197 mov\t{%k1, %k0|%k0, %k1}
4199 movd\t{%1, %0|%0, %1}
4200 movd\t{%1, %0|%0, %1}
4201 %vmovd\t{%1, %0|%0, %1}
4202 %vmovd\t{%1, %0|%0, %1}"
4203 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4204 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4205 (set_attr "prefix_0f" "0,*,*,*,*,*")
4206 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4209 [(set (match_operand:DI 0 "memory_operand" "")
4210 (zero_extend:DI (match_dup 0)))]
4212 [(set (match_dup 4) (const_int 0))]
4213 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4216 [(set (match_operand:DI 0 "register_operand" "")
4217 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4218 (clobber (reg:CC FLAGS_REG))]
4219 "!TARGET_64BIT && reload_completed
4220 && true_regnum (operands[0]) == true_regnum (operands[1])"
4221 [(set (match_dup 4) (const_int 0))]
4222 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4225 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))]
4228 "!TARGET_64BIT && reload_completed
4229 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4230 [(set (match_dup 3) (match_dup 1))
4231 (set (match_dup 4) (const_int 0))]
4232 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4234 (define_insn "zero_extendhidi2"
4235 [(set (match_operand:DI 0 "register_operand" "=r")
4236 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4238 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4239 [(set_attr "type" "imovx")
4240 (set_attr "mode" "SI")])
4242 (define_insn "zero_extendqidi2"
4243 [(set (match_operand:DI 0 "register_operand" "=r")
4244 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4246 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4247 [(set_attr "type" "imovx")
4248 (set_attr "mode" "SI")])
4250 ;; Sign extension instructions
4252 (define_expand "extendsidi2"
4253 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4254 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4255 (clobber (reg:CC FLAGS_REG))
4256 (clobber (match_scratch:SI 2 ""))])]
4261 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4266 (define_insn "*extendsidi2_1"
4267 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4268 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4269 (clobber (reg:CC FLAGS_REG))
4270 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4274 (define_insn "extendsidi2_rex64"
4275 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4276 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4280 movs{lq|x}\t{%1, %0|%0, %1}"
4281 [(set_attr "type" "imovx")
4282 (set_attr "mode" "DI")
4283 (set_attr "prefix_0f" "0")
4284 (set_attr "modrm" "0,1")])
4286 (define_insn "extendhidi2"
4287 [(set (match_operand:DI 0 "register_operand" "=r")
4288 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4290 "movs{wq|x}\t{%1, %0|%0, %1}"
4291 [(set_attr "type" "imovx")
4292 (set_attr "mode" "DI")])
4294 (define_insn "extendqidi2"
4295 [(set (match_operand:DI 0 "register_operand" "=r")
4296 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4298 "movs{bq|x}\t{%1, %0|%0, %1}"
4299 [(set_attr "type" "imovx")
4300 (set_attr "mode" "DI")])
4302 ;; Extend to memory case when source register does die.
4304 [(set (match_operand:DI 0 "memory_operand" "")
4305 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4306 (clobber (reg:CC FLAGS_REG))
4307 (clobber (match_operand:SI 2 "register_operand" ""))]
4309 && dead_or_set_p (insn, operands[1])
4310 && !reg_mentioned_p (operands[1], operands[0]))"
4311 [(set (match_dup 3) (match_dup 1))
4312 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4313 (clobber (reg:CC FLAGS_REG))])
4314 (set (match_dup 4) (match_dup 1))]
4315 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4317 ;; Extend to memory case when source register does not die.
4319 [(set (match_operand:DI 0 "memory_operand" "")
4320 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4321 (clobber (reg:CC FLAGS_REG))
4322 (clobber (match_operand:SI 2 "register_operand" ""))]
4326 split_di (&operands[0], 1, &operands[3], &operands[4]);
4328 emit_move_insn (operands[3], operands[1]);
4330 /* Generate a cltd if possible and doing so it profitable. */
4331 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4332 && true_regnum (operands[1]) == AX_REG
4333 && true_regnum (operands[2]) == DX_REG)
4335 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4339 emit_move_insn (operands[2], operands[1]);
4340 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4342 emit_move_insn (operands[4], operands[2]);
4346 ;; Extend to register case. Optimize case where source and destination
4347 ;; registers match and cases where we can use cltd.
4349 [(set (match_operand:DI 0 "register_operand" "")
4350 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4351 (clobber (reg:CC FLAGS_REG))
4352 (clobber (match_scratch:SI 2 ""))]
4356 split_di (&operands[0], 1, &operands[3], &operands[4]);
4358 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4359 emit_move_insn (operands[3], operands[1]);
4361 /* Generate a cltd if possible and doing so it profitable. */
4362 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4363 && true_regnum (operands[3]) == AX_REG)
4365 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4369 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4370 emit_move_insn (operands[4], operands[1]);
4372 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4376 (define_insn "extendhisi2"
4377 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4378 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4381 switch (get_attr_prefix_0f (insn))
4384 return "{cwtl|cwde}";
4386 return "movs{wl|x}\t{%1, %0|%0, %1}";
4389 [(set_attr "type" "imovx")
4390 (set_attr "mode" "SI")
4391 (set (attr "prefix_0f")
4392 ;; movsx is short decodable while cwtl is vector decoded.
4393 (if_then_else (and (eq_attr "cpu" "!k6")
4394 (eq_attr "alternative" "0"))
4396 (const_string "1")))
4398 (if_then_else (eq_attr "prefix_0f" "0")
4400 (const_string "1")))])
4402 (define_insn "*extendhisi2_zext"
4403 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4405 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4408 switch (get_attr_prefix_0f (insn))
4411 return "{cwtl|cwde}";
4413 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4416 [(set_attr "type" "imovx")
4417 (set_attr "mode" "SI")
4418 (set (attr "prefix_0f")
4419 ;; movsx is short decodable while cwtl is vector decoded.
4420 (if_then_else (and (eq_attr "cpu" "!k6")
4421 (eq_attr "alternative" "0"))
4423 (const_string "1")))
4425 (if_then_else (eq_attr "prefix_0f" "0")
4427 (const_string "1")))])
4429 (define_insn "extendqihi2"
4430 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4431 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4434 switch (get_attr_prefix_0f (insn))
4437 return "{cbtw|cbw}";
4439 return "movs{bw|x}\t{%1, %0|%0, %1}";
4442 [(set_attr "type" "imovx")
4443 (set_attr "mode" "HI")
4444 (set (attr "prefix_0f")
4445 ;; movsx is short decodable while cwtl is vector decoded.
4446 (if_then_else (and (eq_attr "cpu" "!k6")
4447 (eq_attr "alternative" "0"))
4449 (const_string "1")))
4451 (if_then_else (eq_attr "prefix_0f" "0")
4453 (const_string "1")))])
4455 (define_insn "extendqisi2"
4456 [(set (match_operand:SI 0 "register_operand" "=r")
4457 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4459 "movs{bl|x}\t{%1, %0|%0, %1}"
4460 [(set_attr "type" "imovx")
4461 (set_attr "mode" "SI")])
4463 (define_insn "*extendqisi2_zext"
4464 [(set (match_operand:DI 0 "register_operand" "=r")
4466 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4468 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4469 [(set_attr "type" "imovx")
4470 (set_attr "mode" "SI")])
4472 ;; Conversions between float and double.
4474 ;; These are all no-ops in the model used for the 80387. So just
4477 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4478 (define_insn "*dummy_extendsfdf2"
4479 [(set (match_operand:DF 0 "push_operand" "=<")
4480 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4485 [(set (match_operand:DF 0 "push_operand" "")
4486 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4488 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4489 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4491 (define_insn "*dummy_extendsfxf2"
4492 [(set (match_operand:XF 0 "push_operand" "=<")
4493 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4498 [(set (match_operand:XF 0 "push_operand" "")
4499 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4501 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4502 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4503 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4506 [(set (match_operand:XF 0 "push_operand" "")
4507 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4509 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4510 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4511 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4513 (define_expand "extendsfdf2"
4514 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4515 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4516 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4518 /* ??? Needed for compress_float_constant since all fp constants
4519 are LEGITIMATE_CONSTANT_P. */
4520 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4522 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4523 && standard_80387_constant_p (operands[1]) > 0)
4525 operands[1] = simplify_const_unary_operation
4526 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4527 emit_move_insn_1 (operands[0], operands[1]);
4530 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4534 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4536 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4538 We do the conversion post reload to avoid producing of 128bit spills
4539 that might lead to ICE on 32bit target. The sequence unlikely combine
4542 [(set (match_operand:DF 0 "register_operand" "")
4544 (match_operand:SF 1 "nonimmediate_operand" "")))]
4545 "TARGET_USE_VECTOR_FP_CONVERTS
4546 && optimize_insn_for_speed_p ()
4547 && reload_completed && SSE_REG_P (operands[0])"
4552 (parallel [(const_int 0) (const_int 1)]))))]
4554 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4555 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4556 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4557 Try to avoid move when unpacking can be done in source. */
4558 if (REG_P (operands[1]))
4560 /* If it is unsafe to overwrite upper half of source, we need
4561 to move to destination and unpack there. */
4562 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4563 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4564 && true_regnum (operands[0]) != true_regnum (operands[1]))
4566 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4567 emit_move_insn (tmp, operands[1]);
4570 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4571 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4574 emit_insn (gen_vec_setv4sf_0 (operands[3],
4575 CONST0_RTX (V4SFmode), operands[1]));
4578 (define_insn "*extendsfdf2_mixed"
4579 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4581 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4582 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4584 switch (which_alternative)
4588 return output_387_reg_move (insn, operands);
4591 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4597 [(set_attr "type" "fmov,fmov,ssecvt")
4598 (set_attr "prefix" "orig,orig,maybe_vex")
4599 (set_attr "mode" "SF,XF,DF")])
4601 (define_insn "*extendsfdf2_sse"
4602 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4603 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4604 "TARGET_SSE2 && TARGET_SSE_MATH"
4605 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4606 [(set_attr "type" "ssecvt")
4607 (set_attr "prefix" "maybe_vex")
4608 (set_attr "mode" "DF")])
4610 (define_insn "*extendsfdf2_i387"
4611 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4612 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4614 "* return output_387_reg_move (insn, operands);"
4615 [(set_attr "type" "fmov")
4616 (set_attr "mode" "SF,XF")])
4618 (define_expand "extend<mode>xf2"
4619 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4620 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4623 /* ??? Needed for compress_float_constant since all fp constants
4624 are LEGITIMATE_CONSTANT_P. */
4625 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4627 if (standard_80387_constant_p (operands[1]) > 0)
4629 operands[1] = simplify_const_unary_operation
4630 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4631 emit_move_insn_1 (operands[0], operands[1]);
4634 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4638 (define_insn "*extend<mode>xf2_i387"
4639 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4641 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4643 "* return output_387_reg_move (insn, operands);"
4644 [(set_attr "type" "fmov")
4645 (set_attr "mode" "<MODE>,XF")])
4647 ;; %%% This seems bad bad news.
4648 ;; This cannot output into an f-reg because there is no way to be sure
4649 ;; of truncating in that case. Otherwise this is just like a simple move
4650 ;; insn. So we pretend we can output to a reg in order to get better
4651 ;; register preferencing, but we really use a stack slot.
4653 ;; Conversion from DFmode to SFmode.
4655 (define_expand "truncdfsf2"
4656 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4658 (match_operand:DF 1 "nonimmediate_operand" "")))]
4659 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4661 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4663 else if (flag_unsafe_math_optimizations)
4667 enum ix86_stack_slot slot = (virtuals_instantiated
4670 rtx temp = assign_386_stack_local (SFmode, slot);
4671 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4676 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4678 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4680 We do the conversion post reload to avoid producing of 128bit spills
4681 that might lead to ICE on 32bit target. The sequence unlikely combine
4684 [(set (match_operand:SF 0 "register_operand" "")
4686 (match_operand:DF 1 "nonimmediate_operand" "")))]
4687 "TARGET_USE_VECTOR_FP_CONVERTS
4688 && optimize_insn_for_speed_p ()
4689 && reload_completed && SSE_REG_P (operands[0])"
4692 (float_truncate:V2SF
4696 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4697 operands[3] = CONST0_RTX (V2SFmode);
4698 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4699 /* Use movsd for loading from memory, unpcklpd for registers.
4700 Try to avoid move when unpacking can be done in source, or SSE3
4701 movddup is available. */
4702 if (REG_P (operands[1]))
4705 && true_regnum (operands[0]) != true_regnum (operands[1])
4706 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4707 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4709 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4710 emit_move_insn (tmp, operands[1]);
4713 else if (!TARGET_SSE3)
4714 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4715 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4718 emit_insn (gen_sse2_loadlpd (operands[4],
4719 CONST0_RTX (V2DFmode), operands[1]));
4722 (define_expand "truncdfsf2_with_temp"
4723 [(parallel [(set (match_operand:SF 0 "" "")
4724 (float_truncate:SF (match_operand:DF 1 "" "")))
4725 (clobber (match_operand:SF 2 "" ""))])]
4728 (define_insn "*truncdfsf_fast_mixed"
4729 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4731 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4732 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4734 switch (which_alternative)
4737 return output_387_reg_move (insn, operands);
4739 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4744 [(set_attr "type" "fmov,ssecvt")
4745 (set_attr "prefix" "orig,maybe_vex")
4746 (set_attr "mode" "SF")])
4748 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4749 ;; because nothing we do here is unsafe.
4750 (define_insn "*truncdfsf_fast_sse"
4751 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4753 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4754 "TARGET_SSE2 && TARGET_SSE_MATH"
4755 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4756 [(set_attr "type" "ssecvt")
4757 (set_attr "prefix" "maybe_vex")
4758 (set_attr "mode" "SF")])
4760 (define_insn "*truncdfsf_fast_i387"
4761 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4763 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4764 "TARGET_80387 && flag_unsafe_math_optimizations"
4765 "* return output_387_reg_move (insn, operands);"
4766 [(set_attr "type" "fmov")
4767 (set_attr "mode" "SF")])
4769 (define_insn "*truncdfsf_mixed"
4770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4772 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4773 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4774 "TARGET_MIX_SSE_I387"
4776 switch (which_alternative)
4779 return output_387_reg_move (insn, operands);
4781 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4787 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4788 (set_attr "unit" "*,*,i387,i387,i387")
4789 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4790 (set_attr "mode" "SF")])
4792 (define_insn "*truncdfsf_i387"
4793 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4795 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4796 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4799 switch (which_alternative)
4802 return output_387_reg_move (insn, operands);
4808 [(set_attr "type" "fmov,multi,multi,multi")
4809 (set_attr "unit" "*,i387,i387,i387")
4810 (set_attr "mode" "SF")])
4812 (define_insn "*truncdfsf2_i387_1"
4813 [(set (match_operand:SF 0 "memory_operand" "=m")
4815 (match_operand:DF 1 "register_operand" "f")))]
4817 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4818 && !TARGET_MIX_SSE_I387"
4819 "* return output_387_reg_move (insn, operands);"
4820 [(set_attr "type" "fmov")
4821 (set_attr "mode" "SF")])
4824 [(set (match_operand:SF 0 "register_operand" "")
4826 (match_operand:DF 1 "fp_register_operand" "")))
4827 (clobber (match_operand 2 "" ""))]
4829 [(set (match_dup 2) (match_dup 1))
4830 (set (match_dup 0) (match_dup 2))]
4832 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4835 ;; Conversion from XFmode to {SF,DF}mode
4837 (define_expand "truncxf<mode>2"
4838 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4839 (float_truncate:MODEF
4840 (match_operand:XF 1 "register_operand" "")))
4841 (clobber (match_dup 2))])]
4844 if (flag_unsafe_math_optimizations)
4846 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4847 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4848 if (reg != operands[0])
4849 emit_move_insn (operands[0], reg);
4854 enum ix86_stack_slot slot = (virtuals_instantiated
4857 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4861 (define_insn "*truncxfsf2_mixed"
4862 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4864 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4865 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4868 gcc_assert (!which_alternative);
4869 return output_387_reg_move (insn, operands);
4871 [(set_attr "type" "fmov,multi,multi,multi")
4872 (set_attr "unit" "*,i387,i387,i387")
4873 (set_attr "mode" "SF")])
4875 (define_insn "*truncxfdf2_mixed"
4876 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4878 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4879 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4882 gcc_assert (!which_alternative);
4883 return output_387_reg_move (insn, operands);
4885 [(set_attr "type" "fmov,multi,multi,multi")
4886 (set_attr "unit" "*,i387,i387,i387")
4887 (set_attr "mode" "DF")])
4889 (define_insn "truncxf<mode>2_i387_noop"
4890 [(set (match_operand:MODEF 0 "register_operand" "=f")
4891 (float_truncate:MODEF
4892 (match_operand:XF 1 "register_operand" "f")))]
4893 "TARGET_80387 && flag_unsafe_math_optimizations"
4894 "* return output_387_reg_move (insn, operands);"
4895 [(set_attr "type" "fmov")
4896 (set_attr "mode" "<MODE>")])
4898 (define_insn "*truncxf<mode>2_i387"
4899 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4900 (float_truncate:MODEF
4901 (match_operand:XF 1 "register_operand" "f")))]
4903 "* return output_387_reg_move (insn, operands);"
4904 [(set_attr "type" "fmov")
4905 (set_attr "mode" "<MODE>")])
4908 [(set (match_operand:MODEF 0 "register_operand" "")
4909 (float_truncate:MODEF
4910 (match_operand:XF 1 "register_operand" "")))
4911 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4912 "TARGET_80387 && reload_completed"
4913 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4914 (set (match_dup 0) (match_dup 2))]
4918 [(set (match_operand:MODEF 0 "memory_operand" "")
4919 (float_truncate:MODEF
4920 (match_operand:XF 1 "register_operand" "")))
4921 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4923 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4926 ;; Signed conversion to DImode.
4928 (define_expand "fix_truncxfdi2"
4929 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930 (fix:DI (match_operand:XF 1 "register_operand" "")))
4931 (clobber (reg:CC FLAGS_REG))])]
4936 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4941 (define_expand "fix_trunc<mode>di2"
4942 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4944 (clobber (reg:CC FLAGS_REG))])]
4945 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4948 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4950 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4953 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4955 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4956 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4957 if (out != operands[0])
4958 emit_move_insn (operands[0], out);
4963 ;; Signed conversion to SImode.
4965 (define_expand "fix_truncxfsi2"
4966 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967 (fix:SI (match_operand:XF 1 "register_operand" "")))
4968 (clobber (reg:CC FLAGS_REG))])]
4973 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4978 (define_expand "fix_trunc<mode>si2"
4979 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4980 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4981 (clobber (reg:CC FLAGS_REG))])]
4982 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4985 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4987 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4990 if (SSE_FLOAT_MODE_P (<MODE>mode))
4992 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4993 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4994 if (out != operands[0])
4995 emit_move_insn (operands[0], out);
5000 ;; Signed conversion to HImode.
5002 (define_expand "fix_trunc<mode>hi2"
5003 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5004 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
5005 (clobber (reg:CC FLAGS_REG))])]
5007 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5011 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5016 ;; Unsigned conversion to SImode.
5018 (define_expand "fixuns_trunc<mode>si2"
5020 [(set (match_operand:SI 0 "register_operand" "")
5022 (match_operand:MODEF 1 "nonimmediate_operand" "")))
5024 (clobber (match_scratch:<ssevecmode> 3 ""))
5025 (clobber (match_scratch:<ssevecmode> 4 ""))])]
5026 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5028 enum machine_mode mode = <MODE>mode;
5029 enum machine_mode vecmode = <ssevecmode>mode;
5030 REAL_VALUE_TYPE TWO31r;
5033 if (optimize_insn_for_size_p ())
5036 real_ldexp (&TWO31r, &dconst1, 31);
5037 two31 = const_double_from_real_value (TWO31r, mode);
5038 two31 = ix86_build_const_vector (mode, true, two31);
5039 operands[2] = force_reg (vecmode, two31);
5042 (define_insn_and_split "*fixuns_trunc<mode>_1"
5043 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5045 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5046 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5047 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5048 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5049 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5050 && optimize_function_for_speed_p (cfun)"
5052 "&& reload_completed"
5055 ix86_split_convert_uns_si_sse (operands);
5059 ;; Unsigned conversion to HImode.
5060 ;; Without these patterns, we'll try the unsigned SI conversion which
5061 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5063 (define_expand "fixuns_trunc<mode>hi2"
5065 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5066 (set (match_operand:HI 0 "nonimmediate_operand" "")
5067 (subreg:HI (match_dup 2) 0))]
5068 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5069 "operands[2] = gen_reg_rtx (SImode);")
5071 ;; When SSE is available, it is always faster to use it!
5072 (define_insn "fix_trunc<mode>di_sse"
5073 [(set (match_operand:DI 0 "register_operand" "=r,r")
5074 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5075 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5076 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5077 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5078 [(set_attr "type" "sseicvt")
5079 (set_attr "prefix" "maybe_vex")
5080 (set_attr "prefix_rex" "1")
5081 (set_attr "mode" "<MODE>")
5082 (set_attr "athlon_decode" "double,vector")
5083 (set_attr "amdfam10_decode" "double,double")])
5085 (define_insn "fix_trunc<mode>si_sse"
5086 [(set (match_operand:SI 0 "register_operand" "=r,r")
5087 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5088 "SSE_FLOAT_MODE_P (<MODE>mode)
5089 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5090 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5091 [(set_attr "type" "sseicvt")
5092 (set_attr "prefix" "maybe_vex")
5093 (set_attr "mode" "<MODE>")
5094 (set_attr "athlon_decode" "double,vector")
5095 (set_attr "amdfam10_decode" "double,double")])
5097 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5099 [(set (match_operand:MODEF 0 "register_operand" "")
5100 (match_operand:MODEF 1 "memory_operand" ""))
5101 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5102 (fix:SSEMODEI24 (match_dup 0)))]
5103 "TARGET_SHORTEN_X87_SSE
5104 && peep2_reg_dead_p (2, operands[0])"
5105 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5108 ;; Avoid vector decoded forms of the instruction.
5110 [(match_scratch:DF 2 "Y2")
5111 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5112 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5113 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5114 [(set (match_dup 2) (match_dup 1))
5115 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5119 [(match_scratch:SF 2 "x")
5120 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5121 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5122 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5123 [(set (match_dup 2) (match_dup 1))
5124 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5127 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5128 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5129 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5132 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5133 && (TARGET_64BIT || <MODE>mode != DImode))
5135 && can_create_pseudo_p ()"
5140 if (memory_operand (operands[0], VOIDmode))
5141 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5144 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5145 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5151 [(set_attr "type" "fisttp")
5152 (set_attr "mode" "<MODE>")])
5154 (define_insn "fix_trunc<mode>_i387_fisttp"
5155 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5156 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5157 (clobber (match_scratch:XF 2 "=&1f"))]
5158 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5161 && (TARGET_64BIT || <MODE>mode != DImode))
5162 && TARGET_SSE_MATH)"
5163 "* return output_fix_trunc (insn, operands, 1);"
5164 [(set_attr "type" "fisttp")
5165 (set_attr "mode" "<MODE>")])
5167 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5168 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5169 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5170 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5171 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5172 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5175 && (TARGET_64BIT || <MODE>mode != DImode))
5176 && TARGET_SSE_MATH)"
5178 [(set_attr "type" "fisttp")
5179 (set_attr "mode" "<MODE>")])
5182 [(set (match_operand:X87MODEI 0 "register_operand" "")
5183 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5184 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5185 (clobber (match_scratch 3 ""))]
5187 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5188 (clobber (match_dup 3))])
5189 (set (match_dup 0) (match_dup 2))]
5193 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5194 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5195 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5196 (clobber (match_scratch 3 ""))]
5198 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5199 (clobber (match_dup 3))])]
5202 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5203 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5204 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5205 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5206 ;; function in i386.c.
5207 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5208 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5209 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5210 (clobber (reg:CC FLAGS_REG))]
5211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5213 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5214 && (TARGET_64BIT || <MODE>mode != DImode))
5215 && can_create_pseudo_p ()"
5220 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5222 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5223 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5224 if (memory_operand (operands[0], VOIDmode))
5225 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5226 operands[2], operands[3]));
5229 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5230 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5231 operands[2], operands[3],
5236 [(set_attr "type" "fistp")
5237 (set_attr "i387_cw" "trunc")
5238 (set_attr "mode" "<MODE>")])
5240 (define_insn "fix_truncdi_i387"
5241 [(set (match_operand:DI 0 "memory_operand" "=m")
5242 (fix:DI (match_operand 1 "register_operand" "f")))
5243 (use (match_operand:HI 2 "memory_operand" "m"))
5244 (use (match_operand:HI 3 "memory_operand" "m"))
5245 (clobber (match_scratch:XF 4 "=&1f"))]
5246 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5248 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5249 "* return output_fix_trunc (insn, operands, 0);"
5250 [(set_attr "type" "fistp")
5251 (set_attr "i387_cw" "trunc")
5252 (set_attr "mode" "DI")])
5254 (define_insn "fix_truncdi_i387_with_temp"
5255 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5256 (fix:DI (match_operand 1 "register_operand" "f,f")))
5257 (use (match_operand:HI 2 "memory_operand" "m,m"))
5258 (use (match_operand:HI 3 "memory_operand" "m,m"))
5259 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5260 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5261 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5263 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5265 [(set_attr "type" "fistp")
5266 (set_attr "i387_cw" "trunc")
5267 (set_attr "mode" "DI")])
5270 [(set (match_operand:DI 0 "register_operand" "")
5271 (fix:DI (match_operand 1 "register_operand" "")))
5272 (use (match_operand:HI 2 "memory_operand" ""))
5273 (use (match_operand:HI 3 "memory_operand" ""))
5274 (clobber (match_operand:DI 4 "memory_operand" ""))
5275 (clobber (match_scratch 5 ""))]
5277 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5280 (clobber (match_dup 5))])
5281 (set (match_dup 0) (match_dup 4))]
5285 [(set (match_operand:DI 0 "memory_operand" "")
5286 (fix:DI (match_operand 1 "register_operand" "")))
5287 (use (match_operand:HI 2 "memory_operand" ""))
5288 (use (match_operand:HI 3 "memory_operand" ""))
5289 (clobber (match_operand:DI 4 "memory_operand" ""))
5290 (clobber (match_scratch 5 ""))]
5292 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5295 (clobber (match_dup 5))])]
5298 (define_insn "fix_trunc<mode>_i387"
5299 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5300 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5301 (use (match_operand:HI 2 "memory_operand" "m"))
5302 (use (match_operand:HI 3 "memory_operand" "m"))]
5303 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5305 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5306 "* return output_fix_trunc (insn, operands, 0);"
5307 [(set_attr "type" "fistp")
5308 (set_attr "i387_cw" "trunc")
5309 (set_attr "mode" "<MODE>")])
5311 (define_insn "fix_trunc<mode>_i387_with_temp"
5312 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5313 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5314 (use (match_operand:HI 2 "memory_operand" "m,m"))
5315 (use (match_operand:HI 3 "memory_operand" "m,m"))
5316 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5317 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5319 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5321 [(set_attr "type" "fistp")
5322 (set_attr "i387_cw" "trunc")
5323 (set_attr "mode" "<MODE>")])
5326 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5327 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5328 (use (match_operand:HI 2 "memory_operand" ""))
5329 (use (match_operand:HI 3 "memory_operand" ""))
5330 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5332 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5334 (use (match_dup 3))])
5335 (set (match_dup 0) (match_dup 4))]
5339 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5340 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5341 (use (match_operand:HI 2 "memory_operand" ""))
5342 (use (match_operand:HI 3 "memory_operand" ""))
5343 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5345 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5347 (use (match_dup 3))])]
5350 (define_insn "x86_fnstcw_1"
5351 [(set (match_operand:HI 0 "memory_operand" "=m")
5352 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5355 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5356 (set_attr "mode" "HI")
5357 (set_attr "unit" "i387")])
5359 (define_insn "x86_fldcw_1"
5360 [(set (reg:HI FPCR_REG)
5361 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5364 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5365 (set_attr "mode" "HI")
5366 (set_attr "unit" "i387")
5367 (set_attr "athlon_decode" "vector")
5368 (set_attr "amdfam10_decode" "vector")])
5370 ;; Conversion between fixed point and floating point.
5372 ;; Even though we only accept memory inputs, the backend _really_
5373 ;; wants to be able to do this between registers.
5375 (define_expand "floathi<mode>2"
5376 [(set (match_operand:X87MODEF 0 "register_operand" "")
5377 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5380 || TARGET_MIX_SSE_I387)"
5383 ;; Pre-reload splitter to add memory clobber to the pattern.
5384 (define_insn_and_split "*floathi<mode>2_1"
5385 [(set (match_operand:X87MODEF 0 "register_operand" "")
5386 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5389 || TARGET_MIX_SSE_I387)
5390 && can_create_pseudo_p ()"
5393 [(parallel [(set (match_dup 0)
5394 (float:X87MODEF (match_dup 1)))
5395 (clobber (match_dup 2))])]
5396 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5398 (define_insn "*floathi<mode>2_i387_with_temp"
5399 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5400 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5401 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5404 || TARGET_MIX_SSE_I387)"
5406 [(set_attr "type" "fmov,multi")
5407 (set_attr "mode" "<MODE>")
5408 (set_attr "unit" "*,i387")
5409 (set_attr "fp_int_src" "true")])
5411 (define_insn "*floathi<mode>2_i387"
5412 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5413 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5416 || TARGET_MIX_SSE_I387)"
5418 [(set_attr "type" "fmov")
5419 (set_attr "mode" "<MODE>")
5420 (set_attr "fp_int_src" "true")])
5423 [(set (match_operand:X87MODEF 0 "register_operand" "")
5424 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5425 (clobber (match_operand:HI 2 "memory_operand" ""))]
5427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5428 || TARGET_MIX_SSE_I387)
5429 && reload_completed"
5430 [(set (match_dup 2) (match_dup 1))
5431 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5435 [(set (match_operand:X87MODEF 0 "register_operand" "")
5436 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5437 (clobber (match_operand:HI 2 "memory_operand" ""))]
5439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5440 || TARGET_MIX_SSE_I387)
5441 && reload_completed"
5442 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5445 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5446 [(set (match_operand:X87MODEF 0 "register_operand" "")
5448 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5450 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5451 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5454 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5456 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5458 rtx reg = gen_reg_rtx (XFmode);
5461 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5463 if (<X87MODEF:MODE>mode == SFmode)
5464 insn = gen_truncxfsf2 (operands[0], reg);
5465 else if (<X87MODEF:MODE>mode == DFmode)
5466 insn = gen_truncxfdf2 (operands[0], reg);
5475 ;; Pre-reload splitter to add memory clobber to the pattern.
5476 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5477 [(set (match_operand:X87MODEF 0 "register_operand" "")
5478 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5480 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5481 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5482 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5483 || TARGET_MIX_SSE_I387))
5484 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5485 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5486 && ((<SSEMODEI24:MODE>mode == SImode
5487 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5488 && optimize_function_for_speed_p (cfun)
5489 && flag_trapping_math)
5490 || !(TARGET_INTER_UNIT_CONVERSIONS
5491 || optimize_function_for_size_p (cfun)))))
5492 && can_create_pseudo_p ()"
5495 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5496 (clobber (match_dup 2))])]
5498 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5500 /* Avoid store forwarding (partial memory) stall penalty
5501 by passing DImode value through XMM registers. */
5502 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5503 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5504 && optimize_function_for_speed_p (cfun))
5506 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5513 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5514 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5516 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5517 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5518 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5519 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5521 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5522 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5523 (set_attr "unit" "*,i387,*,*,*")
5524 (set_attr "athlon_decode" "*,*,double,direct,double")
5525 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5526 (set_attr "fp_int_src" "true")])
5528 (define_insn "*floatsi<mode>2_vector_mixed"
5529 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5530 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5531 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5532 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5536 [(set_attr "type" "fmov,sseicvt")
5537 (set_attr "mode" "<MODE>,<ssevecmode>")
5538 (set_attr "unit" "i387,*")
5539 (set_attr "athlon_decode" "*,direct")
5540 (set_attr "amdfam10_decode" "*,double")
5541 (set_attr "fp_int_src" "true")])
5543 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5544 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5546 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5547 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5548 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5549 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5551 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5552 (set_attr "mode" "<MODEF:MODE>")
5553 (set_attr "unit" "*,i387,*,*")
5554 (set_attr "athlon_decode" "*,*,double,direct")
5555 (set_attr "amdfam10_decode" "*,*,vector,double")
5556 (set_attr "fp_int_src" "true")])
5559 [(set (match_operand:MODEF 0 "register_operand" "")
5560 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5561 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5562 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5563 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5564 && TARGET_INTER_UNIT_CONVERSIONS
5566 && (SSE_REG_P (operands[0])
5567 || (GET_CODE (operands[0]) == SUBREG
5568 && SSE_REG_P (operands[0])))"
5569 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5573 [(set (match_operand:MODEF 0 "register_operand" "")
5574 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5575 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5576 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5577 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5578 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5580 && (SSE_REG_P (operands[0])
5581 || (GET_CODE (operands[0]) == SUBREG
5582 && SSE_REG_P (operands[0])))"
5583 [(set (match_dup 2) (match_dup 1))
5584 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5587 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5588 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5590 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5591 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5592 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5593 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5596 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5597 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5598 [(set_attr "type" "fmov,sseicvt,sseicvt")
5599 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5600 (set_attr "mode" "<MODEF:MODE>")
5601 (set (attr "prefix_rex")
5603 (and (eq_attr "prefix" "maybe_vex")
5604 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5606 (const_string "*")))
5607 (set_attr "unit" "i387,*,*")
5608 (set_attr "athlon_decode" "*,double,direct")
5609 (set_attr "amdfam10_decode" "*,vector,double")
5610 (set_attr "fp_int_src" "true")])
5612 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5613 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5615 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5616 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5617 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5618 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5621 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5622 [(set_attr "type" "fmov,sseicvt")
5623 (set_attr "prefix" "orig,maybe_vex")
5624 (set_attr "mode" "<MODEF:MODE>")
5625 (set (attr "prefix_rex")
5627 (and (eq_attr "prefix" "maybe_vex")
5628 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5630 (const_string "*")))
5631 (set_attr "athlon_decode" "*,direct")
5632 (set_attr "amdfam10_decode" "*,double")
5633 (set_attr "fp_int_src" "true")])
5635 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5636 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5638 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5639 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5640 "TARGET_SSE2 && TARGET_SSE_MATH
5641 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5643 [(set_attr "type" "sseicvt")
5644 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5645 (set_attr "athlon_decode" "double,direct,double")
5646 (set_attr "amdfam10_decode" "vector,double,double")
5647 (set_attr "fp_int_src" "true")])
5649 (define_insn "*floatsi<mode>2_vector_sse"
5650 [(set (match_operand:MODEF 0 "register_operand" "=x")
5651 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5652 "TARGET_SSE2 && TARGET_SSE_MATH
5653 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5655 [(set_attr "type" "sseicvt")
5656 (set_attr "mode" "<MODE>")
5657 (set_attr "athlon_decode" "direct")
5658 (set_attr "amdfam10_decode" "double")
5659 (set_attr "fp_int_src" "true")])
5662 [(set (match_operand:MODEF 0 "register_operand" "")
5663 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5664 (clobber (match_operand:SI 2 "memory_operand" ""))]
5665 "TARGET_SSE2 && TARGET_SSE_MATH
5666 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5668 && (SSE_REG_P (operands[0])
5669 || (GET_CODE (operands[0]) == SUBREG
5670 && SSE_REG_P (operands[0])))"
5673 rtx op1 = operands[1];
5675 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5677 if (GET_CODE (op1) == SUBREG)
5678 op1 = SUBREG_REG (op1);
5680 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5682 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5683 emit_insn (gen_sse2_loadld (operands[4],
5684 CONST0_RTX (V4SImode), operands[1]));
5686 /* We can ignore possible trapping value in the
5687 high part of SSE register for non-trapping math. */
5688 else if (SSE_REG_P (op1) && !flag_trapping_math)
5689 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5692 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5693 emit_move_insn (operands[2], operands[1]);
5694 emit_insn (gen_sse2_loadld (operands[4],
5695 CONST0_RTX (V4SImode), operands[2]));
5698 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5703 [(set (match_operand:MODEF 0 "register_operand" "")
5704 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5705 (clobber (match_operand:SI 2 "memory_operand" ""))]
5706 "TARGET_SSE2 && TARGET_SSE_MATH
5707 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5709 && (SSE_REG_P (operands[0])
5710 || (GET_CODE (operands[0]) == SUBREG
5711 && SSE_REG_P (operands[0])))"
5714 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5716 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5718 emit_insn (gen_sse2_loadld (operands[4],
5719 CONST0_RTX (V4SImode), operands[1]));
5721 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5726 [(set (match_operand:MODEF 0 "register_operand" "")
5727 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5728 "TARGET_SSE2 && TARGET_SSE_MATH
5729 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5731 && (SSE_REG_P (operands[0])
5732 || (GET_CODE (operands[0]) == SUBREG
5733 && SSE_REG_P (operands[0])))"
5736 rtx op1 = operands[1];
5738 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5740 if (GET_CODE (op1) == SUBREG)
5741 op1 = SUBREG_REG (op1);
5743 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5745 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5746 emit_insn (gen_sse2_loadld (operands[4],
5747 CONST0_RTX (V4SImode), operands[1]));
5749 /* We can ignore possible trapping value in the
5750 high part of SSE register for non-trapping math. */
5751 else if (SSE_REG_P (op1) && !flag_trapping_math)
5752 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5756 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5761 [(set (match_operand:MODEF 0 "register_operand" "")
5762 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5763 "TARGET_SSE2 && TARGET_SSE_MATH
5764 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5766 && (SSE_REG_P (operands[0])
5767 || (GET_CODE (operands[0]) == SUBREG
5768 && SSE_REG_P (operands[0])))"
5771 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5773 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5775 emit_insn (gen_sse2_loadld (operands[4],
5776 CONST0_RTX (V4SImode), operands[1]));
5778 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5782 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5783 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5785 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5786 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5787 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5788 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5790 [(set_attr "type" "sseicvt")
5791 (set_attr "mode" "<MODEF:MODE>")
5792 (set_attr "athlon_decode" "double,direct")
5793 (set_attr "amdfam10_decode" "vector,double")
5794 (set_attr "fp_int_src" "true")])
5796 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5797 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5799 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5800 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5801 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5802 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5803 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5804 [(set_attr "type" "sseicvt")
5805 (set_attr "prefix" "maybe_vex")
5806 (set_attr "mode" "<MODEF:MODE>")
5807 (set (attr "prefix_rex")
5809 (and (eq_attr "prefix" "maybe_vex")
5810 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5812 (const_string "*")))
5813 (set_attr "athlon_decode" "double,direct")
5814 (set_attr "amdfam10_decode" "vector,double")
5815 (set_attr "fp_int_src" "true")])
5818 [(set (match_operand:MODEF 0 "register_operand" "")
5819 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5820 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5821 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5822 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5823 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5825 && (SSE_REG_P (operands[0])
5826 || (GET_CODE (operands[0]) == SUBREG
5827 && SSE_REG_P (operands[0])))"
5828 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5831 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5832 [(set (match_operand:MODEF 0 "register_operand" "=x")
5834 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5835 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5836 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5837 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5838 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5839 [(set_attr "type" "sseicvt")
5840 (set_attr "prefix" "maybe_vex")
5841 (set_attr "mode" "<MODEF:MODE>")
5842 (set (attr "prefix_rex")
5844 (and (eq_attr "prefix" "maybe_vex")
5845 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5847 (const_string "*")))
5848 (set_attr "athlon_decode" "direct")
5849 (set_attr "amdfam10_decode" "double")
5850 (set_attr "fp_int_src" "true")])
5853 [(set (match_operand:MODEF 0 "register_operand" "")
5854 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5855 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5856 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5860 && (SSE_REG_P (operands[0])
5861 || (GET_CODE (operands[0]) == SUBREG
5862 && SSE_REG_P (operands[0])))"
5863 [(set (match_dup 2) (match_dup 1))
5864 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5868 [(set (match_operand:MODEF 0 "register_operand" "")
5869 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5870 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5871 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5872 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5874 && (SSE_REG_P (operands[0])
5875 || (GET_CODE (operands[0]) == SUBREG
5876 && SSE_REG_P (operands[0])))"
5877 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5880 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5881 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5883 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5884 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5886 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5890 [(set_attr "type" "fmov,multi")
5891 (set_attr "mode" "<X87MODEF:MODE>")
5892 (set_attr "unit" "*,i387")
5893 (set_attr "fp_int_src" "true")])
5895 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5896 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5898 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5900 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5902 [(set_attr "type" "fmov")
5903 (set_attr "mode" "<X87MODEF:MODE>")
5904 (set_attr "fp_int_src" "true")])
5907 [(set (match_operand:X87MODEF 0 "register_operand" "")
5908 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5909 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5911 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5913 && FP_REG_P (operands[0])"
5914 [(set (match_dup 2) (match_dup 1))
5915 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5919 [(set (match_operand:X87MODEF 0 "register_operand" "")
5920 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5921 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5923 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5925 && FP_REG_P (operands[0])"
5926 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5929 ;; Avoid store forwarding (partial memory) stall penalty
5930 ;; by passing DImode value through XMM registers. */
5932 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5933 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5935 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5936 (clobber (match_scratch:V4SI 3 "=X,x"))
5937 (clobber (match_scratch:V4SI 4 "=X,x"))
5938 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5939 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5940 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5941 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5943 [(set_attr "type" "multi")
5944 (set_attr "mode" "<X87MODEF:MODE>")
5945 (set_attr "unit" "i387")
5946 (set_attr "fp_int_src" "true")])
5949 [(set (match_operand:X87MODEF 0 "register_operand" "")
5950 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5951 (clobber (match_scratch:V4SI 3 ""))
5952 (clobber (match_scratch:V4SI 4 ""))
5953 (clobber (match_operand:DI 2 "memory_operand" ""))]
5954 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5955 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5956 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5958 && FP_REG_P (operands[0])"
5959 [(set (match_dup 2) (match_dup 3))
5960 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5962 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5963 Assemble the 64-bit DImode value in an xmm register. */
5964 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5965 gen_rtx_SUBREG (SImode, operands[1], 0)));
5966 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5967 gen_rtx_SUBREG (SImode, operands[1], 4)));
5968 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5970 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5974 [(set (match_operand:X87MODEF 0 "register_operand" "")
5975 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5976 (clobber (match_scratch:V4SI 3 ""))
5977 (clobber (match_scratch:V4SI 4 ""))
5978 (clobber (match_operand:DI 2 "memory_operand" ""))]
5979 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5980 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5981 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5983 && FP_REG_P (operands[0])"
5984 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5987 ;; Avoid store forwarding (partial memory) stall penalty by extending
5988 ;; SImode value to DImode through XMM register instead of pushing two
5989 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5990 ;; targets benefit from this optimization. Also note that fild
5991 ;; loads from memory only.
5993 (define_insn "*floatunssi<mode>2_1"
5994 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5995 (unsigned_float:X87MODEF
5996 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5997 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5998 (clobber (match_scratch:SI 3 "=X,x"))]
6000 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6003 [(set_attr "type" "multi")
6004 (set_attr "mode" "<MODE>")])
6007 [(set (match_operand:X87MODEF 0 "register_operand" "")
6008 (unsigned_float:X87MODEF
6009 (match_operand:SI 1 "register_operand" "")))
6010 (clobber (match_operand:DI 2 "memory_operand" ""))
6011 (clobber (match_scratch:SI 3 ""))]
6013 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6015 && reload_completed"
6016 [(set (match_dup 2) (match_dup 1))
6018 (float:X87MODEF (match_dup 2)))]
6019 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6022 [(set (match_operand:X87MODEF 0 "register_operand" "")
6023 (unsigned_float:X87MODEF
6024 (match_operand:SI 1 "memory_operand" "")))
6025 (clobber (match_operand:DI 2 "memory_operand" ""))
6026 (clobber (match_scratch:SI 3 ""))]
6028 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6030 && reload_completed"
6031 [(set (match_dup 2) (match_dup 3))
6033 (float:X87MODEF (match_dup 2)))]
6035 emit_move_insn (operands[3], operands[1]);
6036 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6039 (define_expand "floatunssi<mode>2"
6041 [(set (match_operand:X87MODEF 0 "register_operand" "")
6042 (unsigned_float:X87MODEF
6043 (match_operand:SI 1 "nonimmediate_operand" "")))
6044 (clobber (match_dup 2))
6045 (clobber (match_scratch:SI 3 ""))])]
6047 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6049 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6051 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6053 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6058 enum ix86_stack_slot slot = (virtuals_instantiated
6061 operands[2] = assign_386_stack_local (DImode, slot);
6065 (define_expand "floatunsdisf2"
6066 [(use (match_operand:SF 0 "register_operand" ""))
6067 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6068 "TARGET_64BIT && TARGET_SSE_MATH"
6069 "x86_emit_floatuns (operands); DONE;")
6071 (define_expand "floatunsdidf2"
6072 [(use (match_operand:DF 0 "register_operand" ""))
6073 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6074 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6075 && TARGET_SSE2 && TARGET_SSE_MATH"
6078 x86_emit_floatuns (operands);
6080 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6086 (define_expand "add<mode>3"
6087 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6088 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6089 (match_operand:SDWIM 2 "<general_operand>" "")))]
6091 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6093 (define_insn_and_split "*add<mode>3_doubleword"
6094 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
6096 (match_operand:DWI 1 "nonimmediate_operand" "%0,0")
6097 (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
6098 (clobber (reg:CC FLAGS_REG))]
6099 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6102 [(parallel [(set (reg:CC FLAGS_REG)
6103 (unspec:CC [(match_dup 1) (match_dup 2)]
6106 (plus:<DWIH> (match_dup 1) (match_dup 2)))])
6107 (parallel [(set (match_dup 3)
6110 (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
6113 (clobber (reg:CC FLAGS_REG))])]
6114 "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
6116 (define_insn "add<mode>3_carry"
6117 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6119 (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
6120 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6121 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6124 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6125 [(set_attr "type" "alu")
6126 (set_attr "use_carry" "1")
6127 (set_attr "pent_pair" "pu")
6128 (set_attr "mode" "<MODE>")])
6130 (define_insn "*addsi3_carry_zext"
6131 [(set (match_operand:DI 0 "register_operand" "=r")
6134 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6135 (match_operand:SI 1 "nonimmediate_operand" "%0"))
6136 (match_operand:SI 2 "general_operand" "g"))))
6137 (clobber (reg:CC FLAGS_REG))]
6138 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6139 "adc{l}\t{%2, %k0|%k0, %2}"
6140 [(set_attr "type" "alu")
6141 (set_attr "use_carry" "1")
6142 (set_attr "pent_pair" "pu")
6143 (set_attr "mode" "SI")])
6145 (define_insn "*add<mode>3_cc"
6146 [(set (reg:CC FLAGS_REG)
6148 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6149 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6151 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6152 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6153 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6154 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6155 [(set_attr "type" "alu")
6156 (set_attr "mode" "<MODE>")])
6158 (define_insn "addqi3_cc"
6159 [(set (reg:CC FLAGS_REG)
6161 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6162 (match_operand:QI 2 "general_operand" "qn,qm")]
6164 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6165 (plus:QI (match_dup 1) (match_dup 2)))]
6166 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6167 "add{b}\t{%2, %0|%0, %2}"
6168 [(set_attr "type" "alu")
6169 (set_attr "mode" "QI")])
6171 (define_insn "*add<mode>3_cconly_overflow"
6172 [(set (reg:CCC FLAGS_REG)
6175 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6176 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6178 (clobber (match_scratch:SWI 0 "=<r>"))]
6179 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6180 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6181 [(set_attr "type" "alu")
6182 (set_attr "mode" "<MODE>")])
6184 (define_insn "*lea_1_rex64"
6185 [(set (match_operand:DI 0 "register_operand" "=r")
6186 (match_operand:DI 1 "no_seg_address_operand" "p"))]
6188 "lea{q}\t{%a1, %0|%0, %a1}"
6189 [(set_attr "type" "lea")
6190 (set_attr "mode" "DI")])
6192 (define_insn "*lea_1"
6193 [(set (match_operand:SI 0 "register_operand" "=r")
6194 (match_operand:SI 1 "no_seg_address_operand" "p"))]
6196 "lea{l}\t{%a1, %0|%0, %a1}"
6197 [(set_attr "type" "lea")
6198 (set_attr "mode" "SI")])
6200 (define_insn "*lea_1_zext"
6201 [(set (match_operand:DI 0 "register_operand" "=r")
6203 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6205 "lea{l}\t{%a1, %k0|%k0, %a1}"
6206 [(set_attr "type" "lea")
6207 (set_attr "mode" "SI")])
6209 (define_insn "*lea_2_rex64"
6210 [(set (match_operand:SI 0 "register_operand" "=r")
6211 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6213 "lea{l}\t{%a1, %0|%0, %a1}"
6214 [(set_attr "type" "lea")
6215 (set_attr "mode" "SI")])
6217 (define_insn "*add<mode>_1"
6218 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6220 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6221 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6222 (clobber (reg:CC FLAGS_REG))]
6223 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6225 switch (get_attr_type (insn))
6228 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6229 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6233 if (operands[2] == const1_rtx)
6234 return "inc{<imodesuffix>}\t%0";
6237 gcc_assert (operands[2] == constm1_rtx);
6238 return "dec{<imodesuffix>}\t%0";
6242 /* Use add as much as possible to replace lea for AGU optimization. */
6243 if (which_alternative == 2 && TARGET_OPT_AGU)
6244 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6248 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6249 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6250 if (CONST_INT_P (operands[2])
6251 /* Avoid overflows. */
6252 && (<MODE>mode != DImode
6253 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6254 && (INTVAL (operands[2]) == 128
6255 || (INTVAL (operands[2]) < 0
6256 && INTVAL (operands[2]) != -128)))
6258 operands[2] = GEN_INT (-INTVAL (operands[2]));
6259 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6261 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6265 (cond [(and (eq_attr "alternative" "2")
6266 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6267 (const_string "lea")
6268 (eq_attr "alternative" "3")
6269 (const_string "lea")
6270 ; Current assemblers are broken and do not allow @GOTOFF in
6271 ; ought but a memory context.
6272 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6273 (const_string "lea")
6274 (match_operand:SWI48 2 "incdec_operand" "")
6275 (const_string "incdec")
6277 (const_string "alu")))
6278 (set (attr "length_immediate")
6280 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6282 (const_string "*")))
6283 (set_attr "mode" "<MODE>")])
6285 ;; It may seem that nonimmediate operand is proper one for operand 1.
6286 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6287 ;; we take care in ix86_binary_operator_ok to not allow two memory
6288 ;; operands so proper swapping will be done in reload. This allow
6289 ;; patterns constructed from addsi_1 to match.
6291 (define_insn "*addsi_1_zext"
6292 [(set (match_operand:DI 0 "register_operand" "=r,r")
6294 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6295 (match_operand:SI 2 "general_operand" "g,li"))))
6296 (clobber (reg:CC FLAGS_REG))]
6297 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6299 switch (get_attr_type (insn))
6302 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6303 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6306 if (operands[2] == const1_rtx)
6307 return "inc{l}\t%k0";
6310 gcc_assert (operands[2] == constm1_rtx);
6311 return "dec{l}\t%k0";
6315 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6316 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6317 if (CONST_INT_P (operands[2])
6318 && (INTVAL (operands[2]) == 128
6319 || (INTVAL (operands[2]) < 0
6320 && INTVAL (operands[2]) != -128)))
6322 operands[2] = GEN_INT (-INTVAL (operands[2]));
6323 return "sub{l}\t{%2, %k0|%k0, %2}";
6325 return "add{l}\t{%2, %k0|%k0, %2}";
6329 (cond [(eq_attr "alternative" "1")
6330 (const_string "lea")
6331 ; Current assemblers are broken and do not allow @GOTOFF in
6332 ; ought but a memory context.
6333 (match_operand:SI 2 "pic_symbolic_operand" "")
6334 (const_string "lea")
6335 (match_operand:SI 2 "incdec_operand" "")
6336 (const_string "incdec")
6338 (const_string "alu")))
6339 (set (attr "length_immediate")
6341 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6343 (const_string "*")))
6344 (set_attr "mode" "SI")])
6346 (define_insn "*addhi_1"
6347 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6348 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6349 (match_operand:HI 2 "general_operand" "rn,rm")))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "TARGET_PARTIAL_REG_STALL
6352 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6354 switch (get_attr_type (insn))
6357 if (operands[2] == const1_rtx)
6358 return "inc{w}\t%0";
6361 gcc_assert (operands[2] == constm1_rtx);
6362 return "dec{w}\t%0";
6366 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6367 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6368 if (CONST_INT_P (operands[2])
6369 && (INTVAL (operands[2]) == 128
6370 || (INTVAL (operands[2]) < 0
6371 && INTVAL (operands[2]) != -128)))
6373 operands[2] = GEN_INT (-INTVAL (operands[2]));
6374 return "sub{w}\t{%2, %0|%0, %2}";
6376 return "add{w}\t{%2, %0|%0, %2}";
6380 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6381 (const_string "incdec")
6382 (const_string "alu")))
6383 (set (attr "length_immediate")
6385 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6387 (const_string "*")))
6388 (set_attr "mode" "HI")])
6390 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6391 ;; type optimizations enabled by define-splits. This is not important
6392 ;; for PII, and in fact harmful because of partial register stalls.
6394 (define_insn "*addhi_1_lea"
6395 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6396 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6397 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6398 (clobber (reg:CC FLAGS_REG))]
6399 "!TARGET_PARTIAL_REG_STALL
6400 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6402 switch (get_attr_type (insn))
6407 if (operands[2] == const1_rtx)
6408 return "inc{w}\t%0";
6411 gcc_assert (operands[2] == constm1_rtx);
6412 return "dec{w}\t%0";
6416 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6417 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6418 if (CONST_INT_P (operands[2])
6419 && (INTVAL (operands[2]) == 128
6420 || (INTVAL (operands[2]) < 0
6421 && INTVAL (operands[2]) != -128)))
6423 operands[2] = GEN_INT (-INTVAL (operands[2]));
6424 return "sub{w}\t{%2, %0|%0, %2}";
6426 return "add{w}\t{%2, %0|%0, %2}";
6430 (if_then_else (eq_attr "alternative" "2")
6431 (const_string "lea")
6432 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6433 (const_string "incdec")
6434 (const_string "alu"))))
6435 (set (attr "length_immediate")
6437 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6439 (const_string "*")))
6440 (set_attr "mode" "HI,HI,SI")])
6442 (define_insn "*addqi_1"
6443 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6444 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6445 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6446 (clobber (reg:CC FLAGS_REG))]
6447 "TARGET_PARTIAL_REG_STALL
6448 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6450 int widen = (which_alternative == 2);
6451 switch (get_attr_type (insn))
6454 if (operands[2] == const1_rtx)
6455 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6458 gcc_assert (operands[2] == constm1_rtx);
6459 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6463 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6464 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6465 if (CONST_INT_P (operands[2])
6466 && (INTVAL (operands[2]) == 128
6467 || (INTVAL (operands[2]) < 0
6468 && INTVAL (operands[2]) != -128)))
6470 operands[2] = GEN_INT (-INTVAL (operands[2]));
6472 return "sub{l}\t{%2, %k0|%k0, %2}";
6474 return "sub{b}\t{%2, %0|%0, %2}";
6477 return "add{l}\t{%k2, %k0|%k0, %k2}";
6479 return "add{b}\t{%2, %0|%0, %2}";
6483 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484 (const_string "incdec")
6485 (const_string "alu")))
6486 (set (attr "length_immediate")
6488 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6490 (const_string "*")))
6491 (set_attr "mode" "QI,QI,SI")])
6493 ;; %%% Potential partial reg stall on alternative 2. What to do?
6494 (define_insn "*addqi_1_lea"
6495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6496 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6497 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6498 (clobber (reg:CC FLAGS_REG))]
6499 "!TARGET_PARTIAL_REG_STALL
6500 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6502 int widen = (which_alternative == 2);
6503 switch (get_attr_type (insn))
6508 if (operands[2] == const1_rtx)
6509 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6512 gcc_assert (operands[2] == constm1_rtx);
6513 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6517 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6518 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6519 if (CONST_INT_P (operands[2])
6520 && (INTVAL (operands[2]) == 128
6521 || (INTVAL (operands[2]) < 0
6522 && INTVAL (operands[2]) != -128)))
6524 operands[2] = GEN_INT (-INTVAL (operands[2]));
6526 return "sub{l}\t{%2, %k0|%k0, %2}";
6528 return "sub{b}\t{%2, %0|%0, %2}";
6531 return "add{l}\t{%k2, %k0|%k0, %k2}";
6533 return "add{b}\t{%2, %0|%0, %2}";
6537 (if_then_else (eq_attr "alternative" "3")
6538 (const_string "lea")
6539 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6540 (const_string "incdec")
6541 (const_string "alu"))))
6542 (set (attr "length_immediate")
6544 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6546 (const_string "*")))
6547 (set_attr "mode" "QI,QI,SI,SI")])
6549 (define_insn "*addqi_1_slp"
6550 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6551 (plus:QI (match_dup 0)
6552 (match_operand:QI 1 "general_operand" "qn,qnm")))
6553 (clobber (reg:CC FLAGS_REG))]
6554 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6555 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6557 switch (get_attr_type (insn))
6560 if (operands[1] == const1_rtx)
6561 return "inc{b}\t%0";
6564 gcc_assert (operands[1] == constm1_rtx);
6565 return "dec{b}\t%0";
6569 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6570 if (CONST_INT_P (operands[1])
6571 && INTVAL (operands[1]) < 0)
6573 operands[1] = GEN_INT (-INTVAL (operands[1]));
6574 return "sub{b}\t{%1, %0|%0, %1}";
6576 return "add{b}\t{%1, %0|%0, %1}";
6580 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6581 (const_string "incdec")
6582 (const_string "alu1")))
6583 (set (attr "memory")
6584 (if_then_else (match_operand 1 "memory_operand" "")
6585 (const_string "load")
6586 (const_string "none")))
6587 (set_attr "mode" "QI")])
6589 (define_insn "*add<mode>_2"
6590 [(set (reg FLAGS_REG)
6593 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6594 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6596 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6597 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6598 "ix86_match_ccmode (insn, CCGOCmode)
6599 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6600 /* Current assemblers are broken and do not allow @GOTOFF in
6601 ought but a memory context. */
6602 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6604 switch (get_attr_type (insn))
6607 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6608 if (operands[2] == const1_rtx)
6609 return "inc{<imodesuffix>}\t%0";
6612 gcc_assert (operands[2] == constm1_rtx);
6613 return "dec{<imodesuffix>}\t%0";
6617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6618 /* ???? In DImode, we ought to handle there the 32bit case too
6619 - do we need new constraint? */
6620 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6621 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6622 if (CONST_INT_P (operands[2])
6623 /* Avoid overflows. */
6624 && (<MODE>mode != DImode
6625 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6626 && (INTVAL (operands[2]) == 128
6627 || (INTVAL (operands[2]) < 0
6628 && INTVAL (operands[2]) != -128)))
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6633 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6637 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set (attr "length_immediate")
6642 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6644 (const_string "*")))
6645 (set_attr "mode" "<MODE>")])
6647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6648 (define_insn "*addsi_2_zext"
6649 [(set (reg FLAGS_REG)
6651 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6652 (match_operand:SI 2 "general_operand" "g"))
6654 (set (match_operand:DI 0 "register_operand" "=r")
6655 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6656 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6657 && ix86_binary_operator_ok (PLUS, SImode, operands)
6658 /* Current assemblers are broken and do not allow @GOTOFF in
6659 ought but a memory context. */
6660 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6662 switch (get_attr_type (insn))
6665 if (operands[2] == const1_rtx)
6666 return "inc{l}\t%k0";
6669 gcc_assert (operands[2] == constm1_rtx);
6670 return "dec{l}\t%k0";
6674 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6675 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6676 if (CONST_INT_P (operands[2])
6677 && (INTVAL (operands[2]) == 128
6678 || (INTVAL (operands[2]) < 0
6679 && INTVAL (operands[2]) != -128)))
6681 operands[2] = GEN_INT (-INTVAL (operands[2]));
6682 return "sub{l}\t{%2, %k0|%k0, %2}";
6684 return "add{l}\t{%2, %k0|%k0, %2}";
6688 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6689 (const_string "incdec")
6690 (const_string "alu")))
6691 (set (attr "length_immediate")
6693 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6695 (const_string "*")))
6696 (set_attr "mode" "SI")])
6698 (define_insn "*addhi_2"
6699 [(set (reg FLAGS_REG)
6701 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6702 (match_operand:HI 2 "general_operand" "rmn,rn"))
6704 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6705 (plus:HI (match_dup 1) (match_dup 2)))]
6706 "ix86_match_ccmode (insn, CCGOCmode)
6707 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6709 switch (get_attr_type (insn))
6712 if (operands[2] == const1_rtx)
6713 return "inc{w}\t%0";
6716 gcc_assert (operands[2] == constm1_rtx);
6717 return "dec{w}\t%0";
6721 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6722 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6723 if (CONST_INT_P (operands[2])
6724 && (INTVAL (operands[2]) == 128
6725 || (INTVAL (operands[2]) < 0
6726 && INTVAL (operands[2]) != -128)))
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{w}\t{%2, %0|%0, %2}";
6731 return "add{w}\t{%2, %0|%0, %2}";
6735 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set (attr "length_immediate")
6740 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6742 (const_string "*")))
6743 (set_attr "mode" "HI")])
6745 (define_insn "*addqi_2"
6746 [(set (reg FLAGS_REG)
6748 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6749 (match_operand:QI 2 "general_operand" "qmn,qn"))
6751 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6752 (plus:QI (match_dup 1) (match_dup 2)))]
6753 "ix86_match_ccmode (insn, CCGOCmode)
6754 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6756 switch (get_attr_type (insn))
6759 if (operands[2] == const1_rtx)
6760 return "inc{b}\t%0";
6763 gcc_assert (operands[2] == constm1_rtx
6764 || (CONST_INT_P (operands[2])
6765 && INTVAL (operands[2]) == 255));
6766 return "dec{b}\t%0";
6770 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6771 if (CONST_INT_P (operands[2])
6772 && INTVAL (operands[2]) < 0)
6774 operands[2] = GEN_INT (-INTVAL (operands[2]));
6775 return "sub{b}\t{%2, %0|%0, %2}";
6777 return "add{b}\t{%2, %0|%0, %2}";
6781 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6782 (const_string "incdec")
6783 (const_string "alu")))
6784 (set_attr "mode" "QI")])
6786 (define_insn "*add<mode>_3"
6787 [(set (reg FLAGS_REG)
6789 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6790 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6791 (clobber (match_scratch:SWI48 0 "=r"))]
6792 "ix86_match_ccmode (insn, CCZmode)
6793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6794 /* Current assemblers are broken and do not allow @GOTOFF in
6795 ought but a memory context. */
6796 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6798 switch (get_attr_type (insn))
6801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802 if (operands[2] == const1_rtx)
6803 return "inc{<imodesuffix>}\t%0";
6806 gcc_assert (operands[2] == constm1_rtx);
6807 return "dec{<imodesuffix>}\t%0";
6811 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6812 /* ???? In DImode, we ought to handle there the 32bit case too
6813 - do we need new constraint? */
6814 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6815 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6816 if (CONST_INT_P (operands[2])
6817 /* Avoid overflows. */
6818 && (<MODE>mode != DImode
6819 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
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{<imodesuffix>}\t{%2, %0|%0, %2}";
6827 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6831 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6832 (const_string "incdec")
6833 (const_string "alu")))
6834 (set (attr "length_immediate")
6836 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6838 (const_string "*")))
6839 (set_attr "mode" "<MODE>")])
6841 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6842 (define_insn "*addsi_3_zext"
6843 [(set (reg FLAGS_REG)
6845 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6846 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6847 (set (match_operand:DI 0 "register_operand" "=r")
6848 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6849 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6850 && ix86_binary_operator_ok (PLUS, SImode, operands)
6851 /* Current assemblers are broken and do not allow @GOTOFF in
6852 ought but a memory context. */
6853 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6855 switch (get_attr_type (insn))
6858 if (operands[2] == const1_rtx)
6859 return "inc{l}\t%k0";
6862 gcc_assert (operands[2] == constm1_rtx);
6863 return "dec{l}\t%k0";
6867 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6868 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6869 if (CONST_INT_P (operands[2])
6870 && (INTVAL (operands[2]) == 128
6871 || (INTVAL (operands[2]) < 0
6872 && INTVAL (operands[2]) != -128)))
6874 operands[2] = GEN_INT (-INTVAL (operands[2]));
6875 return "sub{l}\t{%2, %k0|%k0, %2}";
6877 return "add{l}\t{%2, %k0|%k0, %2}";
6881 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6882 (const_string "incdec")
6883 (const_string "alu")))
6884 (set (attr "length_immediate")
6886 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6888 (const_string "*")))
6889 (set_attr "mode" "SI")])
6891 (define_insn "*addhi_3"
6892 [(set (reg FLAGS_REG)
6894 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6895 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6896 (clobber (match_scratch:HI 0 "=r"))]
6897 "ix86_match_ccmode (insn, CCZmode)
6898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900 switch (get_attr_type (insn))
6903 if (operands[2] == const1_rtx)
6904 return "inc{w}\t%0";
6907 gcc_assert (operands[2] == constm1_rtx);
6908 return "dec{w}\t%0";
6912 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6913 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6914 if (CONST_INT_P (operands[2])
6915 && (INTVAL (operands[2]) == 128
6916 || (INTVAL (operands[2]) < 0
6917 && INTVAL (operands[2]) != -128)))
6919 operands[2] = GEN_INT (-INTVAL (operands[2]));
6920 return "sub{w}\t{%2, %0|%0, %2}";
6922 return "add{w}\t{%2, %0|%0, %2}";
6926 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6927 (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" "HI")])
6936 (define_insn "*addqi_3"
6937 [(set (reg FLAGS_REG)
6939 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6940 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6941 (clobber (match_scratch:QI 0 "=q"))]
6942 "ix86_match_ccmode (insn, CCZmode)
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945 switch (get_attr_type (insn))
6948 if (operands[2] == const1_rtx)
6949 return "inc{b}\t%0";
6952 gcc_assert (operands[2] == constm1_rtx
6953 || (CONST_INT_P (operands[2])
6954 && INTVAL (operands[2]) == 255));
6955 return "dec{b}\t%0";
6959 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6960 if (CONST_INT_P (operands[2])
6961 && INTVAL (operands[2]) < 0)
6963 operands[2] = GEN_INT (-INTVAL (operands[2]));
6964 return "sub{b}\t{%2, %0|%0, %2}";
6966 return "add{b}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set_attr "mode" "QI")])
6975 ; For comparisons against 1, -1 and 128, we may generate better code
6976 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6977 ; is matched then. We can't accept general immediate, because for
6978 ; case of overflows, the result is messed up.
6979 ; This pattern also don't hold of 0x8000000000000000, since the value
6980 ; overflows when negated.
6981 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6982 ; only for comparisons not depending on it.
6984 (define_insn "*adddi_4"
6985 [(set (reg FLAGS_REG)
6987 (match_operand:DI 1 "nonimmediate_operand" "0")
6988 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6989 (clobber (match_scratch:DI 0 "=rm"))]
6991 && ix86_match_ccmode (insn, CCGCmode)"
6993 switch (get_attr_type (insn))
6996 if (operands[2] == constm1_rtx)
6997 return "inc{q}\t%0";
7000 gcc_assert (operands[2] == const1_rtx);
7001 return "dec{q}\t%0";
7005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7006 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7007 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7008 if ((INTVAL (operands[2]) == -128
7009 || (INTVAL (operands[2]) > 0
7010 && INTVAL (operands[2]) != 128))
7011 /* Avoid overflows. */
7012 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7013 return "sub{q}\t{%2, %0|%0, %2}";
7014 operands[2] = GEN_INT (-INTVAL (operands[2]));
7015 return "add{q}\t{%2, %0|%0, %2}";
7019 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7020 (const_string "incdec")
7021 (const_string "alu")))
7022 (set (attr "length_immediate")
7024 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7026 (const_string "*")))
7027 (set_attr "mode" "DI")])
7029 ; For comparisons against 1, -1 and 128, we may generate better code
7030 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7031 ; is matched then. We can't accept general immediate, because for
7032 ; case of overflows, the result is messed up.
7033 ; This pattern also don't hold of 0x80000000, since the value overflows
7035 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7036 ; only for comparisons not depending on it.
7038 (define_insn "*addsi_4"
7039 [(set (reg FLAGS_REG)
7041 (match_operand:SI 1 "nonimmediate_operand" "0")
7042 (match_operand:SI 2 "const_int_operand" "n")))
7043 (clobber (match_scratch:SI 0 "=rm"))]
7044 "ix86_match_ccmode (insn, CCGCmode)
7045 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7047 switch (get_attr_type (insn))
7050 if (operands[2] == constm1_rtx)
7051 return "inc{l}\t%0";
7054 gcc_assert (operands[2] == const1_rtx);
7055 return "dec{l}\t%0";
7059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7060 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7061 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7062 if ((INTVAL (operands[2]) == -128
7063 || (INTVAL (operands[2]) > 0
7064 && INTVAL (operands[2]) != 128)))
7065 return "sub{l}\t{%2, %0|%0, %2}";
7066 operands[2] = GEN_INT (-INTVAL (operands[2]));
7067 return "add{l}\t{%2, %0|%0, %2}";
7071 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7072 (const_string "incdec")
7073 (const_string "alu")))
7074 (set (attr "length_immediate")
7076 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7078 (const_string "*")))
7079 (set_attr "mode" "SI")])
7081 ; See comments above addsi_4 for details.
7083 (define_insn "*addhi_4"
7084 [(set (reg FLAGS_REG)
7086 (match_operand:HI 1 "nonimmediate_operand" "0")
7087 (match_operand:HI 2 "const_int_operand" "n")))
7088 (clobber (match_scratch:HI 0 "=rm"))]
7089 "ix86_match_ccmode (insn, CCGCmode)
7090 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7092 switch (get_attr_type (insn))
7095 if (operands[2] == constm1_rtx)
7096 return "inc{w}\t%0";
7099 gcc_assert (operands[2] == const1_rtx);
7100 return "dec{w}\t%0";
7104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7105 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7106 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7107 if ((INTVAL (operands[2]) == -128
7108 || (INTVAL (operands[2]) > 0
7109 && INTVAL (operands[2]) != 128)))
7110 return "sub{w}\t{%2, %0|%0, %2}";
7111 operands[2] = GEN_INT (-INTVAL (operands[2]));
7112 return "add{w}\t{%2, %0|%0, %2}";
7116 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7117 (const_string "incdec")
7118 (const_string "alu")))
7119 (set (attr "length_immediate")
7121 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7123 (const_string "*")))
7124 (set_attr "mode" "HI")])
7126 ; See comments above addsi_4 for details.
7128 (define_insn "*addqi_4"
7129 [(set (reg FLAGS_REG)
7131 (match_operand:QI 1 "nonimmediate_operand" "0")
7132 (match_operand:QI 2 "const_int_operand" "n")))
7133 (clobber (match_scratch:QI 0 "=qm"))]
7134 "ix86_match_ccmode (insn, CCGCmode)
7135 && (INTVAL (operands[2]) & 0xff) != 0x80"
7137 switch (get_attr_type (insn))
7140 if (operands[2] == constm1_rtx
7141 || (CONST_INT_P (operands[2])
7142 && INTVAL (operands[2]) == 255))
7143 return "inc{b}\t%0";
7146 gcc_assert (operands[2] == const1_rtx);
7147 return "dec{b}\t%0";
7151 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7152 if (INTVAL (operands[2]) < 0)
7154 operands[2] = GEN_INT (-INTVAL (operands[2]));
7155 return "add{b}\t{%2, %0|%0, %2}";
7157 return "sub{b}\t{%2, %0|%0, %2}";
7161 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7162 (const_string "incdec")
7163 (const_string "alu")))
7164 (set_attr "mode" "QI")])
7166 (define_insn "*add<mode>_5"
7167 [(set (reg FLAGS_REG)
7170 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
7171 (match_operand:SWI48 2 "<general_operand>" "<g>"))
7173 (clobber (match_scratch:SWI48 0 "=r"))]
7174 "ix86_match_ccmode (insn, CCGOCmode)
7175 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7176 /* Current assemblers are broken and do not allow @GOTOFF in
7177 ought but a memory context. */
7178 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7180 switch (get_attr_type (insn))
7183 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7184 if (operands[2] == const1_rtx)
7185 return "inc{<imodesuffix>}\t%0";
7188 gcc_assert (operands[2] == constm1_rtx);
7189 return "dec{<imodesuffix>}\t%0";
7193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7194 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7195 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7196 if (CONST_INT_P (operands[2])
7197 /* Avoid overflows. */
7198 && (<MODE>mode != DImode
7199 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7200 && (INTVAL (operands[2]) == 128
7201 || (INTVAL (operands[2]) < 0
7202 && INTVAL (operands[2]) != -128)))
7204 operands[2] = GEN_INT (-INTVAL (operands[2]));
7205 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7207 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7211 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
7212 (const_string "incdec")
7213 (const_string "alu")))
7214 (set (attr "length_immediate")
7216 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7218 (const_string "*")))
7219 (set_attr "mode" "<MODE>")])
7221 (define_insn "*addhi_5"
7222 [(set (reg FLAGS_REG)
7224 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7225 (match_operand:HI 2 "general_operand" "rmn"))
7227 (clobber (match_scratch:HI 0 "=r"))]
7228 "ix86_match_ccmode (insn, CCGOCmode)
7229 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7231 switch (get_attr_type (insn))
7234 if (operands[2] == const1_rtx)
7235 return "inc{w}\t%0";
7238 gcc_assert (operands[2] == constm1_rtx);
7239 return "dec{w}\t%0";
7243 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7244 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7245 if (CONST_INT_P (operands[2])
7246 && (INTVAL (operands[2]) == 128
7247 || (INTVAL (operands[2]) < 0
7248 && INTVAL (operands[2]) != -128)))
7250 operands[2] = GEN_INT (-INTVAL (operands[2]));
7251 return "sub{w}\t{%2, %0|%0, %2}";
7253 return "add{w}\t{%2, %0|%0, %2}";
7257 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7258 (const_string "incdec")
7259 (const_string "alu")))
7260 (set (attr "length_immediate")
7262 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7264 (const_string "*")))
7265 (set_attr "mode" "HI")])
7267 (define_insn "*addqi_5"
7268 [(set (reg FLAGS_REG)
7270 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7271 (match_operand:QI 2 "general_operand" "qmn"))
7273 (clobber (match_scratch:QI 0 "=q"))]
7274 "ix86_match_ccmode (insn, CCGOCmode)
7275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7277 switch (get_attr_type (insn))
7280 if (operands[2] == const1_rtx)
7281 return "inc{b}\t%0";
7284 gcc_assert (operands[2] == constm1_rtx
7285 || (CONST_INT_P (operands[2])
7286 && INTVAL (operands[2]) == 255));
7287 return "dec{b}\t%0";
7291 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7292 if (CONST_INT_P (operands[2])
7293 && INTVAL (operands[2]) < 0)
7295 operands[2] = GEN_INT (-INTVAL (operands[2]));
7296 return "sub{b}\t{%2, %0|%0, %2}";
7298 return "add{b}\t{%2, %0|%0, %2}";
7302 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7303 (const_string "incdec")
7304 (const_string "alu")))
7305 (set_attr "mode" "QI")])
7307 (define_insn "*addqi_ext_1_rex64"
7308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7313 (match_operand 1 "ext_register_operand" "0")
7316 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7317 (clobber (reg:CC FLAGS_REG))]
7320 switch (get_attr_type (insn))
7323 if (operands[2] == const1_rtx)
7324 return "inc{b}\t%h0";
7327 gcc_assert (operands[2] == constm1_rtx
7328 || (CONST_INT_P (operands[2])
7329 && INTVAL (operands[2]) == 255));
7330 return "dec{b}\t%h0";
7334 return "add{b}\t{%2, %h0|%h0, %2}";
7338 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7339 (const_string "incdec")
7340 (const_string "alu")))
7341 (set_attr "modrm" "1")
7342 (set_attr "mode" "QI")])
7344 (define_insn "addqi_ext_1"
7345 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7350 (match_operand 1 "ext_register_operand" "0")
7353 (match_operand:QI 2 "general_operand" "Qmn")))
7354 (clobber (reg:CC FLAGS_REG))]
7357 switch (get_attr_type (insn))
7360 if (operands[2] == const1_rtx)
7361 return "inc{b}\t%h0";
7364 gcc_assert (operands[2] == constm1_rtx
7365 || (CONST_INT_P (operands[2])
7366 && INTVAL (operands[2]) == 255));
7367 return "dec{b}\t%h0";
7371 return "add{b}\t{%2, %h0|%h0, %2}";
7375 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7376 (const_string "incdec")
7377 (const_string "alu")))
7378 (set_attr "modrm" "1")
7379 (set_attr "mode" "QI")])
7381 (define_insn "*addqi_ext_2"
7382 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7387 (match_operand 1 "ext_register_operand" "%0")
7391 (match_operand 2 "ext_register_operand" "Q")
7394 (clobber (reg:CC FLAGS_REG))]
7396 "add{b}\t{%h2, %h0|%h0, %h2}"
7397 [(set_attr "type" "alu")
7398 (set_attr "mode" "QI")])
7400 ;; The lea patterns for non-Pmodes needs to be matched by
7401 ;; several insns converted to real lea by splitters.
7403 (define_insn_and_split "*lea_general_1"
7404 [(set (match_operand 0 "register_operand" "=r")
7405 (plus (plus (match_operand 1 "index_register_operand" "l")
7406 (match_operand 2 "register_operand" "r"))
7407 (match_operand 3 "immediate_operand" "i")))]
7408 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7409 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7410 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7411 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7412 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7413 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7414 || GET_MODE (operands[3]) == VOIDmode)"
7416 "&& reload_completed"
7420 operands[0] = gen_lowpart (SImode, operands[0]);
7421 operands[1] = gen_lowpart (Pmode, operands[1]);
7422 operands[2] = gen_lowpart (Pmode, operands[2]);
7423 operands[3] = gen_lowpart (Pmode, operands[3]);
7424 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7426 if (Pmode != SImode)
7427 pat = gen_rtx_SUBREG (SImode, pat, 0);
7428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7431 [(set_attr "type" "lea")
7432 (set_attr "mode" "SI")])
7434 (define_insn_and_split "*lea_general_1_zext"
7435 [(set (match_operand:DI 0 "register_operand" "=r")
7438 (match_operand:SI 1 "index_register_operand" "l")
7439 (match_operand:SI 2 "register_operand" "r"))
7440 (match_operand:SI 3 "immediate_operand" "i"))))]
7443 "&& reload_completed"
7445 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7447 (match_dup 3)) 0)))]
7449 operands[1] = gen_lowpart (Pmode, operands[1]);
7450 operands[2] = gen_lowpart (Pmode, operands[2]);
7451 operands[3] = gen_lowpart (Pmode, operands[3]);
7453 [(set_attr "type" "lea")
7454 (set_attr "mode" "SI")])
7456 (define_insn_and_split "*lea_general_2"
7457 [(set (match_operand 0 "register_operand" "=r")
7458 (plus (mult (match_operand 1 "index_register_operand" "l")
7459 (match_operand 2 "const248_operand" "i"))
7460 (match_operand 3 "nonmemory_operand" "ri")))]
7461 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7462 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7463 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7464 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7465 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7466 || GET_MODE (operands[3]) == VOIDmode)"
7468 "&& reload_completed"
7472 operands[0] = gen_lowpart (SImode, operands[0]);
7473 operands[1] = gen_lowpart (Pmode, operands[1]);
7474 operands[3] = gen_lowpart (Pmode, operands[3]);
7475 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7477 if (Pmode != SImode)
7478 pat = gen_rtx_SUBREG (SImode, pat, 0);
7479 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7482 [(set_attr "type" "lea")
7483 (set_attr "mode" "SI")])
7485 (define_insn_and_split "*lea_general_2_zext"
7486 [(set (match_operand:DI 0 "register_operand" "=r")
7489 (match_operand:SI 1 "index_register_operand" "l")
7490 (match_operand:SI 2 "const248_operand" "n"))
7491 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7494 "&& reload_completed"
7496 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7498 (match_dup 3)) 0)))]
7500 operands[1] = gen_lowpart (Pmode, operands[1]);
7501 operands[3] = gen_lowpart (Pmode, operands[3]);
7503 [(set_attr "type" "lea")
7504 (set_attr "mode" "SI")])
7506 (define_insn_and_split "*lea_general_3"
7507 [(set (match_operand 0 "register_operand" "=r")
7508 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7509 (match_operand 2 "const248_operand" "i"))
7510 (match_operand 3 "register_operand" "r"))
7511 (match_operand 4 "immediate_operand" "i")))]
7512 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7513 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7514 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7515 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7516 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7518 "&& reload_completed"
7522 operands[0] = gen_lowpart (SImode, operands[0]);
7523 operands[1] = gen_lowpart (Pmode, operands[1]);
7524 operands[3] = gen_lowpart (Pmode, operands[3]);
7525 operands[4] = gen_lowpart (Pmode, operands[4]);
7526 pat = gen_rtx_PLUS (Pmode,
7527 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7531 if (Pmode != SImode)
7532 pat = gen_rtx_SUBREG (SImode, pat, 0);
7533 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7536 [(set_attr "type" "lea")
7537 (set_attr "mode" "SI")])
7539 (define_insn_and_split "*lea_general_3_zext"
7540 [(set (match_operand:DI 0 "register_operand" "=r")
7544 (match_operand:SI 1 "index_register_operand" "l")
7545 (match_operand:SI 2 "const248_operand" "n"))
7546 (match_operand:SI 3 "register_operand" "r"))
7547 (match_operand:SI 4 "immediate_operand" "i"))))]
7550 "&& reload_completed"
7552 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7555 (match_dup 4)) 0)))]
7557 operands[1] = gen_lowpart (Pmode, operands[1]);
7558 operands[3] = gen_lowpart (Pmode, operands[3]);
7559 operands[4] = gen_lowpart (Pmode, operands[4]);
7561 [(set_attr "type" "lea")
7562 (set_attr "mode" "SI")])
7564 ;; Convert lea to the lea pattern to avoid flags dependency.
7566 [(set (match_operand:DI 0 "register_operand" "")
7567 (plus:DI (match_operand:DI 1 "register_operand" "")
7568 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7569 (clobber (reg:CC FLAGS_REG))]
7570 "TARGET_64BIT && reload_completed
7571 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7573 (plus:DI (match_dup 1)
7577 ;; Convert lea to the lea pattern to avoid flags dependency.
7579 [(set (match_operand 0 "register_operand" "")
7580 (plus (match_operand 1 "register_operand" "")
7581 (match_operand 2 "nonmemory_operand" "")))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7587 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7588 may confuse gen_lowpart. */
7589 if (GET_MODE (operands[0]) != Pmode)
7591 operands[1] = gen_lowpart (Pmode, operands[1]);
7592 operands[2] = gen_lowpart (Pmode, operands[2]);
7594 operands[0] = gen_lowpart (SImode, operands[0]);
7595 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7596 if (Pmode != SImode)
7597 pat = gen_rtx_SUBREG (SImode, pat, 0);
7598 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7602 ;; Convert lea to the lea pattern to avoid flags dependency.
7604 [(set (match_operand:DI 0 "register_operand" "")
7606 (plus:SI (match_operand:SI 1 "register_operand" "")
7607 (match_operand:SI 2 "nonmemory_operand" ""))))
7608 (clobber (reg:CC FLAGS_REG))]
7609 "TARGET_64BIT && reload_completed
7610 && true_regnum (operands[0]) != true_regnum (operands[1])"
7612 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7614 operands[1] = gen_lowpart (Pmode, operands[1]);
7615 operands[2] = gen_lowpart (Pmode, operands[2]);
7618 ;; Subtract instructions
7620 (define_expand "sub<mode>3"
7621 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7622 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7623 (match_operand:SDWIM 2 "<general_operand>" "")))]
7625 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7627 (define_insn_and_split "*sub<mode>3_doubleword"
7628 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
7630 (match_operand:DWI 1 "nonimmediate_operand" "0,0")
7631 (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
7632 (clobber (reg:CC FLAGS_REG))]
7633 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7636 [(parallel [(set (reg:CC FLAGS_REG)
7637 (compare:CC (match_dup 1) (match_dup 2)))
7639 (minus:<DWIH> (match_dup 1) (match_dup 2)))])
7640 (parallel [(set (match_dup 3)
7644 (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
7646 (clobber (reg:CC FLAGS_REG))])]
7647 "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
7649 (define_insn "sub<mode>3_carry"
7650 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7652 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7654 (match_operand:SWI 3 "ix86_carry_flag_operator" "")
7655 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7656 (clobber (reg:CC FLAGS_REG))]
7657 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7658 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7659 [(set_attr "type" "alu")
7660 (set_attr "use_carry" "1")
7661 (set_attr "pent_pair" "pu")
7662 (set_attr "mode" "<MODE>")])
7664 (define_insn "*subsi3_carry_zext"
7665 [(set (match_operand:DI 0 "register_operand" "=r")
7667 (minus:SI (match_operand:SI 1 "register_operand" "0")
7668 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7669 (match_operand:SI 2 "general_operand" "g")))))
7670 (clobber (reg:CC FLAGS_REG))]
7671 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7672 "sbb{l}\t{%2, %k0|%k0, %2}"
7673 [(set_attr "type" "alu")
7674 (set_attr "pent_pair" "pu")
7675 (set_attr "mode" "SI")])
7677 (define_insn "*sub<mode>3_cconly_overflow"
7678 [(set (reg:CCC FLAGS_REG)
7681 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7682 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7685 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7686 [(set_attr "type" "icmp")
7687 (set_attr "mode" "<MODE>")])
7689 (define_insn "*sub<mode>_1"
7690 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7692 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7693 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7696 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7697 [(set_attr "type" "alu")
7698 (set_attr "mode" "<MODE>")])
7700 (define_insn "*subsi_1_zext"
7701 [(set (match_operand:DI 0 "register_operand" "=r")
7703 (minus:SI (match_operand:SI 1 "register_operand" "0")
7704 (match_operand:SI 2 "general_operand" "g"))))
7705 (clobber (reg:CC FLAGS_REG))]
7706 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7707 "sub{l}\t{%2, %k0|%k0, %2}"
7708 [(set_attr "type" "alu")
7709 (set_attr "mode" "SI")])
7711 (define_insn "*subqi_1_slp"
7712 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7713 (minus:QI (match_dup 0)
7714 (match_operand:QI 1 "general_operand" "qn,qm")))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7717 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7718 "sub{b}\t{%1, %0|%0, %1}"
7719 [(set_attr "type" "alu1")
7720 (set_attr "mode" "QI")])
7722 (define_insn "*sub<mode>_2"
7723 [(set (reg FLAGS_REG)
7726 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7727 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7729 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7730 (minus:SWI (match_dup 1) (match_dup 2)))]
7731 "ix86_match_ccmode (insn, CCGOCmode)
7732 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7733 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7734 [(set_attr "type" "alu")
7735 (set_attr "mode" "<MODE>")])
7737 (define_insn "*subsi_2_zext"
7738 [(set (reg FLAGS_REG)
7740 (minus:SI (match_operand:SI 1 "register_operand" "0")
7741 (match_operand:SI 2 "general_operand" "g"))
7743 (set (match_operand:DI 0 "register_operand" "=r")
7745 (minus:SI (match_dup 1)
7747 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7748 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7749 "sub{l}\t{%2, %k0|%k0, %2}"
7750 [(set_attr "type" "alu")
7751 (set_attr "mode" "SI")])
7753 (define_insn "*sub<mode>_3"
7754 [(set (reg FLAGS_REG)
7755 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7756 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7757 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7758 (minus:SWI (match_dup 1) (match_dup 2)))]
7759 "ix86_match_ccmode (insn, CCmode)
7760 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7761 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7762 [(set_attr "type" "alu")
7763 (set_attr "mode" "<MODE>")])
7765 (define_insn "*subsi_3_zext"
7766 [(set (reg FLAGS_REG)
7767 (compare (match_operand:SI 1 "register_operand" "0")
7768 (match_operand:SI 2 "general_operand" "g")))
7769 (set (match_operand:DI 0 "register_operand" "=r")
7771 (minus:SI (match_dup 1)
7773 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7774 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7775 "sub{l}\t{%2, %1|%1, %2}"
7776 [(set_attr "type" "alu")
7777 (set_attr "mode" "SI")])
7780 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7781 [(set (reg:CCC FLAGS_REG)
7784 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7785 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7787 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7788 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7789 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7790 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7791 [(set_attr "type" "alu")
7792 (set_attr "mode" "<MODE>")])
7794 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7795 [(set (reg:CCC FLAGS_REG)
7798 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7799 (match_operand:SI 2 "general_operand" "g"))
7801 (set (match_operand:DI 0 "register_operand" "=r")
7802 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7803 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7804 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7805 [(set_attr "type" "alu")
7806 (set_attr "mode" "SI")])
7808 ;; The patterns that match these are at the end of this file.
7810 (define_expand "<plusminus_insn>xf3"
7811 [(set (match_operand:XF 0 "register_operand" "")
7813 (match_operand:XF 1 "register_operand" "")
7814 (match_operand:XF 2 "register_operand" "")))]
7818 (define_expand "<plusminus_insn><mode>3"
7819 [(set (match_operand:MODEF 0 "register_operand" "")
7821 (match_operand:MODEF 1 "register_operand" "")
7822 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7824 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7827 ;; Multiply instructions
7829 (define_expand "muldi3"
7830 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7831 (mult:DI (match_operand:DI 1 "register_operand" "")
7832 (match_operand:DI 2 "x86_64_general_operand" "")))
7833 (clobber (reg:CC FLAGS_REG))])]
7838 ;; IMUL reg64, reg64, imm8 Direct
7839 ;; IMUL reg64, mem64, imm8 VectorPath
7840 ;; IMUL reg64, reg64, imm32 Direct
7841 ;; IMUL reg64, mem64, imm32 VectorPath
7842 ;; IMUL reg64, reg64 Direct
7843 ;; IMUL reg64, mem64 Direct
7845 (define_insn "*muldi3_1_rex64"
7846 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7847 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7848 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7849 (clobber (reg:CC FLAGS_REG))]
7851 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7853 imul{q}\t{%2, %1, %0|%0, %1, %2}
7854 imul{q}\t{%2, %1, %0|%0, %1, %2}
7855 imul{q}\t{%2, %0|%0, %2}"
7856 [(set_attr "type" "imul")
7857 (set_attr "prefix_0f" "0,0,1")
7858 (set (attr "athlon_decode")
7859 (cond [(eq_attr "cpu" "athlon")
7860 (const_string "vector")
7861 (eq_attr "alternative" "1")
7862 (const_string "vector")
7863 (and (eq_attr "alternative" "2")
7864 (match_operand 1 "memory_operand" ""))
7865 (const_string "vector")]
7866 (const_string "direct")))
7867 (set (attr "amdfam10_decode")
7868 (cond [(and (eq_attr "alternative" "0,1")
7869 (match_operand 1 "memory_operand" ""))
7870 (const_string "vector")]
7871 (const_string "direct")))
7872 (set_attr "mode" "DI")])
7874 (define_expand "mulsi3"
7875 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7876 (mult:SI (match_operand:SI 1 "register_operand" "")
7877 (match_operand:SI 2 "general_operand" "")))
7878 (clobber (reg:CC FLAGS_REG))])]
7883 ;; IMUL reg32, reg32, imm8 Direct
7884 ;; IMUL reg32, mem32, imm8 VectorPath
7885 ;; IMUL reg32, reg32, imm32 Direct
7886 ;; IMUL reg32, mem32, imm32 VectorPath
7887 ;; IMUL reg32, reg32 Direct
7888 ;; IMUL reg32, mem32 Direct
7890 (define_insn "*mulsi3_1"
7891 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7892 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7893 (match_operand:SI 2 "general_operand" "K,i,mr")))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7897 imul{l}\t{%2, %1, %0|%0, %1, %2}
7898 imul{l}\t{%2, %1, %0|%0, %1, %2}
7899 imul{l}\t{%2, %0|%0, %2}"
7900 [(set_attr "type" "imul")
7901 (set_attr "prefix_0f" "0,0,1")
7902 (set (attr "athlon_decode")
7903 (cond [(eq_attr "cpu" "athlon")
7904 (const_string "vector")
7905 (eq_attr "alternative" "1")
7906 (const_string "vector")
7907 (and (eq_attr "alternative" "2")
7908 (match_operand 1 "memory_operand" ""))
7909 (const_string "vector")]
7910 (const_string "direct")))
7911 (set (attr "amdfam10_decode")
7912 (cond [(and (eq_attr "alternative" "0,1")
7913 (match_operand 1 "memory_operand" ""))
7914 (const_string "vector")]
7915 (const_string "direct")))
7916 (set_attr "mode" "SI")])
7918 (define_insn "*mulsi3_1_zext"
7919 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7921 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7922 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7923 (clobber (reg:CC FLAGS_REG))]
7925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7927 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7929 imul{l}\t{%2, %k0|%k0, %2}"
7930 [(set_attr "type" "imul")
7931 (set_attr "prefix_0f" "0,0,1")
7932 (set (attr "athlon_decode")
7933 (cond [(eq_attr "cpu" "athlon")
7934 (const_string "vector")
7935 (eq_attr "alternative" "1")
7936 (const_string "vector")
7937 (and (eq_attr "alternative" "2")
7938 (match_operand 1 "memory_operand" ""))
7939 (const_string "vector")]
7940 (const_string "direct")))
7941 (set (attr "amdfam10_decode")
7942 (cond [(and (eq_attr "alternative" "0,1")
7943 (match_operand 1 "memory_operand" ""))
7944 (const_string "vector")]
7945 (const_string "direct")))
7946 (set_attr "mode" "SI")])
7948 (define_expand "mulhi3"
7949 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7950 (mult:HI (match_operand:HI 1 "register_operand" "")
7951 (match_operand:HI 2 "general_operand" "")))
7952 (clobber (reg:CC FLAGS_REG))])]
7953 "TARGET_HIMODE_MATH"
7957 ;; IMUL reg16, reg16, imm8 VectorPath
7958 ;; IMUL reg16, mem16, imm8 VectorPath
7959 ;; IMUL reg16, reg16, imm16 VectorPath
7960 ;; IMUL reg16, mem16, imm16 VectorPath
7961 ;; IMUL reg16, reg16 Direct
7962 ;; IMUL reg16, mem16 Direct
7963 (define_insn "*mulhi3_1"
7964 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7965 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7966 (match_operand:HI 2 "general_operand" "K,n,mr")))
7967 (clobber (reg:CC FLAGS_REG))]
7968 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7970 imul{w}\t{%2, %1, %0|%0, %1, %2}
7971 imul{w}\t{%2, %1, %0|%0, %1, %2}
7972 imul{w}\t{%2, %0|%0, %2}"
7973 [(set_attr "type" "imul")
7974 (set_attr "prefix_0f" "0,0,1")
7975 (set (attr "athlon_decode")
7976 (cond [(eq_attr "cpu" "athlon")
7977 (const_string "vector")
7978 (eq_attr "alternative" "1,2")
7979 (const_string "vector")]
7980 (const_string "direct")))
7981 (set (attr "amdfam10_decode")
7982 (cond [(eq_attr "alternative" "0,1")
7983 (const_string "vector")]
7984 (const_string "direct")))
7985 (set_attr "mode" "HI")])
7987 (define_expand "mulqi3"
7988 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7989 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7990 (match_operand:QI 2 "register_operand" "")))
7991 (clobber (reg:CC FLAGS_REG))])]
7992 "TARGET_QIMODE_MATH"
7999 (define_insn "*mulqi3_1"
8000 [(set (match_operand:QI 0 "register_operand" "=a")
8001 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8002 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8003 (clobber (reg:CC FLAGS_REG))]
8005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8007 [(set_attr "type" "imul")
8008 (set_attr "length_immediate" "0")
8009 (set (attr "athlon_decode")
8010 (if_then_else (eq_attr "cpu" "athlon")
8011 (const_string "vector")
8012 (const_string "direct")))
8013 (set_attr "amdfam10_decode" "direct")
8014 (set_attr "mode" "QI")])
8016 (define_expand "umulqihi3"
8017 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8018 (mult:HI (zero_extend:HI
8019 (match_operand:QI 1 "nonimmediate_operand" ""))
8021 (match_operand:QI 2 "register_operand" ""))))
8022 (clobber (reg:CC FLAGS_REG))])]
8023 "TARGET_QIMODE_MATH"
8026 (define_insn "*umulqihi3_1"
8027 [(set (match_operand:HI 0 "register_operand" "=a")
8028 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8029 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8030 (clobber (reg:CC FLAGS_REG))]
8032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8034 [(set_attr "type" "imul")
8035 (set_attr "length_immediate" "0")
8036 (set (attr "athlon_decode")
8037 (if_then_else (eq_attr "cpu" "athlon")
8038 (const_string "vector")
8039 (const_string "direct")))
8040 (set_attr "amdfam10_decode" "direct")
8041 (set_attr "mode" "QI")])
8043 (define_expand "mulqihi3"
8044 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8045 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8046 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8047 (clobber (reg:CC FLAGS_REG))])]
8048 "TARGET_QIMODE_MATH"
8051 (define_insn "*mulqihi3_insn"
8052 [(set (match_operand:HI 0 "register_operand" "=a")
8053 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8054 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8055 (clobber (reg:CC FLAGS_REG))]
8057 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8059 [(set_attr "type" "imul")
8060 (set_attr "length_immediate" "0")
8061 (set (attr "athlon_decode")
8062 (if_then_else (eq_attr "cpu" "athlon")
8063 (const_string "vector")
8064 (const_string "direct")))
8065 (set_attr "amdfam10_decode" "direct")
8066 (set_attr "mode" "QI")])
8068 (define_expand "umulditi3"
8069 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8070 (mult:TI (zero_extend:TI
8071 (match_operand:DI 1 "nonimmediate_operand" ""))
8073 (match_operand:DI 2 "register_operand" ""))))
8074 (clobber (reg:CC FLAGS_REG))])]
8078 (define_insn "*umulditi3_insn"
8079 [(set (match_operand:TI 0 "register_operand" "=A")
8080 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8081 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8082 (clobber (reg:CC FLAGS_REG))]
8084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8086 [(set_attr "type" "imul")
8087 (set_attr "length_immediate" "0")
8088 (set (attr "athlon_decode")
8089 (if_then_else (eq_attr "cpu" "athlon")
8090 (const_string "vector")
8091 (const_string "double")))
8092 (set_attr "amdfam10_decode" "double")
8093 (set_attr "mode" "DI")])
8095 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8096 (define_expand "umulsidi3"
8097 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8098 (mult:DI (zero_extend:DI
8099 (match_operand:SI 1 "nonimmediate_operand" ""))
8101 (match_operand:SI 2 "register_operand" ""))))
8102 (clobber (reg:CC FLAGS_REG))])]
8106 (define_insn "*umulsidi3_insn"
8107 [(set (match_operand:DI 0 "register_operand" "=A")
8108 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8109 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8110 (clobber (reg:CC FLAGS_REG))]
8112 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8114 [(set_attr "type" "imul")
8115 (set_attr "length_immediate" "0")
8116 (set (attr "athlon_decode")
8117 (if_then_else (eq_attr "cpu" "athlon")
8118 (const_string "vector")
8119 (const_string "double")))
8120 (set_attr "amdfam10_decode" "double")
8121 (set_attr "mode" "SI")])
8123 (define_expand "mulditi3"
8124 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8125 (mult:TI (sign_extend:TI
8126 (match_operand:DI 1 "nonimmediate_operand" ""))
8128 (match_operand:DI 2 "register_operand" ""))))
8129 (clobber (reg:CC FLAGS_REG))])]
8133 (define_insn "*mulditi3_insn"
8134 [(set (match_operand:TI 0 "register_operand" "=A")
8135 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8136 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8137 (clobber (reg:CC FLAGS_REG))]
8139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8141 [(set_attr "type" "imul")
8142 (set_attr "length_immediate" "0")
8143 (set (attr "athlon_decode")
8144 (if_then_else (eq_attr "cpu" "athlon")
8145 (const_string "vector")
8146 (const_string "double")))
8147 (set_attr "amdfam10_decode" "double")
8148 (set_attr "mode" "DI")])
8150 (define_expand "mulsidi3"
8151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8152 (mult:DI (sign_extend:DI
8153 (match_operand:SI 1 "nonimmediate_operand" ""))
8155 (match_operand:SI 2 "register_operand" ""))))
8156 (clobber (reg:CC FLAGS_REG))])]
8160 (define_insn "*mulsidi3_insn"
8161 [(set (match_operand:DI 0 "register_operand" "=A")
8162 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8163 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8164 (clobber (reg:CC FLAGS_REG))]
8166 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8168 [(set_attr "type" "imul")
8169 (set_attr "length_immediate" "0")
8170 (set (attr "athlon_decode")
8171 (if_then_else (eq_attr "cpu" "athlon")
8172 (const_string "vector")
8173 (const_string "double")))
8174 (set_attr "amdfam10_decode" "double")
8175 (set_attr "mode" "SI")])
8177 (define_expand "umuldi3_highpart"
8178 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8181 (mult:TI (zero_extend:TI
8182 (match_operand:DI 1 "nonimmediate_operand" ""))
8184 (match_operand:DI 2 "register_operand" "")))
8186 (clobber (match_scratch:DI 3 ""))
8187 (clobber (reg:CC FLAGS_REG))])]
8191 (define_insn "*umuldi3_highpart_rex64"
8192 [(set (match_operand:DI 0 "register_operand" "=d")
8195 (mult:TI (zero_extend:TI
8196 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8198 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8200 (clobber (match_scratch:DI 3 "=1"))
8201 (clobber (reg:CC FLAGS_REG))]
8203 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8205 [(set_attr "type" "imul")
8206 (set_attr "length_immediate" "0")
8207 (set (attr "athlon_decode")
8208 (if_then_else (eq_attr "cpu" "athlon")
8209 (const_string "vector")
8210 (const_string "double")))
8211 (set_attr "amdfam10_decode" "double")
8212 (set_attr "mode" "DI")])
8214 (define_expand "umulsi3_highpart"
8215 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8218 (mult:DI (zero_extend:DI
8219 (match_operand:SI 1 "nonimmediate_operand" ""))
8221 (match_operand:SI 2 "register_operand" "")))
8223 (clobber (match_scratch:SI 3 ""))
8224 (clobber (reg:CC FLAGS_REG))])]
8228 (define_insn "*umulsi3_highpart_insn"
8229 [(set (match_operand:SI 0 "register_operand" "=d")
8232 (mult:DI (zero_extend:DI
8233 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8235 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8237 (clobber (match_scratch:SI 3 "=1"))
8238 (clobber (reg:CC FLAGS_REG))]
8239 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8241 [(set_attr "type" "imul")
8242 (set_attr "length_immediate" "0")
8243 (set (attr "athlon_decode")
8244 (if_then_else (eq_attr "cpu" "athlon")
8245 (const_string "vector")
8246 (const_string "double")))
8247 (set_attr "amdfam10_decode" "double")
8248 (set_attr "mode" "SI")])
8250 (define_insn "*umulsi3_highpart_zext"
8251 [(set (match_operand:DI 0 "register_operand" "=d")
8252 (zero_extend:DI (truncate:SI
8254 (mult:DI (zero_extend:DI
8255 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8257 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8259 (clobber (match_scratch:SI 3 "=1"))
8260 (clobber (reg:CC FLAGS_REG))]
8262 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8264 [(set_attr "type" "imul")
8265 (set_attr "length_immediate" "0")
8266 (set (attr "athlon_decode")
8267 (if_then_else (eq_attr "cpu" "athlon")
8268 (const_string "vector")
8269 (const_string "double")))
8270 (set_attr "amdfam10_decode" "double")
8271 (set_attr "mode" "SI")])
8273 (define_expand "smuldi3_highpart"
8274 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8277 (mult:TI (sign_extend:TI
8278 (match_operand:DI 1 "nonimmediate_operand" ""))
8280 (match_operand:DI 2 "register_operand" "")))
8282 (clobber (match_scratch:DI 3 ""))
8283 (clobber (reg:CC FLAGS_REG))])]
8287 (define_insn "*smuldi3_highpart_rex64"
8288 [(set (match_operand:DI 0 "register_operand" "=d")
8291 (mult:TI (sign_extend:TI
8292 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8294 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8296 (clobber (match_scratch:DI 3 "=1"))
8297 (clobber (reg:CC FLAGS_REG))]
8299 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8301 [(set_attr "type" "imul")
8302 (set (attr "athlon_decode")
8303 (if_then_else (eq_attr "cpu" "athlon")
8304 (const_string "vector")
8305 (const_string "double")))
8306 (set_attr "amdfam10_decode" "double")
8307 (set_attr "mode" "DI")])
8309 (define_expand "smulsi3_highpart"
8310 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8313 (mult:DI (sign_extend:DI
8314 (match_operand:SI 1 "nonimmediate_operand" ""))
8316 (match_operand:SI 2 "register_operand" "")))
8318 (clobber (match_scratch:SI 3 ""))
8319 (clobber (reg:CC FLAGS_REG))])]
8323 (define_insn "*smulsi3_highpart_insn"
8324 [(set (match_operand:SI 0 "register_operand" "=d")
8327 (mult:DI (sign_extend:DI
8328 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8330 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8332 (clobber (match_scratch:SI 3 "=1"))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8336 [(set_attr "type" "imul")
8337 (set (attr "athlon_decode")
8338 (if_then_else (eq_attr "cpu" "athlon")
8339 (const_string "vector")
8340 (const_string "double")))
8341 (set_attr "amdfam10_decode" "double")
8342 (set_attr "mode" "SI")])
8344 (define_insn "*smulsi3_highpart_zext"
8345 [(set (match_operand:DI 0 "register_operand" "=d")
8346 (zero_extend:DI (truncate:SI
8348 (mult:DI (sign_extend:DI
8349 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8351 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8353 (clobber (match_scratch:SI 3 "=1"))
8354 (clobber (reg:CC FLAGS_REG))]
8356 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8358 [(set_attr "type" "imul")
8359 (set (attr "athlon_decode")
8360 (if_then_else (eq_attr "cpu" "athlon")
8361 (const_string "vector")
8362 (const_string "double")))
8363 (set_attr "amdfam10_decode" "double")
8364 (set_attr "mode" "SI")])
8366 ;; The patterns that match these are at the end of this file.
8368 (define_expand "mulxf3"
8369 [(set (match_operand:XF 0 "register_operand" "")
8370 (mult:XF (match_operand:XF 1 "register_operand" "")
8371 (match_operand:XF 2 "register_operand" "")))]
8375 (define_expand "mul<mode>3"
8376 [(set (match_operand:MODEF 0 "register_operand" "")
8377 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8378 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8379 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8380 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8384 ;; Divide instructions
8386 (define_insn "divqi3"
8387 [(set (match_operand:QI 0 "register_operand" "=a")
8388 (div:QI (match_operand:HI 1 "register_operand" "0")
8389 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "TARGET_QIMODE_MATH"
8393 [(set_attr "type" "idiv")
8394 (set_attr "mode" "QI")])
8396 (define_insn "udivqi3"
8397 [(set (match_operand:QI 0 "register_operand" "=a")
8398 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400 (clobber (reg:CC FLAGS_REG))]
8401 "TARGET_QIMODE_MATH"
8403 [(set_attr "type" "idiv")
8404 (set_attr "mode" "QI")])
8406 ;; The patterns that match these are at the end of this file.
8408 (define_expand "divxf3"
8409 [(set (match_operand:XF 0 "register_operand" "")
8410 (div:XF (match_operand:XF 1 "register_operand" "")
8411 (match_operand:XF 2 "register_operand" "")))]
8415 (define_expand "divdf3"
8416 [(set (match_operand:DF 0 "register_operand" "")
8417 (div:DF (match_operand:DF 1 "register_operand" "")
8418 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8420 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8423 (define_expand "divsf3"
8424 [(set (match_operand:SF 0 "register_operand" "")
8425 (div:SF (match_operand:SF 1 "register_operand" "")
8426 (match_operand:SF 2 "nonimmediate_operand" "")))]
8427 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8430 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8431 && flag_finite_math_only && !flag_trapping_math
8432 && flag_unsafe_math_optimizations)
8434 ix86_emit_swdivsf (operands[0], operands[1],
8435 operands[2], SFmode);
8440 ;; Divmod instructions.
8442 (define_expand "divmod<mode>4"
8443 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8445 (match_operand:SWIM248 1 "register_operand" "")
8446 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8447 (set (match_operand:SWIM248 3 "register_operand" "")
8448 (mod:SWIM248 (match_dup 1) (match_dup 2)))
8449 (clobber (reg:CC FLAGS_REG))])]
8453 (define_insn_and_split "*divmod<mode>4"
8454 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8455 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8456 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8457 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8458 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8459 (clobber (reg:CC FLAGS_REG))]
8462 "&& reload_completed"
8463 [(parallel [(set (match_dup 1)
8464 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8465 (clobber (reg:CC FLAGS_REG))])
8466 (parallel [(set (match_dup 0)
8467 (div:SWIM248 (match_dup 2) (match_dup 3)))
8469 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8471 (clobber (reg:CC FLAGS_REG))])]
8473 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8475 if (<MODE>mode != HImode
8476 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8477 operands[4] = operands[2];
8480 /* Avoid use of cltd in favor of a mov+shift. */
8481 emit_move_insn (operands[1], operands[2]);
8482 operands[4] = operands[1];
8485 [(set_attr "type" "multi")
8486 (set_attr "mode" "<MODE>")])
8488 (define_insn "*divmod<mode>4_noext"
8489 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8490 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8491 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8492 (set (match_operand:SWIM248 1 "register_operand" "=d")
8493 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8494 (use (match_operand:SWIM248 4 "register_operand" "1"))
8495 (clobber (reg:CC FLAGS_REG))]
8497 "idiv{<imodesuffix>}\t%3"
8498 [(set_attr "type" "idiv")
8499 (set_attr "mode" "<MODE>")])
8501 (define_expand "udivmod<mode>4"
8502 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8504 (match_operand:SWIM248 1 "register_operand" "")
8505 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8506 (set (match_operand:SWIM248 3 "register_operand" "")
8507 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8508 (clobber (reg:CC FLAGS_REG))])]
8512 (define_insn_and_split "*udivmod<mode>4"
8513 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8514 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8515 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8516 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8517 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8518 (clobber (reg:CC FLAGS_REG))]
8521 "&& reload_completed"
8522 [(set (match_dup 1) (const_int 0))
8523 (parallel [(set (match_dup 0)
8524 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8526 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8528 (clobber (reg:CC FLAGS_REG))])]
8530 [(set_attr "type" "multi")
8531 (set_attr "mode" "<MODE>")])
8533 (define_insn "*udivmod<mode>4_noext"
8534 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8535 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8536 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8537 (set (match_operand:SWIM248 1 "register_operand" "=d")
8538 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8539 (use (match_operand:SWIM248 4 "register_operand" "1"))
8540 (clobber (reg:CC FLAGS_REG))]
8542 "div{<imodesuffix>}\t%3"
8543 [(set_attr "type" "idiv")
8544 (set_attr "mode" "<MODE>")])
8546 ;; We cannot use div/idiv for double division, because it causes
8547 ;; "division by zero" on the overflow and that's not what we expect
8548 ;; from truncate. Because true (non truncating) double division is
8549 ;; never generated, we can't create this insn anyway.
8552 ; [(set (match_operand:SI 0 "register_operand" "=a")
8554 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8556 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8557 ; (set (match_operand:SI 3 "register_operand" "=d")
8559 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8560 ; (clobber (reg:CC FLAGS_REG))]
8562 ; "div{l}\t{%2, %0|%0, %2}"
8563 ; [(set_attr "type" "idiv")])
8565 ;;- Logical AND instructions
8567 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8568 ;; Note that this excludes ah.
8570 (define_insn "*testdi_1_rex64"
8571 [(set (reg FLAGS_REG)
8573 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8574 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8576 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8577 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8579 test{l}\t{%k1, %k0|%k0, %k1}
8580 test{l}\t{%k1, %k0|%k0, %k1}
8581 test{q}\t{%1, %0|%0, %1}
8582 test{q}\t{%1, %0|%0, %1}
8583 test{q}\t{%1, %0|%0, %1}"
8584 [(set_attr "type" "test")
8585 (set_attr "modrm" "0,1,0,1,1")
8586 (set_attr "mode" "SI,SI,DI,DI,DI")
8587 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8589 (define_insn "testsi_1"
8590 [(set (reg FLAGS_REG)
8592 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8593 (match_operand:SI 1 "general_operand" "i,i,ri"))
8595 "ix86_match_ccmode (insn, CCNOmode)
8596 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8597 "test{l}\t{%1, %0|%0, %1}"
8598 [(set_attr "type" "test")
8599 (set_attr "modrm" "0,1,1")
8600 (set_attr "mode" "SI")
8601 (set_attr "pent_pair" "uv,np,uv")])
8603 (define_expand "testsi_ccno_1"
8604 [(set (reg:CCNO FLAGS_REG)
8606 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8607 (match_operand:SI 1 "nonmemory_operand" ""))
8612 (define_insn "*testhi_1"
8613 [(set (reg FLAGS_REG)
8614 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8615 (match_operand:HI 1 "general_operand" "n,n,rn"))
8617 "ix86_match_ccmode (insn, CCNOmode)
8618 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8619 "test{w}\t{%1, %0|%0, %1}"
8620 [(set_attr "type" "test")
8621 (set_attr "modrm" "0,1,1")
8622 (set_attr "mode" "HI")
8623 (set_attr "pent_pair" "uv,np,uv")])
8625 (define_expand "testqi_ccz_1"
8626 [(set (reg:CCZ FLAGS_REG)
8627 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8628 (match_operand:QI 1 "nonmemory_operand" ""))
8633 (define_insn "*testqi_1_maybe_si"
8634 [(set (reg FLAGS_REG)
8637 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8638 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8640 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8641 && ix86_match_ccmode (insn,
8642 CONST_INT_P (operands[1])
8643 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8645 if (which_alternative == 3)
8647 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8648 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8649 return "test{l}\t{%1, %k0|%k0, %1}";
8651 return "test{b}\t{%1, %0|%0, %1}";
8653 [(set_attr "type" "test")
8654 (set_attr "modrm" "0,1,1,1")
8655 (set_attr "mode" "QI,QI,QI,SI")
8656 (set_attr "pent_pair" "uv,np,uv,np")])
8658 (define_insn "*testqi_1"
8659 [(set (reg FLAGS_REG)
8662 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8663 (match_operand:QI 1 "general_operand" "n,n,qn"))
8665 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8666 && ix86_match_ccmode (insn, CCNOmode)"
8667 "test{b}\t{%1, %0|%0, %1}"
8668 [(set_attr "type" "test")
8669 (set_attr "modrm" "0,1,1")
8670 (set_attr "mode" "QI")
8671 (set_attr "pent_pair" "uv,np,uv")])
8673 (define_expand "testqi_ext_ccno_0"
8674 [(set (reg:CCNO FLAGS_REG)
8678 (match_operand 0 "ext_register_operand" "")
8681 (match_operand 1 "const_int_operand" ""))
8686 (define_insn "*testqi_ext_0"
8687 [(set (reg FLAGS_REG)
8691 (match_operand 0 "ext_register_operand" "Q")
8694 (match_operand 1 "const_int_operand" "n"))
8696 "ix86_match_ccmode (insn, CCNOmode)"
8697 "test{b}\t{%1, %h0|%h0, %1}"
8698 [(set_attr "type" "test")
8699 (set_attr "mode" "QI")
8700 (set_attr "length_immediate" "1")
8701 (set_attr "modrm" "1")
8702 (set_attr "pent_pair" "np")])
8704 (define_insn "*testqi_ext_1"
8705 [(set (reg FLAGS_REG)
8709 (match_operand 0 "ext_register_operand" "Q")
8713 (match_operand:QI 1 "general_operand" "Qm")))
8715 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8716 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8717 "test{b}\t{%1, %h0|%h0, %1}"
8718 [(set_attr "type" "test")
8719 (set_attr "mode" "QI")])
8721 (define_insn "*testqi_ext_1_rex64"
8722 [(set (reg FLAGS_REG)
8726 (match_operand 0 "ext_register_operand" "Q")
8730 (match_operand:QI 1 "register_operand" "Q")))
8732 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8733 "test{b}\t{%1, %h0|%h0, %1}"
8734 [(set_attr "type" "test")
8735 (set_attr "mode" "QI")])
8737 (define_insn "*testqi_ext_2"
8738 [(set (reg FLAGS_REG)
8742 (match_operand 0 "ext_register_operand" "Q")
8746 (match_operand 1 "ext_register_operand" "Q")
8750 "ix86_match_ccmode (insn, CCNOmode)"
8751 "test{b}\t{%h1, %h0|%h0, %h1}"
8752 [(set_attr "type" "test")
8753 (set_attr "mode" "QI")])
8755 ;; Combine likes to form bit extractions for some tests. Humor it.
8756 (define_insn "*testqi_ext_3"
8757 [(set (reg FLAGS_REG)
8758 (compare (zero_extract:SI
8759 (match_operand 0 "nonimmediate_operand" "rm")
8760 (match_operand:SI 1 "const_int_operand" "")
8761 (match_operand:SI 2 "const_int_operand" ""))
8763 "ix86_match_ccmode (insn, CCNOmode)
8764 && INTVAL (operands[1]) > 0
8765 && INTVAL (operands[2]) >= 0
8766 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8767 && (GET_MODE (operands[0]) == SImode
8768 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8769 || GET_MODE (operands[0]) == HImode
8770 || GET_MODE (operands[0]) == QImode)"
8773 (define_insn "*testqi_ext_3_rex64"
8774 [(set (reg FLAGS_REG)
8775 (compare (zero_extract:DI
8776 (match_operand 0 "nonimmediate_operand" "rm")
8777 (match_operand:DI 1 "const_int_operand" "")
8778 (match_operand:DI 2 "const_int_operand" ""))
8781 && ix86_match_ccmode (insn, CCNOmode)
8782 && INTVAL (operands[1]) > 0
8783 && INTVAL (operands[2]) >= 0
8784 /* Ensure that resulting mask is zero or sign extended operand. */
8785 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8786 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8787 && INTVAL (operands[1]) > 32))
8788 && (GET_MODE (operands[0]) == SImode
8789 || GET_MODE (operands[0]) == DImode
8790 || GET_MODE (operands[0]) == HImode
8791 || GET_MODE (operands[0]) == QImode)"
8795 [(set (match_operand 0 "flags_reg_operand" "")
8796 (match_operator 1 "compare_operator"
8798 (match_operand 2 "nonimmediate_operand" "")
8799 (match_operand 3 "const_int_operand" "")
8800 (match_operand 4 "const_int_operand" ""))
8802 "ix86_match_ccmode (insn, CCNOmode)"
8803 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8805 rtx val = operands[2];
8806 HOST_WIDE_INT len = INTVAL (operands[3]);
8807 HOST_WIDE_INT pos = INTVAL (operands[4]);
8809 enum machine_mode mode, submode;
8811 mode = GET_MODE (val);
8814 /* ??? Combine likes to put non-volatile mem extractions in QImode
8815 no matter the size of the test. So find a mode that works. */
8816 if (! MEM_VOLATILE_P (val))
8818 mode = smallest_mode_for_size (pos + len, MODE_INT);
8819 val = adjust_address (val, mode, 0);
8822 else if (GET_CODE (val) == SUBREG
8823 && (submode = GET_MODE (SUBREG_REG (val)),
8824 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8825 && pos + len <= GET_MODE_BITSIZE (submode))
8827 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8829 val = SUBREG_REG (val);
8831 else if (mode == HImode && pos + len <= 8)
8833 /* Small HImode tests can be converted to QImode. */
8835 val = gen_lowpart (QImode, val);
8838 if (len == HOST_BITS_PER_WIDE_INT)
8841 mask = ((HOST_WIDE_INT)1 << len) - 1;
8844 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8847 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8848 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8849 ;; this is relatively important trick.
8850 ;; Do the conversion only post-reload to avoid limiting of the register class
8853 [(set (match_operand 0 "flags_reg_operand" "")
8854 (match_operator 1 "compare_operator"
8855 [(and (match_operand 2 "register_operand" "")
8856 (match_operand 3 "const_int_operand" ""))
8859 && QI_REG_P (operands[2])
8860 && GET_MODE (operands[2]) != QImode
8861 && ((ix86_match_ccmode (insn, CCZmode)
8862 && !(INTVAL (operands[3]) & ~(255 << 8)))
8863 || (ix86_match_ccmode (insn, CCNOmode)
8864 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8867 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8870 "operands[2] = gen_lowpart (SImode, operands[2]);
8871 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8874 [(set (match_operand 0 "flags_reg_operand" "")
8875 (match_operator 1 "compare_operator"
8876 [(and (match_operand 2 "nonimmediate_operand" "")
8877 (match_operand 3 "const_int_operand" ""))
8880 && GET_MODE (operands[2]) != QImode
8881 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8882 && ((ix86_match_ccmode (insn, CCZmode)
8883 && !(INTVAL (operands[3]) & ~255))
8884 || (ix86_match_ccmode (insn, CCNOmode)
8885 && !(INTVAL (operands[3]) & ~127)))"
8887 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8889 "operands[2] = gen_lowpart (QImode, operands[2]);
8890 operands[3] = gen_lowpart (QImode, operands[3]);")
8893 ;; %%% This used to optimize known byte-wide and operations to memory,
8894 ;; and sometimes to QImode registers. If this is considered useful,
8895 ;; it should be done with splitters.
8897 (define_expand "anddi3"
8898 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8902 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8904 (define_insn "*anddi_1_rex64"
8905 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8906 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8907 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8908 (clobber (reg:CC FLAGS_REG))]
8909 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8911 switch (get_attr_type (insn))
8915 enum machine_mode mode;
8917 gcc_assert (CONST_INT_P (operands[2]));
8918 if (INTVAL (operands[2]) == 0xff)
8922 gcc_assert (INTVAL (operands[2]) == 0xffff);
8926 operands[1] = gen_lowpart (mode, operands[1]);
8928 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8930 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8934 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8935 if (get_attr_mode (insn) == MODE_SI)
8936 return "and{l}\t{%k2, %k0|%k0, %k2}";
8938 return "and{q}\t{%2, %0|%0, %2}";
8941 [(set_attr "type" "alu,alu,alu,imovx")
8942 (set_attr "length_immediate" "*,*,*,0")
8943 (set (attr "prefix_rex")
8945 (and (eq_attr "type" "imovx")
8946 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8947 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8949 (const_string "*")))
8950 (set_attr "mode" "SI,DI,DI,SI")])
8952 (define_insn "*anddi_2"
8953 [(set (reg FLAGS_REG)
8954 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8955 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8957 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8958 (and:DI (match_dup 1) (match_dup 2)))]
8959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8960 && ix86_binary_operator_ok (AND, DImode, operands)"
8962 and{l}\t{%k2, %k0|%k0, %k2}
8963 and{q}\t{%2, %0|%0, %2}
8964 and{q}\t{%2, %0|%0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "SI,DI,DI")])
8968 (define_expand "andsi3"
8969 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8970 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8971 (match_operand:SI 2 "general_operand" "")))]
8973 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8975 (define_insn "*andsi_1"
8976 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8977 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8978 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "ix86_binary_operator_ok (AND, SImode, operands)"
8982 switch (get_attr_type (insn))
8986 enum machine_mode mode;
8988 gcc_assert (CONST_INT_P (operands[2]));
8989 if (INTVAL (operands[2]) == 0xff)
8993 gcc_assert (INTVAL (operands[2]) == 0xffff);
8997 operands[1] = gen_lowpart (mode, operands[1]);
8999 return "movz{bl|x}\t{%1, %0|%0, %1}";
9001 return "movz{wl|x}\t{%1, %0|%0, %1}";
9005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9006 return "and{l}\t{%2, %0|%0, %2}";
9009 [(set_attr "type" "alu,alu,imovx")
9010 (set (attr "prefix_rex")
9012 (and (eq_attr "type" "imovx")
9013 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9014 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9016 (const_string "*")))
9017 (set_attr "length_immediate" "*,*,0")
9018 (set_attr "mode" "SI")])
9021 [(set (match_operand 0 "register_operand" "")
9023 (const_int -65536)))
9024 (clobber (reg:CC FLAGS_REG))]
9025 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9026 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9027 "operands[1] = gen_lowpart (HImode, operands[0]);")
9030 [(set (match_operand 0 "ext_register_operand" "")
9033 (clobber (reg:CC FLAGS_REG))]
9034 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9035 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9036 "operands[1] = gen_lowpart (QImode, operands[0]);")
9039 [(set (match_operand 0 "ext_register_operand" "")
9041 (const_int -65281)))
9042 (clobber (reg:CC FLAGS_REG))]
9043 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9044 [(parallel [(set (zero_extract:SI (match_dup 0)
9048 (zero_extract:SI (match_dup 0)
9051 (zero_extract:SI (match_dup 0)
9054 (clobber (reg:CC FLAGS_REG))])]
9055 "operands[0] = gen_lowpart (SImode, operands[0]);")
9057 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9058 (define_insn "*andsi_1_zext"
9059 [(set (match_operand:DI 0 "register_operand" "=r")
9061 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9062 (match_operand:SI 2 "general_operand" "g"))))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9065 "and{l}\t{%2, %k0|%k0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9069 (define_insn "*andsi_2"
9070 [(set (reg FLAGS_REG)
9071 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9072 (match_operand:SI 2 "general_operand" "g,ri"))
9074 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9075 (and:SI (match_dup 1) (match_dup 2)))]
9076 "ix86_match_ccmode (insn, CCNOmode)
9077 && ix86_binary_operator_ok (AND, SImode, operands)"
9078 "and{l}\t{%2, %0|%0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "SI")])
9082 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9083 (define_insn "*andsi_2_zext"
9084 [(set (reg FLAGS_REG)
9085 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9086 (match_operand:SI 2 "general_operand" "g"))
9088 (set (match_operand:DI 0 "register_operand" "=r")
9089 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9090 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_binary_operator_ok (AND, SImode, operands)"
9092 "and{l}\t{%2, %k0|%k0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "mode" "SI")])
9096 (define_expand "andhi3"
9097 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9098 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9099 (match_operand:HI 2 "general_operand" "")))]
9100 "TARGET_HIMODE_MATH"
9101 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9103 (define_insn "*andhi_1"
9104 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9105 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9106 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "ix86_binary_operator_ok (AND, HImode, operands)"
9110 switch (get_attr_type (insn))
9113 gcc_assert (CONST_INT_P (operands[2]));
9114 gcc_assert (INTVAL (operands[2]) == 0xff);
9115 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9118 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9120 return "and{w}\t{%2, %0|%0, %2}";
9123 [(set_attr "type" "alu,alu,imovx")
9124 (set_attr "length_immediate" "*,*,0")
9125 (set (attr "prefix_rex")
9127 (and (eq_attr "type" "imovx")
9128 (match_operand 1 "ext_QIreg_nomode_operand" ""))
9130 (const_string "*")))
9131 (set_attr "mode" "HI,HI,SI")])
9133 (define_insn "*andhi_2"
9134 [(set (reg FLAGS_REG)
9135 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136 (match_operand:HI 2 "general_operand" "rmn,rn"))
9138 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9139 (and:HI (match_dup 1) (match_dup 2)))]
9140 "ix86_match_ccmode (insn, CCNOmode)
9141 && ix86_binary_operator_ok (AND, HImode, operands)"
9142 "and{w}\t{%2, %0|%0, %2}"
9143 [(set_attr "type" "alu")
9144 (set_attr "mode" "HI")])
9146 (define_expand "andqi3"
9147 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9148 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9149 (match_operand:QI 2 "general_operand" "")))]
9150 "TARGET_QIMODE_MATH"
9151 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9153 ;; %%% Potential partial reg stall on alternative 2. What to do?
9154 (define_insn "*andqi_1"
9155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9156 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9157 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9158 (clobber (reg:CC FLAGS_REG))]
9159 "ix86_binary_operator_ok (AND, QImode, operands)"
9161 and{b}\t{%2, %0|%0, %2}
9162 and{b}\t{%2, %0|%0, %2}
9163 and{l}\t{%k2, %k0|%k0, %k2}"
9164 [(set_attr "type" "alu")
9165 (set_attr "mode" "QI,QI,SI")])
9167 (define_insn "*andqi_1_slp"
9168 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9169 (and:QI (match_dup 0)
9170 (match_operand:QI 1 "general_operand" "qn,qmn")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9174 "and{b}\t{%1, %0|%0, %1}"
9175 [(set_attr "type" "alu1")
9176 (set_attr "mode" "QI")])
9178 (define_insn "*andqi_2_maybe_si"
9179 [(set (reg FLAGS_REG)
9181 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9182 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9184 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9185 (and:QI (match_dup 1) (match_dup 2)))]
9186 "ix86_binary_operator_ok (AND, QImode, operands)
9187 && ix86_match_ccmode (insn,
9188 CONST_INT_P (operands[2])
9189 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9191 if (which_alternative == 2)
9193 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9194 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9195 return "and{l}\t{%2, %k0|%k0, %2}";
9197 return "and{b}\t{%2, %0|%0, %2}";
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "QI,QI,SI")])
9202 (define_insn "*andqi_2"
9203 [(set (reg FLAGS_REG)
9205 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9206 (match_operand:QI 2 "general_operand" "qmn,qn"))
9208 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9209 (and:QI (match_dup 1) (match_dup 2)))]
9210 "ix86_match_ccmode (insn, CCNOmode)
9211 && ix86_binary_operator_ok (AND, QImode, operands)"
9212 "and{b}\t{%2, %0|%0, %2}"
9213 [(set_attr "type" "alu")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*andqi_2_slp"
9217 [(set (reg FLAGS_REG)
9219 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9220 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9222 (set (strict_low_part (match_dup 0))
9223 (and:QI (match_dup 0) (match_dup 1)))]
9224 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9225 && ix86_match_ccmode (insn, CCNOmode)
9226 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9227 "and{b}\t{%1, %0|%0, %1}"
9228 [(set_attr "type" "alu1")
9229 (set_attr "mode" "QI")])
9231 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9232 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9233 ;; for a QImode operand, which of course failed.
9235 (define_insn "andqi_ext_0"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9241 (match_operand 1 "ext_register_operand" "0")
9244 (match_operand 2 "const_int_operand" "n")))
9245 (clobber (reg:CC FLAGS_REG))]
9247 "and{b}\t{%2, %h0|%h0, %2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "length_immediate" "1")
9250 (set_attr "modrm" "1")
9251 (set_attr "mode" "QI")])
9253 ;; Generated by peephole translating test to and. This shows up
9254 ;; often in fp comparisons.
9256 (define_insn "*andqi_ext_0_cc"
9257 [(set (reg FLAGS_REG)
9261 (match_operand 1 "ext_register_operand" "0")
9264 (match_operand 2 "const_int_operand" "n"))
9266 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9275 "ix86_match_ccmode (insn, CCNOmode)"
9276 "and{b}\t{%2, %h0|%h0, %2}"
9277 [(set_attr "type" "alu")
9278 (set_attr "length_immediate" "1")
9279 (set_attr "modrm" "1")
9280 (set_attr "mode" "QI")])
9282 (define_insn "*andqi_ext_1"
9283 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288 (match_operand 1 "ext_register_operand" "0")
9292 (match_operand:QI 2 "general_operand" "Qm"))))
9293 (clobber (reg:CC FLAGS_REG))]
9295 "and{b}\t{%2, %h0|%h0, %2}"
9296 [(set_attr "type" "alu")
9297 (set_attr "length_immediate" "0")
9298 (set_attr "mode" "QI")])
9300 (define_insn "*andqi_ext_1_rex64"
9301 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9306 (match_operand 1 "ext_register_operand" "0")
9310 (match_operand 2 "ext_register_operand" "Q"))))
9311 (clobber (reg:CC FLAGS_REG))]
9313 "and{b}\t{%2, %h0|%h0, %2}"
9314 [(set_attr "type" "alu")
9315 (set_attr "length_immediate" "0")
9316 (set_attr "mode" "QI")])
9318 (define_insn "*andqi_ext_2"
9319 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9324 (match_operand 1 "ext_register_operand" "%0")
9328 (match_operand 2 "ext_register_operand" "Q")
9331 (clobber (reg:CC FLAGS_REG))]
9333 "and{b}\t{%h2, %h0|%h0, %h2}"
9334 [(set_attr "type" "alu")
9335 (set_attr "length_immediate" "0")
9336 (set_attr "mode" "QI")])
9338 ;; Convert wide AND instructions with immediate operand to shorter QImode
9339 ;; equivalents when possible.
9340 ;; Don't do the splitting with memory operands, since it introduces risk
9341 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9342 ;; for size, but that can (should?) be handled by generic code instead.
9344 [(set (match_operand 0 "register_operand" "")
9345 (and (match_operand 1 "register_operand" "")
9346 (match_operand 2 "const_int_operand" "")))
9347 (clobber (reg:CC FLAGS_REG))]
9349 && QI_REG_P (operands[0])
9350 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9351 && !(~INTVAL (operands[2]) & ~(255 << 8))
9352 && GET_MODE (operands[0]) != QImode"
9353 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9354 (and:SI (zero_extract:SI (match_dup 1)
9355 (const_int 8) (const_int 8))
9357 (clobber (reg:CC FLAGS_REG))])]
9358 "operands[0] = gen_lowpart (SImode, operands[0]);
9359 operands[1] = gen_lowpart (SImode, operands[1]);
9360 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9362 ;; Since AND can be encoded with sign extended immediate, this is only
9363 ;; profitable when 7th bit is not set.
9365 [(set (match_operand 0 "register_operand" "")
9366 (and (match_operand 1 "general_operand" "")
9367 (match_operand 2 "const_int_operand" "")))
9368 (clobber (reg:CC FLAGS_REG))]
9370 && ANY_QI_REG_P (operands[0])
9371 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9372 && !(~INTVAL (operands[2]) & ~255)
9373 && !(INTVAL (operands[2]) & 128)
9374 && GET_MODE (operands[0]) != QImode"
9375 [(parallel [(set (strict_low_part (match_dup 0))
9376 (and:QI (match_dup 1)
9378 (clobber (reg:CC FLAGS_REG))])]
9379 "operands[0] = gen_lowpart (QImode, operands[0]);
9380 operands[1] = gen_lowpart (QImode, operands[1]);
9381 operands[2] = gen_lowpart (QImode, operands[2]);")
9383 ;; Logical inclusive OR instructions
9385 ;; %%% This used to optimize known byte-wide and operations to memory.
9386 ;; If this is considered useful, it should be done with splitters.
9388 (define_expand "iordi3"
9389 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9391 (match_operand:DI 2 "x86_64_general_operand" "")))]
9393 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9395 (define_insn "*iordi_1_rex64"
9396 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9397 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9398 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9399 (clobber (reg:CC FLAGS_REG))]
9401 && ix86_binary_operator_ok (IOR, DImode, operands)"
9402 "or{q}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "DI")])
9406 (define_insn "*iordi_2_rex64"
9407 [(set (reg FLAGS_REG)
9408 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9409 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9411 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9412 (ior:DI (match_dup 1) (match_dup 2)))]
9414 && ix86_match_ccmode (insn, CCNOmode)
9415 && ix86_binary_operator_ok (IOR, DImode, operands)"
9416 "or{q}\t{%2, %0|%0, %2}"
9417 [(set_attr "type" "alu")
9418 (set_attr "mode" "DI")])
9420 (define_insn "*iordi_3_rex64"
9421 [(set (reg FLAGS_REG)
9422 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9423 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9425 (clobber (match_scratch:DI 0 "=r"))]
9427 && ix86_match_ccmode (insn, CCNOmode)
9428 && ix86_binary_operator_ok (IOR, DImode, operands)"
9429 "or{q}\t{%2, %0|%0, %2}"
9430 [(set_attr "type" "alu")
9431 (set_attr "mode" "DI")])
9434 (define_expand "iorsi3"
9435 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9437 (match_operand:SI 2 "general_operand" "")))]
9439 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9441 (define_insn "*iorsi_1"
9442 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9443 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9444 (match_operand:SI 2 "general_operand" "ri,g")))
9445 (clobber (reg:CC FLAGS_REG))]
9446 "ix86_binary_operator_ok (IOR, SImode, operands)"
9447 "or{l}\t{%2, %0|%0, %2}"
9448 [(set_attr "type" "alu")
9449 (set_attr "mode" "SI")])
9451 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9452 (define_insn "*iorsi_1_zext"
9453 [(set (match_operand:DI 0 "register_operand" "=r")
9455 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9456 (match_operand:SI 2 "general_operand" "g"))))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9459 "or{l}\t{%2, %k0|%k0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "mode" "SI")])
9463 (define_insn "*iorsi_1_zext_imm"
9464 [(set (match_operand:DI 0 "register_operand" "=r")
9465 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9466 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9467 (clobber (reg:CC FLAGS_REG))]
9469 "or{l}\t{%2, %k0|%k0, %2}"
9470 [(set_attr "type" "alu")
9471 (set_attr "mode" "SI")])
9473 (define_insn "*iorsi_2"
9474 [(set (reg FLAGS_REG)
9475 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9476 (match_operand:SI 2 "general_operand" "g,ri"))
9478 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9479 (ior:SI (match_dup 1) (match_dup 2)))]
9480 "ix86_match_ccmode (insn, CCNOmode)
9481 && ix86_binary_operator_ok (IOR, SImode, operands)"
9482 "or{l}\t{%2, %0|%0, %2}"
9483 [(set_attr "type" "alu")
9484 (set_attr "mode" "SI")])
9486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9487 ;; ??? Special case for immediate operand is missing - it is tricky.
9488 (define_insn "*iorsi_2_zext"
9489 [(set (reg FLAGS_REG)
9490 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9491 (match_operand:SI 2 "general_operand" "g"))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9495 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9496 && ix86_binary_operator_ok (IOR, SImode, operands)"
9497 "or{l}\t{%2, %k0|%k0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "mode" "SI")])
9501 (define_insn "*iorsi_2_zext_imm"
9502 [(set (reg FLAGS_REG)
9503 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9504 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9506 (set (match_operand:DI 0 "register_operand" "=r")
9507 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9508 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9509 && ix86_binary_operator_ok (IOR, SImode, operands)"
9510 "or{l}\t{%2, %k0|%k0, %2}"
9511 [(set_attr "type" "alu")
9512 (set_attr "mode" "SI")])
9514 (define_insn "*iorsi_3"
9515 [(set (reg FLAGS_REG)
9516 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9517 (match_operand:SI 2 "general_operand" "g"))
9519 (clobber (match_scratch:SI 0 "=r"))]
9520 "ix86_match_ccmode (insn, CCNOmode)
9521 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9522 "or{l}\t{%2, %0|%0, %2}"
9523 [(set_attr "type" "alu")
9524 (set_attr "mode" "SI")])
9526 (define_expand "iorhi3"
9527 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9528 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9529 (match_operand:HI 2 "general_operand" "")))]
9530 "TARGET_HIMODE_MATH"
9531 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9533 (define_insn "*iorhi_1"
9534 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9535 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9536 (match_operand:HI 2 "general_operand" "rmn,rn")))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "ix86_binary_operator_ok (IOR, HImode, operands)"
9539 "or{w}\t{%2, %0|%0, %2}"
9540 [(set_attr "type" "alu")
9541 (set_attr "mode" "HI")])
9543 (define_insn "*iorhi_2"
9544 [(set (reg FLAGS_REG)
9545 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9546 (match_operand:HI 2 "general_operand" "rmn,rn"))
9548 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9549 (ior:HI (match_dup 1) (match_dup 2)))]
9550 "ix86_match_ccmode (insn, CCNOmode)
9551 && ix86_binary_operator_ok (IOR, HImode, operands)"
9552 "or{w}\t{%2, %0|%0, %2}"
9553 [(set_attr "type" "alu")
9554 (set_attr "mode" "HI")])
9556 (define_insn "*iorhi_3"
9557 [(set (reg FLAGS_REG)
9558 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9559 (match_operand:HI 2 "general_operand" "rmn"))
9561 (clobber (match_scratch:HI 0 "=r"))]
9562 "ix86_match_ccmode (insn, CCNOmode)
9563 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9564 "or{w}\t{%2, %0|%0, %2}"
9565 [(set_attr "type" "alu")
9566 (set_attr "mode" "HI")])
9568 (define_expand "iorqi3"
9569 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9570 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9571 (match_operand:QI 2 "general_operand" "")))]
9572 "TARGET_QIMODE_MATH"
9573 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9575 ;; %%% Potential partial reg stall on alternative 2. What to do?
9576 (define_insn "*iorqi_1"
9577 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9578 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9579 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9580 (clobber (reg:CC FLAGS_REG))]
9581 "ix86_binary_operator_ok (IOR, QImode, operands)"
9583 or{b}\t{%2, %0|%0, %2}
9584 or{b}\t{%2, %0|%0, %2}
9585 or{l}\t{%k2, %k0|%k0, %k2}"
9586 [(set_attr "type" "alu")
9587 (set_attr "mode" "QI,QI,SI")])
9589 (define_insn "*iorqi_1_slp"
9590 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9591 (ior:QI (match_dup 0)
9592 (match_operand:QI 1 "general_operand" "qmn,qn")))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9596 "or{b}\t{%1, %0|%0, %1}"
9597 [(set_attr "type" "alu1")
9598 (set_attr "mode" "QI")])
9600 (define_insn "*iorqi_2"
9601 [(set (reg FLAGS_REG)
9602 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9603 (match_operand:QI 2 "general_operand" "qmn,qn"))
9605 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9606 (ior:QI (match_dup 1) (match_dup 2)))]
9607 "ix86_match_ccmode (insn, CCNOmode)
9608 && ix86_binary_operator_ok (IOR, QImode, operands)"
9609 "or{b}\t{%2, %0|%0, %2}"
9610 [(set_attr "type" "alu")
9611 (set_attr "mode" "QI")])
9613 (define_insn "*iorqi_2_slp"
9614 [(set (reg FLAGS_REG)
9615 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9616 (match_operand:QI 1 "general_operand" "qmn,qn"))
9618 (set (strict_low_part (match_dup 0))
9619 (ior:QI (match_dup 0) (match_dup 1)))]
9620 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9621 && ix86_match_ccmode (insn, CCNOmode)
9622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9623 "or{b}\t{%1, %0|%0, %1}"
9624 [(set_attr "type" "alu1")
9625 (set_attr "mode" "QI")])
9627 (define_insn "*iorqi_3"
9628 [(set (reg FLAGS_REG)
9629 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9630 (match_operand:QI 2 "general_operand" "qmn"))
9632 (clobber (match_scratch:QI 0 "=q"))]
9633 "ix86_match_ccmode (insn, CCNOmode)
9634 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9635 "or{b}\t{%2, %0|%0, %2}"
9636 [(set_attr "type" "alu")
9637 (set_attr "mode" "QI")])
9639 (define_insn "*iorqi_ext_0"
9640 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9645 (match_operand 1 "ext_register_operand" "0")
9648 (match_operand 2 "const_int_operand" "n")))
9649 (clobber (reg:CC FLAGS_REG))]
9650 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9651 "or{b}\t{%2, %h0|%h0, %2}"
9652 [(set_attr "type" "alu")
9653 (set_attr "length_immediate" "1")
9654 (set_attr "modrm" "1")
9655 (set_attr "mode" "QI")])
9657 (define_insn "*iorqi_ext_1"
9658 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9663 (match_operand 1 "ext_register_operand" "0")
9667 (match_operand:QI 2 "general_operand" "Qm"))))
9668 (clobber (reg:CC FLAGS_REG))]
9670 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9671 "or{b}\t{%2, %h0|%h0, %2}"
9672 [(set_attr "type" "alu")
9673 (set_attr "length_immediate" "0")
9674 (set_attr "mode" "QI")])
9676 (define_insn "*iorqi_ext_1_rex64"
9677 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9682 (match_operand 1 "ext_register_operand" "0")
9686 (match_operand 2 "ext_register_operand" "Q"))))
9687 (clobber (reg:CC FLAGS_REG))]
9689 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9690 "or{b}\t{%2, %h0|%h0, %2}"
9691 [(set_attr "type" "alu")
9692 (set_attr "length_immediate" "0")
9693 (set_attr "mode" "QI")])
9695 (define_insn "*iorqi_ext_2"
9696 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9700 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9703 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9706 (clobber (reg:CC FLAGS_REG))]
9707 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9708 "ior{b}\t{%h2, %h0|%h0, %h2}"
9709 [(set_attr "type" "alu")
9710 (set_attr "length_immediate" "0")
9711 (set_attr "mode" "QI")])
9714 [(set (match_operand 0 "register_operand" "")
9715 (ior (match_operand 1 "register_operand" "")
9716 (match_operand 2 "const_int_operand" "")))
9717 (clobber (reg:CC FLAGS_REG))]
9719 && QI_REG_P (operands[0])
9720 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9721 && !(INTVAL (operands[2]) & ~(255 << 8))
9722 && GET_MODE (operands[0]) != QImode"
9723 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9724 (ior:SI (zero_extract:SI (match_dup 1)
9725 (const_int 8) (const_int 8))
9727 (clobber (reg:CC FLAGS_REG))])]
9728 "operands[0] = gen_lowpart (SImode, operands[0]);
9729 operands[1] = gen_lowpart (SImode, operands[1]);
9730 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9732 ;; Since OR can be encoded with sign extended immediate, this is only
9733 ;; profitable when 7th bit is set.
9735 [(set (match_operand 0 "register_operand" "")
9736 (ior (match_operand 1 "general_operand" "")
9737 (match_operand 2 "const_int_operand" "")))
9738 (clobber (reg:CC FLAGS_REG))]
9740 && ANY_QI_REG_P (operands[0])
9741 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9742 && !(INTVAL (operands[2]) & ~255)
9743 && (INTVAL (operands[2]) & 128)
9744 && GET_MODE (operands[0]) != QImode"
9745 [(parallel [(set (strict_low_part (match_dup 0))
9746 (ior:QI (match_dup 1)
9748 (clobber (reg:CC FLAGS_REG))])]
9749 "operands[0] = gen_lowpart (QImode, operands[0]);
9750 operands[1] = gen_lowpart (QImode, operands[1]);
9751 operands[2] = gen_lowpart (QImode, operands[2]);")
9753 ;; Logical XOR instructions
9755 ;; %%% This used to optimize known byte-wide and operations to memory.
9756 ;; If this is considered useful, it should be done with splitters.
9758 (define_expand "xordi3"
9759 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9760 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9761 (match_operand:DI 2 "x86_64_general_operand" "")))]
9763 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9765 (define_insn "*xordi_1_rex64"
9766 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9767 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9768 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9769 (clobber (reg:CC FLAGS_REG))]
9771 && ix86_binary_operator_ok (XOR, DImode, operands)"
9772 "xor{q}\t{%2, %0|%0, %2}"
9773 [(set_attr "type" "alu")
9774 (set_attr "mode" "DI")])
9776 (define_insn "*xordi_2_rex64"
9777 [(set (reg FLAGS_REG)
9778 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9779 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9781 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9782 (xor:DI (match_dup 1) (match_dup 2)))]
9784 && ix86_match_ccmode (insn, CCNOmode)
9785 && ix86_binary_operator_ok (XOR, DImode, operands)"
9786 "xor{q}\t{%2, %0|%0, %2}"
9787 [(set_attr "type" "alu")
9788 (set_attr "mode" "DI")])
9790 (define_insn "*xordi_3_rex64"
9791 [(set (reg FLAGS_REG)
9792 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9793 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9795 (clobber (match_scratch:DI 0 "=r"))]
9797 && ix86_match_ccmode (insn, CCNOmode)
9798 && ix86_binary_operator_ok (XOR, DImode, operands)"
9799 "xor{q}\t{%2, %0|%0, %2}"
9800 [(set_attr "type" "alu")
9801 (set_attr "mode" "DI")])
9803 (define_expand "xorsi3"
9804 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9805 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9806 (match_operand:SI 2 "general_operand" "")))]
9808 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9810 (define_insn "*xorsi_1"
9811 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9812 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9813 (match_operand:SI 2 "general_operand" "ri,rm")))
9814 (clobber (reg:CC FLAGS_REG))]
9815 "ix86_binary_operator_ok (XOR, SImode, operands)"
9816 "xor{l}\t{%2, %0|%0, %2}"
9817 [(set_attr "type" "alu")
9818 (set_attr "mode" "SI")])
9820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9821 ;; Add speccase for immediates
9822 (define_insn "*xorsi_1_zext"
9823 [(set (match_operand:DI 0 "register_operand" "=r")
9825 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9826 (match_operand:SI 2 "general_operand" "g"))))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9829 "xor{l}\t{%2, %k0|%k0, %2}"
9830 [(set_attr "type" "alu")
9831 (set_attr "mode" "SI")])
9833 (define_insn "*xorsi_1_zext_imm"
9834 [(set (match_operand:DI 0 "register_operand" "=r")
9835 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9836 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9839 "xor{l}\t{%2, %k0|%k0, %2}"
9840 [(set_attr "type" "alu")
9841 (set_attr "mode" "SI")])
9843 (define_insn "*xorsi_2"
9844 [(set (reg FLAGS_REG)
9845 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9846 (match_operand:SI 2 "general_operand" "g,ri"))
9848 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9849 (xor:SI (match_dup 1) (match_dup 2)))]
9850 "ix86_match_ccmode (insn, CCNOmode)
9851 && ix86_binary_operator_ok (XOR, SImode, operands)"
9852 "xor{l}\t{%2, %0|%0, %2}"
9853 [(set_attr "type" "alu")
9854 (set_attr "mode" "SI")])
9856 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9857 ;; ??? Special case for immediate operand is missing - it is tricky.
9858 (define_insn "*xorsi_2_zext"
9859 [(set (reg FLAGS_REG)
9860 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9861 (match_operand:SI 2 "general_operand" "g"))
9863 (set (match_operand:DI 0 "register_operand" "=r")
9864 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9865 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9866 && ix86_binary_operator_ok (XOR, SImode, operands)"
9867 "xor{l}\t{%2, %k0|%k0, %2}"
9868 [(set_attr "type" "alu")
9869 (set_attr "mode" "SI")])
9871 (define_insn "*xorsi_2_zext_imm"
9872 [(set (reg FLAGS_REG)
9873 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9874 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9876 (set (match_operand:DI 0 "register_operand" "=r")
9877 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9878 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9879 && ix86_binary_operator_ok (XOR, SImode, operands)"
9880 "xor{l}\t{%2, %k0|%k0, %2}"
9881 [(set_attr "type" "alu")
9882 (set_attr "mode" "SI")])
9884 (define_insn "*xorsi_3"
9885 [(set (reg FLAGS_REG)
9886 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9887 (match_operand:SI 2 "general_operand" "g"))
9889 (clobber (match_scratch:SI 0 "=r"))]
9890 "ix86_match_ccmode (insn, CCNOmode)
9891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9892 "xor{l}\t{%2, %0|%0, %2}"
9893 [(set_attr "type" "alu")
9894 (set_attr "mode" "SI")])
9896 (define_expand "xorhi3"
9897 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9898 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9899 (match_operand:HI 2 "general_operand" "")))]
9900 "TARGET_HIMODE_MATH"
9901 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9903 (define_insn "*xorhi_1"
9904 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9905 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9906 (match_operand:HI 2 "general_operand" "rmn,rn")))
9907 (clobber (reg:CC FLAGS_REG))]
9908 "ix86_binary_operator_ok (XOR, HImode, operands)"
9909 "xor{w}\t{%2, %0|%0, %2}"
9910 [(set_attr "type" "alu")
9911 (set_attr "mode" "HI")])
9913 (define_insn "*xorhi_2"
9914 [(set (reg FLAGS_REG)
9915 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9916 (match_operand:HI 2 "general_operand" "rmn,rn"))
9918 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9919 (xor:HI (match_dup 1) (match_dup 2)))]
9920 "ix86_match_ccmode (insn, CCNOmode)
9921 && ix86_binary_operator_ok (XOR, HImode, operands)"
9922 "xor{w}\t{%2, %0|%0, %2}"
9923 [(set_attr "type" "alu")
9924 (set_attr "mode" "HI")])
9926 (define_insn "*xorhi_3"
9927 [(set (reg FLAGS_REG)
9928 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9929 (match_operand:HI 2 "general_operand" "rmn"))
9931 (clobber (match_scratch:HI 0 "=r"))]
9932 "ix86_match_ccmode (insn, CCNOmode)
9933 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9934 "xor{w}\t{%2, %0|%0, %2}"
9935 [(set_attr "type" "alu")
9936 (set_attr "mode" "HI")])
9938 (define_expand "xorqi3"
9939 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9940 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9941 (match_operand:QI 2 "general_operand" "")))]
9942 "TARGET_QIMODE_MATH"
9943 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9945 ;; %%% Potential partial reg stall on alternative 2. What to do?
9946 (define_insn "*xorqi_1"
9947 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9948 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9949 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9950 (clobber (reg:CC FLAGS_REG))]
9951 "ix86_binary_operator_ok (XOR, QImode, operands)"
9953 xor{b}\t{%2, %0|%0, %2}
9954 xor{b}\t{%2, %0|%0, %2}
9955 xor{l}\t{%k2, %k0|%k0, %k2}"
9956 [(set_attr "type" "alu")
9957 (set_attr "mode" "QI,QI,SI")])
9959 (define_insn "*xorqi_1_slp"
9960 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9961 (xor:QI (match_dup 0)
9962 (match_operand:QI 1 "general_operand" "qn,qmn")))
9963 (clobber (reg:CC FLAGS_REG))]
9964 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9965 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9966 "xor{b}\t{%1, %0|%0, %1}"
9967 [(set_attr "type" "alu1")
9968 (set_attr "mode" "QI")])
9970 (define_insn "*xorqi_ext_0"
9971 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9976 (match_operand 1 "ext_register_operand" "0")
9979 (match_operand 2 "const_int_operand" "n")))
9980 (clobber (reg:CC FLAGS_REG))]
9981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9982 "xor{b}\t{%2, %h0|%h0, %2}"
9983 [(set_attr "type" "alu")
9984 (set_attr "length_immediate" "1")
9985 (set_attr "modrm" "1")
9986 (set_attr "mode" "QI")])
9988 (define_insn "*xorqi_ext_1"
9989 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9994 (match_operand 1 "ext_register_operand" "0")
9998 (match_operand:QI 2 "general_operand" "Qm"))))
9999 (clobber (reg:CC FLAGS_REG))]
10001 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10002 "xor{b}\t{%2, %h0|%h0, %2}"
10003 [(set_attr "type" "alu")
10004 (set_attr "length_immediate" "0")
10005 (set_attr "mode" "QI")])
10007 (define_insn "*xorqi_ext_1_rex64"
10008 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10013 (match_operand 1 "ext_register_operand" "0")
10017 (match_operand 2 "ext_register_operand" "Q"))))
10018 (clobber (reg:CC FLAGS_REG))]
10020 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10021 "xor{b}\t{%2, %h0|%h0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "length_immediate" "0")
10024 (set_attr "mode" "QI")])
10026 (define_insn "*xorqi_ext_2"
10027 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10031 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10034 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10037 (clobber (reg:CC FLAGS_REG))]
10038 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10039 "xor{b}\t{%h2, %h0|%h0, %h2}"
10040 [(set_attr "type" "alu")
10041 (set_attr "length_immediate" "0")
10042 (set_attr "mode" "QI")])
10044 (define_insn "*xorqi_cc_1"
10045 [(set (reg FLAGS_REG)
10047 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10048 (match_operand:QI 2 "general_operand" "qmn,qn"))
10050 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10051 (xor:QI (match_dup 1) (match_dup 2)))]
10052 "ix86_match_ccmode (insn, CCNOmode)
10053 && ix86_binary_operator_ok (XOR, QImode, operands)"
10054 "xor{b}\t{%2, %0|%0, %2}"
10055 [(set_attr "type" "alu")
10056 (set_attr "mode" "QI")])
10058 (define_insn "*xorqi_2_slp"
10059 [(set (reg FLAGS_REG)
10060 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10061 (match_operand:QI 1 "general_operand" "qmn,qn"))
10063 (set (strict_low_part (match_dup 0))
10064 (xor:QI (match_dup 0) (match_dup 1)))]
10065 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10066 && ix86_match_ccmode (insn, CCNOmode)
10067 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10068 "xor{b}\t{%1, %0|%0, %1}"
10069 [(set_attr "type" "alu1")
10070 (set_attr "mode" "QI")])
10072 (define_insn "*xorqi_cc_2"
10073 [(set (reg FLAGS_REG)
10075 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10076 (match_operand:QI 2 "general_operand" "qmn"))
10078 (clobber (match_scratch:QI 0 "=q"))]
10079 "ix86_match_ccmode (insn, CCNOmode)
10080 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10081 "xor{b}\t{%2, %0|%0, %2}"
10082 [(set_attr "type" "alu")
10083 (set_attr "mode" "QI")])
10085 (define_insn "*xorqi_cc_ext_1"
10086 [(set (reg FLAGS_REG)
10090 (match_operand 1 "ext_register_operand" "0")
10093 (match_operand:QI 2 "general_operand" "qmn"))
10095 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10099 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10101 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10102 "xor{b}\t{%2, %h0|%h0, %2}"
10103 [(set_attr "type" "alu")
10104 (set_attr "modrm" "1")
10105 (set_attr "mode" "QI")])
10107 (define_insn "*xorqi_cc_ext_1_rex64"
10108 [(set (reg FLAGS_REG)
10112 (match_operand 1 "ext_register_operand" "0")
10115 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10117 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10121 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10123 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10124 "xor{b}\t{%2, %h0|%h0, %2}"
10125 [(set_attr "type" "alu")
10126 (set_attr "modrm" "1")
10127 (set_attr "mode" "QI")])
10129 (define_expand "xorqi_cc_ext_1"
10131 (set (reg:CCNO FLAGS_REG)
10135 (match_operand 1 "ext_register_operand" "")
10138 (match_operand:QI 2 "general_operand" ""))
10140 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10144 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10150 [(set (match_operand 0 "register_operand" "")
10151 (xor (match_operand 1 "register_operand" "")
10152 (match_operand 2 "const_int_operand" "")))
10153 (clobber (reg:CC FLAGS_REG))]
10155 && QI_REG_P (operands[0])
10156 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10157 && !(INTVAL (operands[2]) & ~(255 << 8))
10158 && GET_MODE (operands[0]) != QImode"
10159 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10160 (xor:SI (zero_extract:SI (match_dup 1)
10161 (const_int 8) (const_int 8))
10163 (clobber (reg:CC FLAGS_REG))])]
10164 "operands[0] = gen_lowpart (SImode, operands[0]);
10165 operands[1] = gen_lowpart (SImode, operands[1]);
10166 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10168 ;; Since XOR can be encoded with sign extended immediate, this is only
10169 ;; profitable when 7th bit is set.
10171 [(set (match_operand 0 "register_operand" "")
10172 (xor (match_operand 1 "general_operand" "")
10173 (match_operand 2 "const_int_operand" "")))
10174 (clobber (reg:CC FLAGS_REG))]
10176 && ANY_QI_REG_P (operands[0])
10177 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10178 && !(INTVAL (operands[2]) & ~255)
10179 && (INTVAL (operands[2]) & 128)
10180 && GET_MODE (operands[0]) != QImode"
10181 [(parallel [(set (strict_low_part (match_dup 0))
10182 (xor:QI (match_dup 1)
10184 (clobber (reg:CC FLAGS_REG))])]
10185 "operands[0] = gen_lowpart (QImode, operands[0]);
10186 operands[1] = gen_lowpart (QImode, operands[1]);
10187 operands[2] = gen_lowpart (QImode, operands[2]);")
10189 ;; Negation instructions
10191 (define_expand "negti2"
10192 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10193 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10195 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10197 (define_insn "*negti2_1"
10198 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10199 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10200 (clobber (reg:CC FLAGS_REG))]
10202 && ix86_unary_operator_ok (NEG, TImode, operands)"
10206 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10207 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10208 (clobber (reg:CC FLAGS_REG))]
10209 "TARGET_64BIT && reload_completed"
10211 [(set (reg:CCZ FLAGS_REG)
10212 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10213 (set (match_dup 0) (neg:DI (match_dup 1)))])
10215 [(set (match_dup 2)
10216 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10219 (clobber (reg:CC FLAGS_REG))])
10221 [(set (match_dup 2)
10222 (neg:DI (match_dup 2)))
10223 (clobber (reg:CC FLAGS_REG))])]
10224 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10226 (define_expand "negdi2"
10227 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10228 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10230 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10232 (define_insn "*negdi2_1"
10233 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10234 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10235 (clobber (reg:CC FLAGS_REG))]
10237 && ix86_unary_operator_ok (NEG, DImode, operands)"
10241 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10242 (neg:DI (match_operand:DI 1 "general_operand" "")))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "!TARGET_64BIT && reload_completed"
10246 [(set (reg:CCZ FLAGS_REG)
10247 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10248 (set (match_dup 0) (neg:SI (match_dup 1)))])
10250 [(set (match_dup 2)
10251 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10254 (clobber (reg:CC FLAGS_REG))])
10256 [(set (match_dup 2)
10257 (neg:SI (match_dup 2)))
10258 (clobber (reg:CC FLAGS_REG))])]
10259 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10261 (define_insn "*negdi2_1_rex64"
10262 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10263 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10267 [(set_attr "type" "negnot")
10268 (set_attr "mode" "DI")])
10270 ;; The problem with neg is that it does not perform (compare x 0),
10271 ;; it really performs (compare 0 x), which leaves us with the zero
10272 ;; flag being the only useful item.
10274 (define_insn "*negdi2_cmpz_rex64"
10275 [(set (reg:CCZ FLAGS_REG)
10276 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10278 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10279 (neg:DI (match_dup 1)))]
10280 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10282 [(set_attr "type" "negnot")
10283 (set_attr "mode" "DI")])
10286 (define_expand "negsi2"
10287 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10288 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10290 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10292 (define_insn "*negsi2_1"
10293 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10294 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10295 (clobber (reg:CC FLAGS_REG))]
10296 "ix86_unary_operator_ok (NEG, SImode, operands)"
10298 [(set_attr "type" "negnot")
10299 (set_attr "mode" "SI")])
10301 ;; Combine is quite creative about this pattern.
10302 (define_insn "*negsi2_1_zext"
10303 [(set (match_operand:DI 0 "register_operand" "=r")
10304 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10307 (clobber (reg:CC FLAGS_REG))]
10308 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10310 [(set_attr "type" "negnot")
10311 (set_attr "mode" "SI")])
10313 ;; The problem with neg is that it does not perform (compare x 0),
10314 ;; it really performs (compare 0 x), which leaves us with the zero
10315 ;; flag being the only useful item.
10317 (define_insn "*negsi2_cmpz"
10318 [(set (reg:CCZ FLAGS_REG)
10319 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10321 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10322 (neg:SI (match_dup 1)))]
10323 "ix86_unary_operator_ok (NEG, SImode, operands)"
10325 [(set_attr "type" "negnot")
10326 (set_attr "mode" "SI")])
10328 (define_insn "*negsi2_cmpz_zext"
10329 [(set (reg:CCZ FLAGS_REG)
10330 (compare:CCZ (lshiftrt:DI
10332 (match_operand:DI 1 "register_operand" "0")
10336 (set (match_operand:DI 0 "register_operand" "=r")
10337 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10340 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10342 [(set_attr "type" "negnot")
10343 (set_attr "mode" "SI")])
10345 (define_expand "neghi2"
10346 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10347 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10348 "TARGET_HIMODE_MATH"
10349 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10351 (define_insn "*neghi2_1"
10352 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10353 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "ix86_unary_operator_ok (NEG, HImode, operands)"
10357 [(set_attr "type" "negnot")
10358 (set_attr "mode" "HI")])
10360 (define_insn "*neghi2_cmpz"
10361 [(set (reg:CCZ FLAGS_REG)
10362 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10364 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10365 (neg:HI (match_dup 1)))]
10366 "ix86_unary_operator_ok (NEG, HImode, operands)"
10368 [(set_attr "type" "negnot")
10369 (set_attr "mode" "HI")])
10371 (define_expand "negqi2"
10372 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10373 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10374 "TARGET_QIMODE_MATH"
10375 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10377 (define_insn "*negqi2_1"
10378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10379 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "ix86_unary_operator_ok (NEG, QImode, operands)"
10383 [(set_attr "type" "negnot")
10384 (set_attr "mode" "QI")])
10386 (define_insn "*negqi2_cmpz"
10387 [(set (reg:CCZ FLAGS_REG)
10388 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10390 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10391 (neg:QI (match_dup 1)))]
10392 "ix86_unary_operator_ok (NEG, QImode, operands)"
10394 [(set_attr "type" "negnot")
10395 (set_attr "mode" "QI")])
10397 ;; Changing of sign for FP values is doable using integer unit too.
10399 (define_expand "<code><mode>2"
10400 [(set (match_operand:X87MODEF 0 "register_operand" "")
10401 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10402 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10403 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10405 (define_insn "*absneg<mode>2_mixed"
10406 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10407 (match_operator:MODEF 3 "absneg_operator"
10408 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10409 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10414 (define_insn "*absneg<mode>2_sse"
10415 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10416 (match_operator:MODEF 3 "absneg_operator"
10417 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10418 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10423 (define_insn "*absneg<mode>2_i387"
10424 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10425 (match_operator:X87MODEF 3 "absneg_operator"
10426 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10427 (use (match_operand 2 "" ""))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10432 (define_expand "<code>tf2"
10433 [(set (match_operand:TF 0 "register_operand" "")
10434 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10436 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10438 (define_insn "*absnegtf2_sse"
10439 [(set (match_operand:TF 0 "register_operand" "=x,x")
10440 (match_operator:TF 3 "absneg_operator"
10441 [(match_operand:TF 1 "register_operand" "0,x")]))
10442 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10443 (clobber (reg:CC FLAGS_REG))]
10447 ;; Splitters for fp abs and neg.
10450 [(set (match_operand 0 "fp_register_operand" "")
10451 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10452 (use (match_operand 2 "" ""))
10453 (clobber (reg:CC FLAGS_REG))]
10455 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10458 [(set (match_operand 0 "register_operand" "")
10459 (match_operator 3 "absneg_operator"
10460 [(match_operand 1 "register_operand" "")]))
10461 (use (match_operand 2 "nonimmediate_operand" ""))
10462 (clobber (reg:CC FLAGS_REG))]
10463 "reload_completed && SSE_REG_P (operands[0])"
10464 [(set (match_dup 0) (match_dup 3))]
10466 enum machine_mode mode = GET_MODE (operands[0]);
10467 enum machine_mode vmode = GET_MODE (operands[2]);
10470 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10471 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10472 if (operands_match_p (operands[0], operands[2]))
10475 operands[1] = operands[2];
10478 if (GET_CODE (operands[3]) == ABS)
10479 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10481 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10486 [(set (match_operand:SF 0 "register_operand" "")
10487 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10488 (use (match_operand:V4SF 2 "" ""))
10489 (clobber (reg:CC FLAGS_REG))]
10491 [(parallel [(set (match_dup 0) (match_dup 1))
10492 (clobber (reg:CC FLAGS_REG))])]
10495 operands[0] = gen_lowpart (SImode, operands[0]);
10496 if (GET_CODE (operands[1]) == ABS)
10498 tmp = gen_int_mode (0x7fffffff, SImode);
10499 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10503 tmp = gen_int_mode (0x80000000, SImode);
10504 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10510 [(set (match_operand:DF 0 "register_operand" "")
10511 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10512 (use (match_operand 2 "" ""))
10513 (clobber (reg:CC FLAGS_REG))]
10515 [(parallel [(set (match_dup 0) (match_dup 1))
10516 (clobber (reg:CC FLAGS_REG))])]
10521 tmp = gen_lowpart (DImode, operands[0]);
10522 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10525 if (GET_CODE (operands[1]) == ABS)
10528 tmp = gen_rtx_NOT (DImode, tmp);
10532 operands[0] = gen_highpart (SImode, operands[0]);
10533 if (GET_CODE (operands[1]) == ABS)
10535 tmp = gen_int_mode (0x7fffffff, SImode);
10536 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10540 tmp = gen_int_mode (0x80000000, SImode);
10541 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10548 [(set (match_operand:XF 0 "register_operand" "")
10549 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10550 (use (match_operand 2 "" ""))
10551 (clobber (reg:CC FLAGS_REG))]
10553 [(parallel [(set (match_dup 0) (match_dup 1))
10554 (clobber (reg:CC FLAGS_REG))])]
10557 operands[0] = gen_rtx_REG (SImode,
10558 true_regnum (operands[0])
10559 + (TARGET_64BIT ? 1 : 2));
10560 if (GET_CODE (operands[1]) == ABS)
10562 tmp = GEN_INT (0x7fff);
10563 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10567 tmp = GEN_INT (0x8000);
10568 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10573 ;; Conditionalize these after reload. If they match before reload, we
10574 ;; lose the clobber and ability to use integer instructions.
10576 (define_insn "*<code><mode>2_1"
10577 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10578 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10580 && (reload_completed
10581 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10583 [(set_attr "type" "fsgn")
10584 (set_attr "mode" "<MODE>")])
10586 (define_insn "*<code>extendsfdf2"
10587 [(set (match_operand:DF 0 "register_operand" "=f")
10588 (absneg:DF (float_extend:DF
10589 (match_operand:SF 1 "register_operand" "0"))))]
10590 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10592 [(set_attr "type" "fsgn")
10593 (set_attr "mode" "DF")])
10595 (define_insn "*<code>extendsfxf2"
10596 [(set (match_operand:XF 0 "register_operand" "=f")
10597 (absneg:XF (float_extend:XF
10598 (match_operand:SF 1 "register_operand" "0"))))]
10601 [(set_attr "type" "fsgn")
10602 (set_attr "mode" "XF")])
10604 (define_insn "*<code>extenddfxf2"
10605 [(set (match_operand:XF 0 "register_operand" "=f")
10606 (absneg:XF (float_extend:XF
10607 (match_operand:DF 1 "register_operand" "0"))))]
10610 [(set_attr "type" "fsgn")
10611 (set_attr "mode" "XF")])
10613 ;; Copysign instructions
10615 (define_mode_iterator CSGNMODE [SF DF TF])
10616 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10618 (define_expand "copysign<mode>3"
10619 [(match_operand:CSGNMODE 0 "register_operand" "")
10620 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10621 (match_operand:CSGNMODE 2 "register_operand" "")]
10622 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10623 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10625 ix86_expand_copysign (operands);
10629 (define_insn_and_split "copysign<mode>3_const"
10630 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10632 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10633 (match_operand:CSGNMODE 2 "register_operand" "0")
10634 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10636 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10637 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10639 "&& reload_completed"
10642 ix86_split_copysign_const (operands);
10646 (define_insn "copysign<mode>3_var"
10647 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10649 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10650 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10651 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10652 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10654 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10655 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10656 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10660 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10662 [(match_operand:CSGNMODE 2 "register_operand" "")
10663 (match_operand:CSGNMODE 3 "register_operand" "")
10664 (match_operand:<CSGNVMODE> 4 "" "")
10665 (match_operand:<CSGNVMODE> 5 "" "")]
10667 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10668 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10669 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10670 && reload_completed"
10673 ix86_split_copysign_var (operands);
10677 ;; One complement instructions
10679 (define_expand "one_cmpldi2"
10680 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10681 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10683 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10685 (define_insn "*one_cmpldi2_1_rex64"
10686 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10687 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10688 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10690 [(set_attr "type" "negnot")
10691 (set_attr "mode" "DI")])
10693 (define_insn "*one_cmpldi2_2_rex64"
10694 [(set (reg FLAGS_REG)
10695 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10697 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10698 (not:DI (match_dup 1)))]
10699 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10700 && ix86_unary_operator_ok (NOT, DImode, operands)"
10702 [(set_attr "type" "alu1")
10703 (set_attr "mode" "DI")])
10706 [(set (match_operand 0 "flags_reg_operand" "")
10707 (match_operator 2 "compare_operator"
10708 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10710 (set (match_operand:DI 1 "nonimmediate_operand" "")
10711 (not:DI (match_dup 3)))]
10712 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10713 [(parallel [(set (match_dup 0)
10715 [(xor:DI (match_dup 3) (const_int -1))
10718 (xor:DI (match_dup 3) (const_int -1)))])]
10721 (define_expand "one_cmplsi2"
10722 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10723 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10725 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10727 (define_insn "*one_cmplsi2_1"
10728 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10729 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10730 "ix86_unary_operator_ok (NOT, SImode, operands)"
10732 [(set_attr "type" "negnot")
10733 (set_attr "mode" "SI")])
10735 ;; ??? Currently never generated - xor is used instead.
10736 (define_insn "*one_cmplsi2_1_zext"
10737 [(set (match_operand:DI 0 "register_operand" "=r")
10738 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10739 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10741 [(set_attr "type" "negnot")
10742 (set_attr "mode" "SI")])
10744 (define_insn "*one_cmplsi2_2"
10745 [(set (reg FLAGS_REG)
10746 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10748 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10749 (not:SI (match_dup 1)))]
10750 "ix86_match_ccmode (insn, CCNOmode)
10751 && ix86_unary_operator_ok (NOT, SImode, operands)"
10753 [(set_attr "type" "alu1")
10754 (set_attr "mode" "SI")])
10757 [(set (match_operand 0 "flags_reg_operand" "")
10758 (match_operator 2 "compare_operator"
10759 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10761 (set (match_operand:SI 1 "nonimmediate_operand" "")
10762 (not:SI (match_dup 3)))]
10763 "ix86_match_ccmode (insn, CCNOmode)"
10764 [(parallel [(set (match_dup 0)
10765 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10768 (xor:SI (match_dup 3) (const_int -1)))])]
10771 ;; ??? Currently never generated - xor is used instead.
10772 (define_insn "*one_cmplsi2_2_zext"
10773 [(set (reg FLAGS_REG)
10774 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10776 (set (match_operand:DI 0 "register_operand" "=r")
10777 (zero_extend:DI (not:SI (match_dup 1))))]
10778 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10779 && ix86_unary_operator_ok (NOT, SImode, operands)"
10781 [(set_attr "type" "alu1")
10782 (set_attr "mode" "SI")])
10785 [(set (match_operand 0 "flags_reg_operand" "")
10786 (match_operator 2 "compare_operator"
10787 [(not:SI (match_operand:SI 3 "register_operand" ""))
10789 (set (match_operand:DI 1 "register_operand" "")
10790 (zero_extend:DI (not:SI (match_dup 3))))]
10791 "ix86_match_ccmode (insn, CCNOmode)"
10792 [(parallel [(set (match_dup 0)
10793 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10796 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10799 (define_expand "one_cmplhi2"
10800 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10801 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10802 "TARGET_HIMODE_MATH"
10803 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10805 (define_insn "*one_cmplhi2_1"
10806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10807 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10808 "ix86_unary_operator_ok (NOT, HImode, operands)"
10810 [(set_attr "type" "negnot")
10811 (set_attr "mode" "HI")])
10813 (define_insn "*one_cmplhi2_2"
10814 [(set (reg FLAGS_REG)
10815 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10817 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10818 (not:HI (match_dup 1)))]
10819 "ix86_match_ccmode (insn, CCNOmode)
10820 && ix86_unary_operator_ok (NEG, HImode, operands)"
10822 [(set_attr "type" "alu1")
10823 (set_attr "mode" "HI")])
10826 [(set (match_operand 0 "flags_reg_operand" "")
10827 (match_operator 2 "compare_operator"
10828 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10830 (set (match_operand:HI 1 "nonimmediate_operand" "")
10831 (not:HI (match_dup 3)))]
10832 "ix86_match_ccmode (insn, CCNOmode)"
10833 [(parallel [(set (match_dup 0)
10834 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10837 (xor:HI (match_dup 3) (const_int -1)))])]
10840 ;; %%% Potential partial reg stall on alternative 1. What to do?
10841 (define_expand "one_cmplqi2"
10842 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10843 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10844 "TARGET_QIMODE_MATH"
10845 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10847 (define_insn "*one_cmplqi2_1"
10848 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10849 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10850 "ix86_unary_operator_ok (NOT, QImode, operands)"
10854 [(set_attr "type" "negnot")
10855 (set_attr "mode" "QI,SI")])
10857 (define_insn "*one_cmplqi2_2"
10858 [(set (reg FLAGS_REG)
10859 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10861 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10862 (not:QI (match_dup 1)))]
10863 "ix86_match_ccmode (insn, CCNOmode)
10864 && ix86_unary_operator_ok (NOT, QImode, operands)"
10866 [(set_attr "type" "alu1")
10867 (set_attr "mode" "QI")])
10870 [(set (match_operand 0 "flags_reg_operand" "")
10871 (match_operator 2 "compare_operator"
10872 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10874 (set (match_operand:QI 1 "nonimmediate_operand" "")
10875 (not:QI (match_dup 3)))]
10876 "ix86_match_ccmode (insn, CCNOmode)"
10877 [(parallel [(set (match_dup 0)
10878 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10881 (xor:QI (match_dup 3) (const_int -1)))])]
10884 ;; Arithmetic shift instructions
10886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10889 ;; from the assembler input.
10891 ;; This instruction shifts the target reg/mem as usual, but instead of
10892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10893 ;; is a left shift double, bits are taken from the high order bits of
10894 ;; reg, else if the insn is a shift right double, bits are taken from the
10895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10898 ;; Since sh[lr]d does not change the `reg' operand, that is done
10899 ;; separately, making all shifts emit pairs of shift double and normal
10900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10901 ;; support a 63 bit shift, each shift where the count is in a reg expands
10902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10904 ;; If the shift count is a constant, we need never emit more than one
10905 ;; shift pair, instead using moves and sign extension for counts greater
10908 (define_expand "ashlti3"
10909 [(set (match_operand:TI 0 "register_operand" "")
10910 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10911 (match_operand:QI 2 "nonmemory_operand" "")))]
10913 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10915 ;; This pattern must be defined before *ashlti3_1 to prevent
10916 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10918 (define_insn "*avx_ashlti3"
10919 [(set (match_operand:TI 0 "register_operand" "=x")
10920 (ashift:TI (match_operand:TI 1 "register_operand" "x")
10921 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10924 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10925 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10927 [(set_attr "type" "sseishft")
10928 (set_attr "prefix" "vex")
10929 (set_attr "length_immediate" "1")
10930 (set_attr "mode" "TI")])
10932 (define_insn "sse2_ashlti3"
10933 [(set (match_operand:TI 0 "register_operand" "=x")
10934 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10935 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10938 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10939 return "pslldq\t{%2, %0|%0, %2}";
10941 [(set_attr "type" "sseishft")
10942 (set_attr "prefix_data16" "1")
10943 (set_attr "length_immediate" "1")
10944 (set_attr "mode" "TI")])
10946 (define_insn "*ashlti3_1"
10947 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10948 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10949 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10950 (clobber (reg:CC FLAGS_REG))]
10953 [(set_attr "type" "multi")])
10956 [(match_scratch:DI 3 "r")
10957 (parallel [(set (match_operand:TI 0 "register_operand" "")
10958 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10959 (match_operand:QI 2 "nonmemory_operand" "")))
10960 (clobber (reg:CC FLAGS_REG))])
10964 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10967 [(set (match_operand:TI 0 "register_operand" "")
10968 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10969 (match_operand:QI 2 "nonmemory_operand" "")))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10972 ? epilogue_completed : reload_completed)"
10974 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10976 (define_insn "x86_64_shld"
10977 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10978 (ior:DI (ashift:DI (match_dup 0)
10979 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10981 (minus:QI (const_int 64) (match_dup 2)))))
10982 (clobber (reg:CC FLAGS_REG))]
10984 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10985 [(set_attr "type" "ishift")
10986 (set_attr "prefix_0f" "1")
10987 (set_attr "mode" "DI")
10988 (set_attr "athlon_decode" "vector")
10989 (set_attr "amdfam10_decode" "vector")])
10991 (define_expand "x86_64_shift_adj_1"
10992 [(set (reg:CCZ FLAGS_REG)
10993 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10996 (set (match_operand:DI 0 "register_operand" "")
10997 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10998 (match_operand:DI 1 "register_operand" "")
11001 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11002 (match_operand:DI 3 "register_operand" "r")
11007 (define_expand "x86_64_shift_adj_2"
11008 [(use (match_operand:DI 0 "register_operand" ""))
11009 (use (match_operand:DI 1 "register_operand" ""))
11010 (use (match_operand:QI 2 "register_operand" ""))]
11013 rtx label = gen_label_rtx ();
11016 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11018 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11019 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11020 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11021 gen_rtx_LABEL_REF (VOIDmode, label),
11023 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11024 JUMP_LABEL (tmp) = label;
11026 emit_move_insn (operands[0], operands[1]);
11027 ix86_expand_clear (operands[1]);
11029 emit_label (label);
11030 LABEL_NUSES (label) = 1;
11035 (define_expand "ashldi3"
11036 [(set (match_operand:DI 0 "shiftdi_operand" "")
11037 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11038 (match_operand:QI 2 "nonmemory_operand" "")))]
11040 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11042 (define_insn "*ashldi3_1_rex64"
11043 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11044 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11045 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11046 (clobber (reg:CC FLAGS_REG))]
11047 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11049 switch (get_attr_type (insn))
11052 gcc_assert (operands[2] == const1_rtx);
11053 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11054 return "add{q}\t%0, %0";
11057 gcc_assert (CONST_INT_P (operands[2]));
11058 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11059 operands[1] = gen_rtx_MULT (DImode, operands[1],
11060 GEN_INT (1 << INTVAL (operands[2])));
11061 return "lea{q}\t{%a1, %0|%0, %a1}";
11064 if (REG_P (operands[2]))
11065 return "sal{q}\t{%b2, %0|%0, %b2}";
11066 else if (operands[2] == const1_rtx
11067 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11068 return "sal{q}\t%0";
11070 return "sal{q}\t{%2, %0|%0, %2}";
11073 [(set (attr "type")
11074 (cond [(eq_attr "alternative" "1")
11075 (const_string "lea")
11076 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11078 (match_operand 0 "register_operand" ""))
11079 (match_operand 2 "const1_operand" ""))
11080 (const_string "alu")
11082 (const_string "ishift")))
11083 (set (attr "length_immediate")
11085 (ior (eq_attr "type" "alu")
11086 (and (eq_attr "type" "ishift")
11087 (and (match_operand 2 "const1_operand" "")
11088 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11091 (const_string "*")))
11092 (set_attr "mode" "DI")])
11094 ;; Convert lea to the lea pattern to avoid flags dependency.
11096 [(set (match_operand:DI 0 "register_operand" "")
11097 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11098 (match_operand:QI 2 "immediate_operand" "")))
11099 (clobber (reg:CC FLAGS_REG))]
11100 "TARGET_64BIT && reload_completed
11101 && true_regnum (operands[0]) != true_regnum (operands[1])"
11102 [(set (match_dup 0)
11103 (mult:DI (match_dup 1)
11105 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11107 ;; This pattern can't accept a variable shift count, since shifts by
11108 ;; zero don't affect the flags. We assume that shifts by constant
11109 ;; zero are optimized away.
11110 (define_insn "*ashldi3_cmp_rex64"
11111 [(set (reg FLAGS_REG)
11113 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11114 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11116 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11117 (ashift:DI (match_dup 1) (match_dup 2)))]
11119 && (optimize_function_for_size_p (cfun)
11120 || !TARGET_PARTIAL_FLAG_REG_STALL
11121 || (operands[2] == const1_rtx
11123 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11124 && ix86_match_ccmode (insn, CCGOCmode)
11125 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11127 switch (get_attr_type (insn))
11130 gcc_assert (operands[2] == const1_rtx);
11131 return "add{q}\t%0, %0";
11134 if (REG_P (operands[2]))
11135 return "sal{q}\t{%b2, %0|%0, %b2}";
11136 else if (operands[2] == const1_rtx
11137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11138 return "sal{q}\t%0";
11140 return "sal{q}\t{%2, %0|%0, %2}";
11143 [(set (attr "type")
11144 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11146 (match_operand 0 "register_operand" ""))
11147 (match_operand 2 "const1_operand" ""))
11148 (const_string "alu")
11150 (const_string "ishift")))
11151 (set (attr "length_immediate")
11153 (ior (eq_attr "type" "alu")
11154 (and (eq_attr "type" "ishift")
11155 (and (match_operand 2 "const1_operand" "")
11156 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11159 (const_string "*")))
11160 (set_attr "mode" "DI")])
11162 (define_insn "*ashldi3_cconly_rex64"
11163 [(set (reg FLAGS_REG)
11165 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11166 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11168 (clobber (match_scratch:DI 0 "=r"))]
11170 && (optimize_function_for_size_p (cfun)
11171 || !TARGET_PARTIAL_FLAG_REG_STALL
11172 || (operands[2] == const1_rtx
11174 || TARGET_DOUBLE_WITH_ADD)))
11175 && ix86_match_ccmode (insn, CCGOCmode)
11176 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11178 switch (get_attr_type (insn))
11181 gcc_assert (operands[2] == const1_rtx);
11182 return "add{q}\t%0, %0";
11185 if (REG_P (operands[2]))
11186 return "sal{q}\t{%b2, %0|%0, %b2}";
11187 else if (operands[2] == const1_rtx
11188 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11189 return "sal{q}\t%0";
11191 return "sal{q}\t{%2, %0|%0, %2}";
11194 [(set (attr "type")
11195 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11197 (match_operand 0 "register_operand" ""))
11198 (match_operand 2 "const1_operand" ""))
11199 (const_string "alu")
11201 (const_string "ishift")))
11202 (set (attr "length_immediate")
11204 (ior (eq_attr "type" "alu")
11205 (and (eq_attr "type" "ishift")
11206 (and (match_operand 2 "const1_operand" "")
11207 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11210 (const_string "*")))
11211 (set_attr "mode" "DI")])
11213 (define_insn "*ashldi3_1"
11214 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11215 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11216 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11217 (clobber (reg:CC FLAGS_REG))]
11220 [(set_attr "type" "multi")])
11222 ;; By default we don't ask for a scratch register, because when DImode
11223 ;; values are manipulated, registers are already at a premium. But if
11224 ;; we have one handy, we won't turn it away.
11226 [(match_scratch:SI 3 "r")
11227 (parallel [(set (match_operand:DI 0 "register_operand" "")
11228 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11229 (match_operand:QI 2 "nonmemory_operand" "")))
11230 (clobber (reg:CC FLAGS_REG))])
11232 "!TARGET_64BIT && TARGET_CMOVE"
11234 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11237 [(set (match_operand:DI 0 "register_operand" "")
11238 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11239 (match_operand:QI 2 "nonmemory_operand" "")))
11240 (clobber (reg:CC FLAGS_REG))]
11241 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11242 ? epilogue_completed : reload_completed)"
11244 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11246 (define_insn "x86_shld"
11247 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11248 (ior:SI (ashift:SI (match_dup 0)
11249 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11250 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11251 (minus:QI (const_int 32) (match_dup 2)))))
11252 (clobber (reg:CC FLAGS_REG))]
11254 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11255 [(set_attr "type" "ishift")
11256 (set_attr "prefix_0f" "1")
11257 (set_attr "mode" "SI")
11258 (set_attr "pent_pair" "np")
11259 (set_attr "athlon_decode" "vector")
11260 (set_attr "amdfam10_decode" "vector")])
11262 (define_expand "x86_shift_adj_1"
11263 [(set (reg:CCZ FLAGS_REG)
11264 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11267 (set (match_operand:SI 0 "register_operand" "")
11268 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11269 (match_operand:SI 1 "register_operand" "")
11272 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11273 (match_operand:SI 3 "register_operand" "r")
11278 (define_expand "x86_shift_adj_2"
11279 [(use (match_operand:SI 0 "register_operand" ""))
11280 (use (match_operand:SI 1 "register_operand" ""))
11281 (use (match_operand:QI 2 "register_operand" ""))]
11284 rtx label = gen_label_rtx ();
11287 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11289 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11290 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11291 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11292 gen_rtx_LABEL_REF (VOIDmode, label),
11294 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11295 JUMP_LABEL (tmp) = label;
11297 emit_move_insn (operands[0], operands[1]);
11298 ix86_expand_clear (operands[1]);
11300 emit_label (label);
11301 LABEL_NUSES (label) = 1;
11306 (define_expand "ashlsi3"
11307 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11308 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11309 (match_operand:QI 2 "nonmemory_operand" "")))]
11311 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11313 (define_insn "*ashlsi3_1"
11314 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11315 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11316 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11320 switch (get_attr_type (insn))
11323 gcc_assert (operands[2] == const1_rtx);
11324 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11325 return "add{l}\t%0, %0";
11331 if (REG_P (operands[2]))
11332 return "sal{l}\t{%b2, %0|%0, %b2}";
11333 else if (operands[2] == const1_rtx
11334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11335 return "sal{l}\t%0";
11337 return "sal{l}\t{%2, %0|%0, %2}";
11340 [(set (attr "type")
11341 (cond [(eq_attr "alternative" "1")
11342 (const_string "lea")
11343 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11345 (match_operand 0 "register_operand" ""))
11346 (match_operand 2 "const1_operand" ""))
11347 (const_string "alu")
11349 (const_string "ishift")))
11350 (set (attr "length_immediate")
11352 (ior (eq_attr "type" "alu")
11353 (and (eq_attr "type" "ishift")
11354 (and (match_operand 2 "const1_operand" "")
11355 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11358 (const_string "*")))
11359 (set_attr "mode" "SI")])
11361 ;; Convert lea to the lea pattern to avoid flags dependency.
11363 [(set (match_operand 0 "register_operand" "")
11364 (ashift (match_operand 1 "index_register_operand" "")
11365 (match_operand:QI 2 "const_int_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11368 && true_regnum (operands[0]) != true_regnum (operands[1])
11369 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11373 enum machine_mode mode = GET_MODE (operands[0]);
11375 if (GET_MODE_SIZE (mode) < 4)
11376 operands[0] = gen_lowpart (SImode, operands[0]);
11378 operands[1] = gen_lowpart (Pmode, operands[1]);
11379 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11381 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11382 if (Pmode != SImode)
11383 pat = gen_rtx_SUBREG (SImode, pat, 0);
11384 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11388 ;; Rare case of shifting RSP is handled by generating move and shift
11390 [(set (match_operand 0 "register_operand" "")
11391 (ashift (match_operand 1 "register_operand" "")
11392 (match_operand:QI 2 "const_int_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11395 && true_regnum (operands[0]) != true_regnum (operands[1])"
11399 emit_move_insn (operands[0], operands[1]);
11400 pat = gen_rtx_SET (VOIDmode, operands[0],
11401 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11402 operands[0], operands[2]));
11403 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11404 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11408 (define_insn "*ashlsi3_1_zext"
11409 [(set (match_operand:DI 0 "register_operand" "=r,r")
11410 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11411 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11412 (clobber (reg:CC FLAGS_REG))]
11413 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11415 switch (get_attr_type (insn))
11418 gcc_assert (operands[2] == const1_rtx);
11419 return "add{l}\t%k0, %k0";
11425 if (REG_P (operands[2]))
11426 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11427 else if (operands[2] == const1_rtx
11428 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11429 return "sal{l}\t%k0";
11431 return "sal{l}\t{%2, %k0|%k0, %2}";
11434 [(set (attr "type")
11435 (cond [(eq_attr "alternative" "1")
11436 (const_string "lea")
11437 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11439 (match_operand 2 "const1_operand" ""))
11440 (const_string "alu")
11442 (const_string "ishift")))
11443 (set (attr "length_immediate")
11445 (ior (eq_attr "type" "alu")
11446 (and (eq_attr "type" "ishift")
11447 (and (match_operand 2 "const1_operand" "")
11448 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11451 (const_string "*")))
11452 (set_attr "mode" "SI")])
11454 ;; Convert lea to the lea pattern to avoid flags dependency.
11456 [(set (match_operand:DI 0 "register_operand" "")
11457 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11458 (match_operand:QI 2 "const_int_operand" ""))))
11459 (clobber (reg:CC FLAGS_REG))]
11460 "TARGET_64BIT && reload_completed
11461 && true_regnum (operands[0]) != true_regnum (operands[1])"
11462 [(set (match_dup 0) (zero_extend:DI
11463 (subreg:SI (mult:SI (match_dup 1)
11464 (match_dup 2)) 0)))]
11466 operands[1] = gen_lowpart (Pmode, operands[1]);
11467 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags. We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashlsi3_cmp"
11474 [(set (reg FLAGS_REG)
11476 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11479 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11480 (ashift:SI (match_dup 1) (match_dup 2)))]
11481 "(optimize_function_for_size_p (cfun)
11482 || !TARGET_PARTIAL_FLAG_REG_STALL
11483 || (operands[2] == const1_rtx
11485 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11486 && ix86_match_ccmode (insn, CCGOCmode)
11487 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11489 switch (get_attr_type (insn))
11492 gcc_assert (operands[2] == const1_rtx);
11493 return "add{l}\t%0, %0";
11496 if (REG_P (operands[2]))
11497 return "sal{l}\t{%b2, %0|%0, %b2}";
11498 else if (operands[2] == const1_rtx
11499 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11500 return "sal{l}\t%0";
11502 return "sal{l}\t{%2, %0|%0, %2}";
11505 [(set (attr "type")
11506 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11508 (match_operand 0 "register_operand" ""))
11509 (match_operand 2 "const1_operand" ""))
11510 (const_string "alu")
11512 (const_string "ishift")))
11513 (set (attr "length_immediate")
11515 (ior (eq_attr "type" "alu")
11516 (and (eq_attr "type" "ishift")
11517 (and (match_operand 2 "const1_operand" "")
11518 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11521 (const_string "*")))
11522 (set_attr "mode" "SI")])
11524 (define_insn "*ashlsi3_cconly"
11525 [(set (reg FLAGS_REG)
11527 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11530 (clobber (match_scratch:SI 0 "=r"))]
11531 "(optimize_function_for_size_p (cfun)
11532 || !TARGET_PARTIAL_FLAG_REG_STALL
11533 || (operands[2] == const1_rtx
11535 || TARGET_DOUBLE_WITH_ADD)))
11536 && ix86_match_ccmode (insn, CCGOCmode)
11537 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11539 switch (get_attr_type (insn))
11542 gcc_assert (operands[2] == const1_rtx);
11543 return "add{l}\t%0, %0";
11546 if (REG_P (operands[2]))
11547 return "sal{l}\t{%b2, %0|%0, %b2}";
11548 else if (operands[2] == const1_rtx
11549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11550 return "sal{l}\t%0";
11552 return "sal{l}\t{%2, %0|%0, %2}";
11555 [(set (attr "type")
11556 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11558 (match_operand 0 "register_operand" ""))
11559 (match_operand 2 "const1_operand" ""))
11560 (const_string "alu")
11562 (const_string "ishift")))
11563 (set (attr "length_immediate")
11565 (ior (eq_attr "type" "alu")
11566 (and (eq_attr "type" "ishift")
11567 (and (match_operand 2 "const1_operand" "")
11568 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11571 (const_string "*")))
11572 (set_attr "mode" "SI")])
11574 (define_insn "*ashlsi3_cmp_zext"
11575 [(set (reg FLAGS_REG)
11577 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11578 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11580 (set (match_operand:DI 0 "register_operand" "=r")
11581 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11583 && (optimize_function_for_size_p (cfun)
11584 || !TARGET_PARTIAL_FLAG_REG_STALL
11585 || (operands[2] == const1_rtx
11587 || TARGET_DOUBLE_WITH_ADD)))
11588 && ix86_match_ccmode (insn, CCGOCmode)
11589 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11591 switch (get_attr_type (insn))
11594 gcc_assert (operands[2] == const1_rtx);
11595 return "add{l}\t%k0, %k0";
11598 if (REG_P (operands[2]))
11599 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11600 else if (operands[2] == const1_rtx
11601 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11602 return "sal{l}\t%k0";
11604 return "sal{l}\t{%2, %k0|%k0, %2}";
11607 [(set (attr "type")
11608 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11610 (match_operand 2 "const1_operand" ""))
11611 (const_string "alu")
11613 (const_string "ishift")))
11614 (set (attr "length_immediate")
11616 (ior (eq_attr "type" "alu")
11617 (and (eq_attr "type" "ishift")
11618 (and (match_operand 2 "const1_operand" "")
11619 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11622 (const_string "*")))
11623 (set_attr "mode" "SI")])
11625 (define_expand "ashlhi3"
11626 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11627 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11628 (match_operand:QI 2 "nonmemory_operand" "")))]
11629 "TARGET_HIMODE_MATH"
11630 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11632 (define_insn "*ashlhi3_1_lea"
11633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11634 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11635 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "!TARGET_PARTIAL_REG_STALL
11638 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11640 switch (get_attr_type (insn))
11645 gcc_assert (operands[2] == const1_rtx);
11646 return "add{w}\t%0, %0";
11649 if (REG_P (operands[2]))
11650 return "sal{w}\t{%b2, %0|%0, %b2}";
11651 else if (operands[2] == const1_rtx
11652 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11653 return "sal{w}\t%0";
11655 return "sal{w}\t{%2, %0|%0, %2}";
11658 [(set (attr "type")
11659 (cond [(eq_attr "alternative" "1")
11660 (const_string "lea")
11661 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11663 (match_operand 0 "register_operand" ""))
11664 (match_operand 2 "const1_operand" ""))
11665 (const_string "alu")
11667 (const_string "ishift")))
11668 (set (attr "length_immediate")
11670 (ior (eq_attr "type" "alu")
11671 (and (eq_attr "type" "ishift")
11672 (and (match_operand 2 "const1_operand" "")
11673 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11676 (const_string "*")))
11677 (set_attr "mode" "HI,SI")])
11679 (define_insn "*ashlhi3_1"
11680 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11681 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "nonmemory_operand" "cI")))
11683 (clobber (reg:CC FLAGS_REG))]
11684 "TARGET_PARTIAL_REG_STALL
11685 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11687 switch (get_attr_type (insn))
11690 gcc_assert (operands[2] == const1_rtx);
11691 return "add{w}\t%0, %0";
11694 if (REG_P (operands[2]))
11695 return "sal{w}\t{%b2, %0|%0, %b2}";
11696 else if (operands[2] == const1_rtx
11697 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11698 return "sal{w}\t%0";
11700 return "sal{w}\t{%2, %0|%0, %2}";
11703 [(set (attr "type")
11704 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11706 (match_operand 0 "register_operand" ""))
11707 (match_operand 2 "const1_operand" ""))
11708 (const_string "alu")
11710 (const_string "ishift")))
11711 (set (attr "length_immediate")
11713 (ior (eq_attr "type" "alu")
11714 (and (eq_attr "type" "ishift")
11715 (and (match_operand 2 "const1_operand" "")
11716 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11719 (const_string "*")))
11720 (set_attr "mode" "HI")])
11722 ;; This pattern can't accept a variable shift count, since shifts by
11723 ;; zero don't affect the flags. We assume that shifts by constant
11724 ;; zero are optimized away.
11725 (define_insn "*ashlhi3_cmp"
11726 [(set (reg FLAGS_REG)
11728 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11729 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11731 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11732 (ashift:HI (match_dup 1) (match_dup 2)))]
11733 "(optimize_function_for_size_p (cfun)
11734 || !TARGET_PARTIAL_FLAG_REG_STALL
11735 || (operands[2] == const1_rtx
11737 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11738 && ix86_match_ccmode (insn, CCGOCmode)
11739 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11741 switch (get_attr_type (insn))
11744 gcc_assert (operands[2] == const1_rtx);
11745 return "add{w}\t%0, %0";
11748 if (REG_P (operands[2]))
11749 return "sal{w}\t{%b2, %0|%0, %b2}";
11750 else if (operands[2] == const1_rtx
11751 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11752 return "sal{w}\t%0";
11754 return "sal{w}\t{%2, %0|%0, %2}";
11757 [(set (attr "type")
11758 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11760 (match_operand 0 "register_operand" ""))
11761 (match_operand 2 "const1_operand" ""))
11762 (const_string "alu")
11764 (const_string "ishift")))
11765 (set (attr "length_immediate")
11767 (ior (eq_attr "type" "alu")
11768 (and (eq_attr "type" "ishift")
11769 (and (match_operand 2 "const1_operand" "")
11770 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11773 (const_string "*")))
11774 (set_attr "mode" "HI")])
11776 (define_insn "*ashlhi3_cconly"
11777 [(set (reg FLAGS_REG)
11779 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11780 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11782 (clobber (match_scratch:HI 0 "=r"))]
11783 "(optimize_function_for_size_p (cfun)
11784 || !TARGET_PARTIAL_FLAG_REG_STALL
11785 || (operands[2] == const1_rtx
11787 || TARGET_DOUBLE_WITH_ADD)))
11788 && ix86_match_ccmode (insn, CCGOCmode)
11789 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11791 switch (get_attr_type (insn))
11794 gcc_assert (operands[2] == const1_rtx);
11795 return "add{w}\t%0, %0";
11798 if (REG_P (operands[2]))
11799 return "sal{w}\t{%b2, %0|%0, %b2}";
11800 else if (operands[2] == const1_rtx
11801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802 return "sal{w}\t%0";
11804 return "sal{w}\t{%2, %0|%0, %2}";
11807 [(set (attr "type")
11808 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11810 (match_operand 0 "register_operand" ""))
11811 (match_operand 2 "const1_operand" ""))
11812 (const_string "alu")
11814 (const_string "ishift")))
11815 (set (attr "length_immediate")
11817 (ior (eq_attr "type" "alu")
11818 (and (eq_attr "type" "ishift")
11819 (and (match_operand 2 "const1_operand" "")
11820 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11823 (const_string "*")))
11824 (set_attr "mode" "HI")])
11826 (define_expand "ashlqi3"
11827 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11828 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11829 (match_operand:QI 2 "nonmemory_operand" "")))]
11830 "TARGET_QIMODE_MATH"
11831 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11833 ;; %%% Potential partial reg stall on alternative 2. What to do?
11835 (define_insn "*ashlqi3_1_lea"
11836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11837 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11838 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11839 (clobber (reg:CC FLAGS_REG))]
11840 "!TARGET_PARTIAL_REG_STALL
11841 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11843 switch (get_attr_type (insn))
11848 gcc_assert (operands[2] == const1_rtx);
11849 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11850 return "add{l}\t%k0, %k0";
11852 return "add{b}\t%0, %0";
11855 if (REG_P (operands[2]))
11857 if (get_attr_mode (insn) == MODE_SI)
11858 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11860 return "sal{b}\t{%b2, %0|%0, %b2}";
11862 else if (operands[2] == const1_rtx
11863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11865 if (get_attr_mode (insn) == MODE_SI)
11866 return "sal{l}\t%0";
11868 return "sal{b}\t%0";
11872 if (get_attr_mode (insn) == MODE_SI)
11873 return "sal{l}\t{%2, %k0|%k0, %2}";
11875 return "sal{b}\t{%2, %0|%0, %2}";
11879 [(set (attr "type")
11880 (cond [(eq_attr "alternative" "2")
11881 (const_string "lea")
11882 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11884 (match_operand 0 "register_operand" ""))
11885 (match_operand 2 "const1_operand" ""))
11886 (const_string "alu")
11888 (const_string "ishift")))
11889 (set (attr "length_immediate")
11891 (ior (eq_attr "type" "alu")
11892 (and (eq_attr "type" "ishift")
11893 (and (match_operand 2 "const1_operand" "")
11894 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11897 (const_string "*")))
11898 (set_attr "mode" "QI,SI,SI")])
11900 (define_insn "*ashlqi3_1"
11901 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11902 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11903 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11904 (clobber (reg:CC FLAGS_REG))]
11905 "TARGET_PARTIAL_REG_STALL
11906 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11908 switch (get_attr_type (insn))
11911 gcc_assert (operands[2] == const1_rtx);
11912 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11913 return "add{l}\t%k0, %k0";
11915 return "add{b}\t%0, %0";
11918 if (REG_P (operands[2]))
11920 if (get_attr_mode (insn) == MODE_SI)
11921 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11923 return "sal{b}\t{%b2, %0|%0, %b2}";
11925 else if (operands[2] == const1_rtx
11926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11928 if (get_attr_mode (insn) == MODE_SI)
11929 return "sal{l}\t%0";
11931 return "sal{b}\t%0";
11935 if (get_attr_mode (insn) == MODE_SI)
11936 return "sal{l}\t{%2, %k0|%k0, %2}";
11938 return "sal{b}\t{%2, %0|%0, %2}";
11942 [(set (attr "type")
11943 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11945 (match_operand 0 "register_operand" ""))
11946 (match_operand 2 "const1_operand" ""))
11947 (const_string "alu")
11949 (const_string "ishift")))
11950 (set (attr "length_immediate")
11952 (ior (eq_attr "type" "alu")
11953 (and (eq_attr "type" "ishift")
11954 (and (match_operand 2 "const1_operand" "")
11955 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11958 (const_string "*")))
11959 (set_attr "mode" "QI,SI")])
11961 ;; This pattern can't accept a variable shift count, since shifts by
11962 ;; zero don't affect the flags. We assume that shifts by constant
11963 ;; zero are optimized away.
11964 (define_insn "*ashlqi3_cmp"
11965 [(set (reg FLAGS_REG)
11967 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11968 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11970 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11971 (ashift:QI (match_dup 1) (match_dup 2)))]
11972 "(optimize_function_for_size_p (cfun)
11973 || !TARGET_PARTIAL_FLAG_REG_STALL
11974 || (operands[2] == const1_rtx
11976 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11977 && ix86_match_ccmode (insn, CCGOCmode)
11978 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11980 switch (get_attr_type (insn))
11983 gcc_assert (operands[2] == const1_rtx);
11984 return "add{b}\t%0, %0";
11987 if (REG_P (operands[2]))
11988 return "sal{b}\t{%b2, %0|%0, %b2}";
11989 else if (operands[2] == const1_rtx
11990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11991 return "sal{b}\t%0";
11993 return "sal{b}\t{%2, %0|%0, %2}";
11996 [(set (attr "type")
11997 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11999 (match_operand 0 "register_operand" ""))
12000 (match_operand 2 "const1_operand" ""))
12001 (const_string "alu")
12003 (const_string "ishift")))
12004 (set (attr "length_immediate")
12006 (ior (eq_attr "type" "alu")
12007 (and (eq_attr "type" "ishift")
12008 (and (match_operand 2 "const1_operand" "")
12009 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12012 (const_string "*")))
12013 (set_attr "mode" "QI")])
12015 (define_insn "*ashlqi3_cconly"
12016 [(set (reg FLAGS_REG)
12018 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12019 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12021 (clobber (match_scratch:QI 0 "=q"))]
12022 "(optimize_function_for_size_p (cfun)
12023 || !TARGET_PARTIAL_FLAG_REG_STALL
12024 || (operands[2] == const1_rtx
12026 || TARGET_DOUBLE_WITH_ADD)))
12027 && ix86_match_ccmode (insn, CCGOCmode)
12028 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12030 switch (get_attr_type (insn))
12033 gcc_assert (operands[2] == const1_rtx);
12034 return "add{b}\t%0, %0";
12037 if (REG_P (operands[2]))
12038 return "sal{b}\t{%b2, %0|%0, %b2}";
12039 else if (operands[2] == const1_rtx
12040 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12041 return "sal{b}\t%0";
12043 return "sal{b}\t{%2, %0|%0, %2}";
12046 [(set (attr "type")
12047 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12049 (match_operand 0 "register_operand" ""))
12050 (match_operand 2 "const1_operand" ""))
12051 (const_string "alu")
12053 (const_string "ishift")))
12054 (set (attr "length_immediate")
12056 (ior (eq_attr "type" "alu")
12057 (and (eq_attr "type" "ishift")
12058 (and (match_operand 2 "const1_operand" "")
12059 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12062 (const_string "*")))
12063 (set_attr "mode" "QI")])
12065 ;; See comment above `ashldi3' about how this works.
12067 (define_expand "ashrti3"
12068 [(set (match_operand:TI 0 "register_operand" "")
12069 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12070 (match_operand:QI 2 "nonmemory_operand" "")))]
12072 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12074 (define_insn "*ashrti3_1"
12075 [(set (match_operand:TI 0 "register_operand" "=r")
12076 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12077 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12078 (clobber (reg:CC FLAGS_REG))]
12081 [(set_attr "type" "multi")])
12084 [(match_scratch:DI 3 "r")
12085 (parallel [(set (match_operand:TI 0 "register_operand" "")
12086 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12087 (match_operand:QI 2 "nonmemory_operand" "")))
12088 (clobber (reg:CC FLAGS_REG))])
12092 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12095 [(set (match_operand:TI 0 "register_operand" "")
12096 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097 (match_operand:QI 2 "nonmemory_operand" "")))
12098 (clobber (reg:CC FLAGS_REG))]
12099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100 ? epilogue_completed : reload_completed)"
12102 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12104 (define_insn "x86_64_shrd"
12105 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12106 (ior:DI (ashiftrt:DI (match_dup 0)
12107 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12108 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12109 (minus:QI (const_int 64) (match_dup 2)))))
12110 (clobber (reg:CC FLAGS_REG))]
12112 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12113 [(set_attr "type" "ishift")
12114 (set_attr "prefix_0f" "1")
12115 (set_attr "mode" "DI")
12116 (set_attr "athlon_decode" "vector")
12117 (set_attr "amdfam10_decode" "vector")])
12119 (define_expand "ashrdi3"
12120 [(set (match_operand:DI 0 "shiftdi_operand" "")
12121 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12122 (match_operand:QI 2 "nonmemory_operand" "")))]
12124 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12126 (define_expand "x86_64_shift_adj_3"
12127 [(use (match_operand:DI 0 "register_operand" ""))
12128 (use (match_operand:DI 1 "register_operand" ""))
12129 (use (match_operand:QI 2 "register_operand" ""))]
12132 rtx label = gen_label_rtx ();
12135 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12137 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12138 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12139 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12140 gen_rtx_LABEL_REF (VOIDmode, label),
12142 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12143 JUMP_LABEL (tmp) = label;
12145 emit_move_insn (operands[0], operands[1]);
12146 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12148 emit_label (label);
12149 LABEL_NUSES (label) = 1;
12154 (define_insn "ashrdi3_63_rex64"
12155 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12156 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12157 (match_operand:DI 2 "const_int_operand" "i,i")))
12158 (clobber (reg:CC FLAGS_REG))]
12159 "TARGET_64BIT && INTVAL (operands[2]) == 63
12160 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12161 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12164 sar{q}\t{%2, %0|%0, %2}"
12165 [(set_attr "type" "imovx,ishift")
12166 (set_attr "prefix_0f" "0,*")
12167 (set_attr "length_immediate" "0,*")
12168 (set_attr "modrm" "0,1")
12169 (set_attr "mode" "DI")])
12171 (define_insn "*ashrdi3_1_one_bit_rex64"
12172 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12173 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const1_operand" "")))
12175 (clobber (reg:CC FLAGS_REG))]
12177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12178 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12180 [(set_attr "type" "ishift")
12181 (set_attr "length_immediate" "0")
12182 (set_attr "mode" "DI")])
12184 (define_insn "*ashrdi3_1_rex64"
12185 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12186 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12191 sar{q}\t{%2, %0|%0, %2}
12192 sar{q}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "DI")])
12196 ;; This pattern can't accept a variable shift count, since shifts by
12197 ;; zero don't affect the flags. We assume that shifts by constant
12198 ;; zero are optimized away.
12199 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12200 [(set (reg FLAGS_REG)
12202 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12203 (match_operand:QI 2 "const1_operand" ""))
12205 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12206 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12208 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12209 && ix86_match_ccmode (insn, CCGOCmode)
12210 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12212 [(set_attr "type" "ishift")
12213 (set_attr "length_immediate" "0")
12214 (set_attr "mode" "DI")])
12216 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12217 [(set (reg FLAGS_REG)
12219 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12220 (match_operand:QI 2 "const1_operand" ""))
12222 (clobber (match_scratch:DI 0 "=r"))]
12224 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12225 && ix86_match_ccmode (insn, CCGOCmode)
12226 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12228 [(set_attr "type" "ishift")
12229 (set_attr "length_immediate" "0")
12230 (set_attr "mode" "DI")])
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags. We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*ashrdi3_cmp_rex64"
12236 [(set (reg FLAGS_REG)
12238 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12241 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12242 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12244 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12245 && ix86_match_ccmode (insn, CCGOCmode)
12246 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12247 "sar{q}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "DI")])
12251 (define_insn "*ashrdi3_cconly_rex64"
12252 [(set (reg FLAGS_REG)
12254 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12255 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12257 (clobber (match_scratch:DI 0 "=r"))]
12259 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12260 && ix86_match_ccmode (insn, CCGOCmode)
12261 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12262 "sar{q}\t{%2, %0|%0, %2}"
12263 [(set_attr "type" "ishift")
12264 (set_attr "mode" "DI")])
12266 (define_insn "*ashrdi3_1"
12267 [(set (match_operand:DI 0 "register_operand" "=r")
12268 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12269 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12270 (clobber (reg:CC FLAGS_REG))]
12273 [(set_attr "type" "multi")])
12275 ;; By default we don't ask for a scratch register, because when DImode
12276 ;; values are manipulated, registers are already at a premium. But if
12277 ;; we have one handy, we won't turn it away.
12279 [(match_scratch:SI 3 "r")
12280 (parallel [(set (match_operand:DI 0 "register_operand" "")
12281 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12282 (match_operand:QI 2 "nonmemory_operand" "")))
12283 (clobber (reg:CC FLAGS_REG))])
12285 "!TARGET_64BIT && TARGET_CMOVE"
12287 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12290 [(set (match_operand:DI 0 "register_operand" "")
12291 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12292 (match_operand:QI 2 "nonmemory_operand" "")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12295 ? epilogue_completed : reload_completed)"
12297 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12299 (define_insn "x86_shrd"
12300 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12301 (ior:SI (ashiftrt:SI (match_dup 0)
12302 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12303 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12304 (minus:QI (const_int 32) (match_dup 2)))))
12305 (clobber (reg:CC FLAGS_REG))]
12307 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12308 [(set_attr "type" "ishift")
12309 (set_attr "prefix_0f" "1")
12310 (set_attr "pent_pair" "np")
12311 (set_attr "mode" "SI")])
12313 (define_expand "x86_shift_adj_3"
12314 [(use (match_operand:SI 0 "register_operand" ""))
12315 (use (match_operand:SI 1 "register_operand" ""))
12316 (use (match_operand:QI 2 "register_operand" ""))]
12319 rtx label = gen_label_rtx ();
12322 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12324 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12325 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12326 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12327 gen_rtx_LABEL_REF (VOIDmode, label),
12329 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12330 JUMP_LABEL (tmp) = label;
12332 emit_move_insn (operands[0], operands[1]);
12333 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12335 emit_label (label);
12336 LABEL_NUSES (label) = 1;
12341 (define_expand "ashrsi3_31"
12342 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12343 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12344 (match_operand:SI 2 "const_int_operand" "i,i")))
12345 (clobber (reg:CC FLAGS_REG))])]
12348 (define_insn "*ashrsi3_31"
12349 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12350 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12351 (match_operand:SI 2 "const_int_operand" "i,i")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "INTVAL (operands[2]) == 31
12354 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12355 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12358 sar{l}\t{%2, %0|%0, %2}"
12359 [(set_attr "type" "imovx,ishift")
12360 (set_attr "prefix_0f" "0,*")
12361 (set_attr "length_immediate" "0,*")
12362 (set_attr "modrm" "0,1")
12363 (set_attr "mode" "SI")])
12365 (define_insn "*ashrsi3_31_zext"
12366 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12367 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12368 (match_operand:SI 2 "const_int_operand" "i,i"))))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12371 && INTVAL (operands[2]) == 31
12372 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12375 sar{l}\t{%2, %k0|%k0, %2}"
12376 [(set_attr "type" "imovx,ishift")
12377 (set_attr "prefix_0f" "0,*")
12378 (set_attr "length_immediate" "0,*")
12379 (set_attr "modrm" "0,1")
12380 (set_attr "mode" "SI")])
12382 (define_expand "ashrsi3"
12383 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12384 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12385 (match_operand:QI 2 "nonmemory_operand" "")))]
12387 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12389 (define_insn "*ashrsi3_1_one_bit"
12390 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12391 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12392 (match_operand:QI 2 "const1_operand" "")))
12393 (clobber (reg:CC FLAGS_REG))]
12394 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12395 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12397 [(set_attr "type" "ishift")
12398 (set_attr "length_immediate" "0")
12399 (set_attr "mode" "SI")])
12401 (define_insn "*ashrsi3_1_one_bit_zext"
12402 [(set (match_operand:DI 0 "register_operand" "=r")
12403 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12404 (match_operand:QI 2 "const1_operand" ""))))
12405 (clobber (reg:CC FLAGS_REG))]
12407 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12410 [(set_attr "type" "ishift")
12411 (set_attr "length_immediate" "0")
12412 (set_attr "mode" "SI")])
12414 (define_insn "*ashrsi3_1"
12415 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12416 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12417 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12421 sar{l}\t{%2, %0|%0, %2}
12422 sar{l}\t{%b2, %0|%0, %b2}"
12423 [(set_attr "type" "ishift")
12424 (set_attr "mode" "SI")])
12426 (define_insn "*ashrsi3_1_zext"
12427 [(set (match_operand:DI 0 "register_operand" "=r,r")
12428 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12429 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12433 sar{l}\t{%2, %k0|%k0, %2}
12434 sar{l}\t{%b2, %k0|%k0, %b2}"
12435 [(set_attr "type" "ishift")
12436 (set_attr "mode" "SI")])
12438 ;; This pattern can't accept a variable shift count, since shifts by
12439 ;; zero don't affect the flags. We assume that shifts by constant
12440 ;; zero are optimized away.
12441 (define_insn "*ashrsi3_one_bit_cmp"
12442 [(set (reg FLAGS_REG)
12444 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12445 (match_operand:QI 2 "const1_operand" ""))
12447 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12448 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12449 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12450 && ix86_match_ccmode (insn, CCGOCmode)
12451 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12453 [(set_attr "type" "ishift")
12454 (set_attr "length_immediate" "0")
12455 (set_attr "mode" "SI")])
12457 (define_insn "*ashrsi3_one_bit_cconly"
12458 [(set (reg FLAGS_REG)
12460 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12461 (match_operand:QI 2 "const1_operand" ""))
12463 (clobber (match_scratch:SI 0 "=r"))]
12464 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12465 && ix86_match_ccmode (insn, CCGOCmode)
12466 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12468 [(set_attr "type" "ishift")
12469 (set_attr "length_immediate" "0")
12470 (set_attr "mode" "SI")])
12472 (define_insn "*ashrsi3_one_bit_cmp_zext"
12473 [(set (reg FLAGS_REG)
12475 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12476 (match_operand:QI 2 "const1_operand" ""))
12478 (set (match_operand:DI 0 "register_operand" "=r")
12479 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12481 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12482 && ix86_match_ccmode (insn, CCmode)
12483 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12485 [(set_attr "type" "ishift")
12486 (set_attr "length_immediate" "0")
12487 (set_attr "mode" "SI")])
12489 ;; This pattern can't accept a variable shift count, since shifts by
12490 ;; zero don't affect the flags. We assume that shifts by constant
12491 ;; zero are optimized away.
12492 (define_insn "*ashrsi3_cmp"
12493 [(set (reg FLAGS_REG)
12495 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12496 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12498 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12499 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12500 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12501 && ix86_match_ccmode (insn, CCGOCmode)
12502 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12503 "sar{l}\t{%2, %0|%0, %2}"
12504 [(set_attr "type" "ishift")
12505 (set_attr "mode" "SI")])
12507 (define_insn "*ashrsi3_cconly"
12508 [(set (reg FLAGS_REG)
12510 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12511 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12513 (clobber (match_scratch:SI 0 "=r"))]
12514 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515 && ix86_match_ccmode (insn, CCGOCmode)
12516 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517 "sar{l}\t{%2, %0|%0, %2}"
12518 [(set_attr "type" "ishift")
12519 (set_attr "mode" "SI")])
12521 (define_insn "*ashrsi3_cmp_zext"
12522 [(set (reg FLAGS_REG)
12524 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12525 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12527 (set (match_operand:DI 0 "register_operand" "=r")
12528 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12530 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12531 && ix86_match_ccmode (insn, CCGOCmode)
12532 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12533 "sar{l}\t{%2, %k0|%k0, %2}"
12534 [(set_attr "type" "ishift")
12535 (set_attr "mode" "SI")])
12537 (define_expand "ashrhi3"
12538 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12539 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12540 (match_operand:QI 2 "nonmemory_operand" "")))]
12541 "TARGET_HIMODE_MATH"
12542 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12544 (define_insn "*ashrhi3_1_one_bit"
12545 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12546 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12547 (match_operand:QI 2 "const1_operand" "")))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12550 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12552 [(set_attr "type" "ishift")
12553 (set_attr "length_immediate" "0")
12554 (set_attr "mode" "HI")])
12556 (define_insn "*ashrhi3_1"
12557 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12558 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12559 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12560 (clobber (reg:CC FLAGS_REG))]
12561 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12563 sar{w}\t{%2, %0|%0, %2}
12564 sar{w}\t{%b2, %0|%0, %b2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "HI")])
12568 ;; This pattern can't accept a variable shift count, since shifts by
12569 ;; zero don't affect the flags. We assume that shifts by constant
12570 ;; zero are optimized away.
12571 (define_insn "*ashrhi3_one_bit_cmp"
12572 [(set (reg FLAGS_REG)
12574 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12575 (match_operand:QI 2 "const1_operand" ""))
12577 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12578 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12579 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12580 && ix86_match_ccmode (insn, CCGOCmode)
12581 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12583 [(set_attr "type" "ishift")
12584 (set_attr "length_immediate" "0")
12585 (set_attr "mode" "HI")])
12587 (define_insn "*ashrhi3_one_bit_cconly"
12588 [(set (reg FLAGS_REG)
12590 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591 (match_operand:QI 2 "const1_operand" ""))
12593 (clobber (match_scratch:HI 0 "=r"))]
12594 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12595 && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598 [(set_attr "type" "ishift")
12599 (set_attr "length_immediate" "0")
12600 (set_attr "mode" "HI")])
12602 ;; This pattern can't accept a variable shift count, since shifts by
12603 ;; zero don't affect the flags. We assume that shifts by constant
12604 ;; zero are optimized away.
12605 (define_insn "*ashrhi3_cmp"
12606 [(set (reg FLAGS_REG)
12608 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12611 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12612 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12613 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12614 && ix86_match_ccmode (insn, CCGOCmode)
12615 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12616 "sar{w}\t{%2, %0|%0, %2}"
12617 [(set_attr "type" "ishift")
12618 (set_attr "mode" "HI")])
12620 (define_insn "*ashrhi3_cconly"
12621 [(set (reg FLAGS_REG)
12623 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12626 (clobber (match_scratch:HI 0 "=r"))]
12627 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12628 && ix86_match_ccmode (insn, CCGOCmode)
12629 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12630 "sar{w}\t{%2, %0|%0, %2}"
12631 [(set_attr "type" "ishift")
12632 (set_attr "mode" "HI")])
12634 (define_expand "ashrqi3"
12635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12636 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12637 (match_operand:QI 2 "nonmemory_operand" "")))]
12638 "TARGET_QIMODE_MATH"
12639 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12641 (define_insn "*ashrqi3_1_one_bit"
12642 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12643 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" "")))
12645 (clobber (reg:CC FLAGS_REG))]
12646 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12647 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12649 [(set_attr "type" "ishift")
12650 (set_attr "length_immediate" "0")
12651 (set_attr "mode" "QI")])
12653 (define_insn "*ashrqi3_1_one_bit_slp"
12654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12655 (ashiftrt:QI (match_dup 0)
12656 (match_operand:QI 1 "const1_operand" "")))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12660 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12662 [(set_attr "type" "ishift1")
12663 (set_attr "length_immediate" "0")
12664 (set_attr "mode" "QI")])
12666 (define_insn "*ashrqi3_1"
12667 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12668 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12669 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12670 (clobber (reg:CC FLAGS_REG))]
12671 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12673 sar{b}\t{%2, %0|%0, %2}
12674 sar{b}\t{%b2, %0|%0, %b2}"
12675 [(set_attr "type" "ishift")
12676 (set_attr "mode" "QI")])
12678 (define_insn "*ashrqi3_1_slp"
12679 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12680 (ashiftrt:QI (match_dup 0)
12681 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12682 (clobber (reg:CC FLAGS_REG))]
12683 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12684 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12686 sar{b}\t{%1, %0|%0, %1}
12687 sar{b}\t{%b1, %0|%0, %b1}"
12688 [(set_attr "type" "ishift1")
12689 (set_attr "mode" "QI")])
12691 ;; This pattern can't accept a variable shift count, since shifts by
12692 ;; zero don't affect the flags. We assume that shifts by constant
12693 ;; zero are optimized away.
12694 (define_insn "*ashrqi3_one_bit_cmp"
12695 [(set (reg FLAGS_REG)
12697 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12698 (match_operand:QI 2 "const1_operand" "I"))
12700 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12701 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12702 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12703 && ix86_match_ccmode (insn, CCGOCmode)
12704 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12706 [(set_attr "type" "ishift")
12707 (set_attr "length_immediate" "0")
12708 (set_attr "mode" "QI")])
12710 (define_insn "*ashrqi3_one_bit_cconly"
12711 [(set (reg FLAGS_REG)
12713 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12714 (match_operand:QI 2 "const1_operand" ""))
12716 (clobber (match_scratch:QI 0 "=q"))]
12717 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12718 && ix86_match_ccmode (insn, CCGOCmode)
12719 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12721 [(set_attr "type" "ishift")
12722 (set_attr "length_immediate" "0")
12723 (set_attr "mode" "QI")])
12725 ;; This pattern can't accept a variable shift count, since shifts by
12726 ;; zero don't affect the flags. We assume that shifts by constant
12727 ;; zero are optimized away.
12728 (define_insn "*ashrqi3_cmp"
12729 [(set (reg FLAGS_REG)
12731 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12734 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12735 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12736 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12737 && ix86_match_ccmode (insn, CCGOCmode)
12738 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12739 "sar{b}\t{%2, %0|%0, %2}"
12740 [(set_attr "type" "ishift")
12741 (set_attr "mode" "QI")])
12743 (define_insn "*ashrqi3_cconly"
12744 [(set (reg FLAGS_REG)
12746 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12749 (clobber (match_scratch:QI 0 "=q"))]
12750 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12751 && ix86_match_ccmode (insn, CCGOCmode)
12752 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12753 "sar{b}\t{%2, %0|%0, %2}"
12754 [(set_attr "type" "ishift")
12755 (set_attr "mode" "QI")])
12758 ;; Logical shift instructions
12760 ;; See comment above `ashldi3' about how this works.
12762 (define_expand "lshrti3"
12763 [(set (match_operand:TI 0 "register_operand" "")
12764 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12765 (match_operand:QI 2 "nonmemory_operand" "")))]
12767 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12769 ;; This pattern must be defined before *lshrti3_1 to prevent
12770 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12772 (define_insn "*avx_lshrti3"
12773 [(set (match_operand:TI 0 "register_operand" "=x")
12774 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12775 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12778 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12779 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12781 [(set_attr "type" "sseishft")
12782 (set_attr "prefix" "vex")
12783 (set_attr "length_immediate" "1")
12784 (set_attr "mode" "TI")])
12786 (define_insn "sse2_lshrti3"
12787 [(set (match_operand:TI 0 "register_operand" "=x")
12788 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12789 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12792 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12793 return "psrldq\t{%2, %0|%0, %2}";
12795 [(set_attr "type" "sseishft")
12796 (set_attr "prefix_data16" "1")
12797 (set_attr "length_immediate" "1")
12798 (set_attr "mode" "TI")])
12800 (define_insn "*lshrti3_1"
12801 [(set (match_operand:TI 0 "register_operand" "=r")
12802 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12803 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12804 (clobber (reg:CC FLAGS_REG))]
12807 [(set_attr "type" "multi")])
12810 [(match_scratch:DI 3 "r")
12811 (parallel [(set (match_operand:TI 0 "register_operand" "")
12812 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12813 (match_operand:QI 2 "nonmemory_operand" "")))
12814 (clobber (reg:CC FLAGS_REG))])
12818 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12821 [(set (match_operand:TI 0 "register_operand" "")
12822 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12823 (match_operand:QI 2 "nonmemory_operand" "")))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12826 ? epilogue_completed : reload_completed)"
12828 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12830 (define_expand "lshrdi3"
12831 [(set (match_operand:DI 0 "shiftdi_operand" "")
12832 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12833 (match_operand:QI 2 "nonmemory_operand" "")))]
12835 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12837 (define_insn "*lshrdi3_1_one_bit_rex64"
12838 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12839 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12840 (match_operand:QI 2 "const1_operand" "")))
12841 (clobber (reg:CC FLAGS_REG))]
12843 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12846 [(set_attr "type" "ishift")
12847 (set_attr "length_immediate" "0")
12848 (set_attr "mode" "DI")])
12850 (define_insn "*lshrdi3_1_rex64"
12851 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12852 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12853 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12854 (clobber (reg:CC FLAGS_REG))]
12855 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857 shr{q}\t{%2, %0|%0, %2}
12858 shr{q}\t{%b2, %0|%0, %b2}"
12859 [(set_attr "type" "ishift")
12860 (set_attr "mode" "DI")])
12862 ;; This pattern can't accept a variable shift count, since shifts by
12863 ;; zero don't affect the flags. We assume that shifts by constant
12864 ;; zero are optimized away.
12865 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12866 [(set (reg FLAGS_REG)
12868 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12869 (match_operand:QI 2 "const1_operand" ""))
12871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12872 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12874 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12875 && ix86_match_ccmode (insn, CCGOCmode)
12876 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 [(set_attr "type" "ishift")
12879 (set_attr "length_immediate" "0")
12880 (set_attr "mode" "DI")])
12882 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12883 [(set (reg FLAGS_REG)
12885 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12886 (match_operand:QI 2 "const1_operand" ""))
12888 (clobber (match_scratch:DI 0 "=r"))]
12890 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12891 && ix86_match_ccmode (insn, CCGOCmode)
12892 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12894 [(set_attr "type" "ishift")
12895 (set_attr "length_immediate" "0")
12896 (set_attr "mode" "DI")])
12898 ;; This pattern can't accept a variable shift count, since shifts by
12899 ;; zero don't affect the flags. We assume that shifts by constant
12900 ;; zero are optimized away.
12901 (define_insn "*lshrdi3_cmp_rex64"
12902 [(set (reg FLAGS_REG)
12904 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12905 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12907 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12908 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12910 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12911 && ix86_match_ccmode (insn, CCGOCmode)
12912 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12913 "shr{q}\t{%2, %0|%0, %2}"
12914 [(set_attr "type" "ishift")
12915 (set_attr "mode" "DI")])
12917 (define_insn "*lshrdi3_cconly_rex64"
12918 [(set (reg FLAGS_REG)
12920 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12921 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12923 (clobber (match_scratch:DI 0 "=r"))]
12925 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12926 && ix86_match_ccmode (insn, CCGOCmode)
12927 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12928 "shr{q}\t{%2, %0|%0, %2}"
12929 [(set_attr "type" "ishift")
12930 (set_attr "mode" "DI")])
12932 (define_insn "*lshrdi3_1"
12933 [(set (match_operand:DI 0 "register_operand" "=r")
12934 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12935 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12936 (clobber (reg:CC FLAGS_REG))]
12939 [(set_attr "type" "multi")])
12941 ;; By default we don't ask for a scratch register, because when DImode
12942 ;; values are manipulated, registers are already at a premium. But if
12943 ;; we have one handy, we won't turn it away.
12945 [(match_scratch:SI 3 "r")
12946 (parallel [(set (match_operand:DI 0 "register_operand" "")
12947 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12948 (match_operand:QI 2 "nonmemory_operand" "")))
12949 (clobber (reg:CC FLAGS_REG))])
12951 "!TARGET_64BIT && TARGET_CMOVE"
12953 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12956 [(set (match_operand:DI 0 "register_operand" "")
12957 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12958 (match_operand:QI 2 "nonmemory_operand" "")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12961 ? epilogue_completed : reload_completed)"
12963 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12965 (define_expand "lshrsi3"
12966 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12967 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12968 (match_operand:QI 2 "nonmemory_operand" "")))]
12970 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12972 (define_insn "*lshrsi3_1_one_bit"
12973 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12974 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12975 (match_operand:QI 2 "const1_operand" "")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12978 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12980 [(set_attr "type" "ishift")
12981 (set_attr "length_immediate" "0")
12982 (set_attr "mode" "SI")])
12984 (define_insn "*lshrsi3_1_one_bit_zext"
12985 [(set (match_operand:DI 0 "register_operand" "=r")
12986 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12987 (match_operand:QI 2 "const1_operand" "")))
12988 (clobber (reg:CC FLAGS_REG))]
12990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12991 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12993 [(set_attr "type" "ishift")
12994 (set_attr "length_immediate" "0")
12995 (set_attr "mode" "SI")])
12997 (define_insn "*lshrsi3_1"
12998 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12999 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13000 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13001 (clobber (reg:CC FLAGS_REG))]
13002 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13004 shr{l}\t{%2, %0|%0, %2}
13005 shr{l}\t{%b2, %0|%0, %b2}"
13006 [(set_attr "type" "ishift")
13007 (set_attr "mode" "SI")])
13009 (define_insn "*lshrsi3_1_zext"
13010 [(set (match_operand:DI 0 "register_operand" "=r,r")
13012 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13013 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13014 (clobber (reg:CC FLAGS_REG))]
13015 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017 shr{l}\t{%2, %k0|%k0, %2}
13018 shr{l}\t{%b2, %k0|%k0, %b2}"
13019 [(set_attr "type" "ishift")
13020 (set_attr "mode" "SI")])
13022 ;; This pattern can't accept a variable shift count, since shifts by
13023 ;; zero don't affect the flags. We assume that shifts by constant
13024 ;; zero are optimized away.
13025 (define_insn "*lshrsi3_one_bit_cmp"
13026 [(set (reg FLAGS_REG)
13028 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13029 (match_operand:QI 2 "const1_operand" ""))
13031 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13032 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13033 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13034 && ix86_match_ccmode (insn, CCGOCmode)
13035 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13037 [(set_attr "type" "ishift")
13038 (set_attr "length_immediate" "0")
13039 (set_attr "mode" "SI")])
13041 (define_insn "*lshrsi3_one_bit_cconly"
13042 [(set (reg FLAGS_REG)
13044 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13045 (match_operand:QI 2 "const1_operand" ""))
13047 (clobber (match_scratch:SI 0 "=r"))]
13048 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13049 && ix86_match_ccmode (insn, CCGOCmode)
13050 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13052 [(set_attr "type" "ishift")
13053 (set_attr "length_immediate" "0")
13054 (set_attr "mode" "SI")])
13056 (define_insn "*lshrsi3_cmp_one_bit_zext"
13057 [(set (reg FLAGS_REG)
13059 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13060 (match_operand:QI 2 "const1_operand" ""))
13062 (set (match_operand:DI 0 "register_operand" "=r")
13063 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13066 && ix86_match_ccmode (insn, CCGOCmode)
13067 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13069 [(set_attr "type" "ishift")
13070 (set_attr "length_immediate" "0")
13071 (set_attr "mode" "SI")])
13073 ;; This pattern can't accept a variable shift count, since shifts by
13074 ;; zero don't affect the flags. We assume that shifts by constant
13075 ;; zero are optimized away.
13076 (define_insn "*lshrsi3_cmp"
13077 [(set (reg FLAGS_REG)
13079 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13080 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13082 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13083 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13084 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13085 && ix86_match_ccmode (insn, CCGOCmode)
13086 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13087 "shr{l}\t{%2, %0|%0, %2}"
13088 [(set_attr "type" "ishift")
13089 (set_attr "mode" "SI")])
13091 (define_insn "*lshrsi3_cconly"
13092 [(set (reg FLAGS_REG)
13094 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13095 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13097 (clobber (match_scratch:SI 0 "=r"))]
13098 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13099 && ix86_match_ccmode (insn, CCGOCmode)
13100 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13101 "shr{l}\t{%2, %0|%0, %2}"
13102 [(set_attr "type" "ishift")
13103 (set_attr "mode" "SI")])
13105 (define_insn "*lshrsi3_cmp_zext"
13106 [(set (reg FLAGS_REG)
13108 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13109 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13111 (set (match_operand:DI 0 "register_operand" "=r")
13112 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13114 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13115 && ix86_match_ccmode (insn, CCGOCmode)
13116 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13117 "shr{l}\t{%2, %k0|%k0, %2}"
13118 [(set_attr "type" "ishift")
13119 (set_attr "mode" "SI")])
13121 (define_expand "lshrhi3"
13122 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13123 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13124 (match_operand:QI 2 "nonmemory_operand" "")))]
13125 "TARGET_HIMODE_MATH"
13126 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13128 (define_insn "*lshrhi3_1_one_bit"
13129 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13130 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13131 (match_operand:QI 2 "const1_operand" "")))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13134 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13136 [(set_attr "type" "ishift")
13137 (set_attr "length_immediate" "0")
13138 (set_attr "mode" "HI")])
13140 (define_insn "*lshrhi3_1"
13141 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13142 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13143 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13147 shr{w}\t{%2, %0|%0, %2}
13148 shr{w}\t{%b2, %0|%0, %b2}"
13149 [(set_attr "type" "ishift")
13150 (set_attr "mode" "HI")])
13152 ;; This pattern can't accept a variable shift count, since shifts by
13153 ;; zero don't affect the flags. We assume that shifts by constant
13154 ;; zero are optimized away.
13155 (define_insn "*lshrhi3_one_bit_cmp"
13156 [(set (reg FLAGS_REG)
13158 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13159 (match_operand:QI 2 "const1_operand" ""))
13161 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13162 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13163 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13164 && ix86_match_ccmode (insn, CCGOCmode)
13165 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13167 [(set_attr "type" "ishift")
13168 (set_attr "length_immediate" "0")
13169 (set_attr "mode" "HI")])
13171 (define_insn "*lshrhi3_one_bit_cconly"
13172 [(set (reg FLAGS_REG)
13174 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13175 (match_operand:QI 2 "const1_operand" ""))
13177 (clobber (match_scratch:HI 0 "=r"))]
13178 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13179 && ix86_match_ccmode (insn, CCGOCmode)
13180 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13182 [(set_attr "type" "ishift")
13183 (set_attr "length_immediate" "0")
13184 (set_attr "mode" "HI")])
13186 ;; This pattern can't accept a variable shift count, since shifts by
13187 ;; zero don't affect the flags. We assume that shifts by constant
13188 ;; zero are optimized away.
13189 (define_insn "*lshrhi3_cmp"
13190 [(set (reg FLAGS_REG)
13192 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13193 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13195 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13196 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13197 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13198 && ix86_match_ccmode (insn, CCGOCmode)
13199 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13200 "shr{w}\t{%2, %0|%0, %2}"
13201 [(set_attr "type" "ishift")
13202 (set_attr "mode" "HI")])
13204 (define_insn "*lshrhi3_cconly"
13205 [(set (reg FLAGS_REG)
13207 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13208 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13210 (clobber (match_scratch:HI 0 "=r"))]
13211 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13212 && ix86_match_ccmode (insn, CCGOCmode)
13213 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13214 "shr{w}\t{%2, %0|%0, %2}"
13215 [(set_attr "type" "ishift")
13216 (set_attr "mode" "HI")])
13218 (define_expand "lshrqi3"
13219 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13220 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13221 (match_operand:QI 2 "nonmemory_operand" "")))]
13222 "TARGET_QIMODE_MATH"
13223 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13225 (define_insn "*lshrqi3_1_one_bit"
13226 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13227 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13228 (match_operand:QI 2 "const1_operand" "")))
13229 (clobber (reg:CC FLAGS_REG))]
13230 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13231 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13233 [(set_attr "type" "ishift")
13234 (set_attr "length_immediate" "0")
13235 (set_attr "mode" "QI")])
13237 (define_insn "*lshrqi3_1_one_bit_slp"
13238 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13239 (lshiftrt:QI (match_dup 0)
13240 (match_operand:QI 1 "const1_operand" "")))
13241 (clobber (reg:CC FLAGS_REG))]
13242 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13243 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13245 [(set_attr "type" "ishift1")
13246 (set_attr "length_immediate" "0")
13247 (set_attr "mode" "QI")])
13249 (define_insn "*lshrqi3_1"
13250 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13251 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13252 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13253 (clobber (reg:CC FLAGS_REG))]
13254 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13256 shr{b}\t{%2, %0|%0, %2}
13257 shr{b}\t{%b2, %0|%0, %b2}"
13258 [(set_attr "type" "ishift")
13259 (set_attr "mode" "QI")])
13261 (define_insn "*lshrqi3_1_slp"
13262 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13263 (lshiftrt:QI (match_dup 0)
13264 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13265 (clobber (reg:CC FLAGS_REG))]
13266 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13267 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13269 shr{b}\t{%1, %0|%0, %1}
13270 shr{b}\t{%b1, %0|%0, %b1}"
13271 [(set_attr "type" "ishift1")
13272 (set_attr "mode" "QI")])
13274 ;; This pattern can't accept a variable shift count, since shifts by
13275 ;; zero don't affect the flags. We assume that shifts by constant
13276 ;; zero are optimized away.
13277 (define_insn "*lshrqi2_one_bit_cmp"
13278 [(set (reg FLAGS_REG)
13280 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13281 (match_operand:QI 2 "const1_operand" ""))
13283 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13284 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13285 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13286 && ix86_match_ccmode (insn, CCGOCmode)
13287 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13289 [(set_attr "type" "ishift")
13290 (set_attr "length_immediate" "0")
13291 (set_attr "mode" "QI")])
13293 (define_insn "*lshrqi2_one_bit_cconly"
13294 [(set (reg FLAGS_REG)
13296 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13297 (match_operand:QI 2 "const1_operand" ""))
13299 (clobber (match_scratch:QI 0 "=q"))]
13300 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13301 && ix86_match_ccmode (insn, CCGOCmode)
13302 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13304 [(set_attr "type" "ishift")
13305 (set_attr "length_immediate" "0")
13306 (set_attr "mode" "QI")])
13308 ;; This pattern can't accept a variable shift count, since shifts by
13309 ;; zero don't affect the flags. We assume that shifts by constant
13310 ;; zero are optimized away.
13311 (define_insn "*lshrqi2_cmp"
13312 [(set (reg FLAGS_REG)
13314 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13315 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13317 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13318 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13319 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13320 && ix86_match_ccmode (insn, CCGOCmode)
13321 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13322 "shr{b}\t{%2, %0|%0, %2}"
13323 [(set_attr "type" "ishift")
13324 (set_attr "mode" "QI")])
13326 (define_insn "*lshrqi2_cconly"
13327 [(set (reg FLAGS_REG)
13329 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13332 (clobber (match_scratch:QI 0 "=q"))]
13333 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13334 && ix86_match_ccmode (insn, CCGOCmode)
13335 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336 "shr{b}\t{%2, %0|%0, %2}"
13337 [(set_attr "type" "ishift")
13338 (set_attr "mode" "QI")])
13340 ;; Rotate instructions
13342 (define_expand "rotldi3"
13343 [(set (match_operand:DI 0 "shiftdi_operand" "")
13344 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13345 (match_operand:QI 2 "nonmemory_operand" "")))]
13350 ix86_expand_binary_operator (ROTATE, DImode, operands);
13353 if (!const_1_to_31_operand (operands[2], VOIDmode))
13355 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13359 ;; Implement rotation using two double-precision shift instructions
13360 ;; and a scratch register.
13361 (define_insn_and_split "ix86_rotldi3"
13362 [(set (match_operand:DI 0 "register_operand" "=r")
13363 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13364 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13365 (clobber (reg:CC FLAGS_REG))
13366 (clobber (match_scratch:SI 3 "=&r"))]
13369 "&& reload_completed"
13370 [(set (match_dup 3) (match_dup 4))
13372 [(set (match_dup 4)
13373 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13374 (lshiftrt:SI (match_dup 5)
13375 (minus:QI (const_int 32) (match_dup 2)))))
13376 (clobber (reg:CC FLAGS_REG))])
13378 [(set (match_dup 5)
13379 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13380 (lshiftrt:SI (match_dup 3)
13381 (minus:QI (const_int 32) (match_dup 2)))))
13382 (clobber (reg:CC FLAGS_REG))])]
13383 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13385 (define_insn "*rotlsi3_1_one_bit_rex64"
13386 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13387 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13388 (match_operand:QI 2 "const1_operand" "")))
13389 (clobber (reg:CC FLAGS_REG))]
13391 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13392 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13394 [(set_attr "type" "rotate")
13395 (set_attr "length_immediate" "0")
13396 (set_attr "mode" "DI")])
13398 (define_insn "*rotldi3_1_rex64"
13399 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13400 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13401 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13402 (clobber (reg:CC FLAGS_REG))]
13403 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13405 rol{q}\t{%2, %0|%0, %2}
13406 rol{q}\t{%b2, %0|%0, %b2}"
13407 [(set_attr "type" "rotate")
13408 (set_attr "mode" "DI")])
13410 (define_expand "rotlsi3"
13411 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13412 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13413 (match_operand:QI 2 "nonmemory_operand" "")))]
13415 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13417 (define_insn "*rotlsi3_1_one_bit"
13418 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13419 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13420 (match_operand:QI 2 "const1_operand" "")))
13421 (clobber (reg:CC FLAGS_REG))]
13422 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13425 [(set_attr "type" "rotate")
13426 (set_attr "length_immediate" "0")
13427 (set_attr "mode" "SI")])
13429 (define_insn "*rotlsi3_1_one_bit_zext"
13430 [(set (match_operand:DI 0 "register_operand" "=r")
13432 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13433 (match_operand:QI 2 "const1_operand" ""))))
13434 (clobber (reg:CC FLAGS_REG))]
13436 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13437 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13439 [(set_attr "type" "rotate")
13440 (set_attr "length_immediate" "0")
13441 (set_attr "mode" "SI")])
13443 (define_insn "*rotlsi3_1"
13444 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13445 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13446 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13447 (clobber (reg:CC FLAGS_REG))]
13448 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13450 rol{l}\t{%2, %0|%0, %2}
13451 rol{l}\t{%b2, %0|%0, %b2}"
13452 [(set_attr "type" "rotate")
13453 (set_attr "mode" "SI")])
13455 (define_insn "*rotlsi3_1_zext"
13456 [(set (match_operand:DI 0 "register_operand" "=r,r")
13458 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13459 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13460 (clobber (reg:CC FLAGS_REG))]
13461 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13463 rol{l}\t{%2, %k0|%k0, %2}
13464 rol{l}\t{%b2, %k0|%k0, %b2}"
13465 [(set_attr "type" "rotate")
13466 (set_attr "mode" "SI")])
13468 (define_expand "rotlhi3"
13469 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13470 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13471 (match_operand:QI 2 "nonmemory_operand" "")))]
13472 "TARGET_HIMODE_MATH"
13473 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13475 (define_insn "*rotlhi3_1_one_bit"
13476 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13477 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13478 (match_operand:QI 2 "const1_operand" "")))
13479 (clobber (reg:CC FLAGS_REG))]
13480 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13481 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13483 [(set_attr "type" "rotate")
13484 (set_attr "length_immediate" "0")
13485 (set_attr "mode" "HI")])
13487 (define_insn "*rotlhi3_1"
13488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13489 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13490 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13491 (clobber (reg:CC FLAGS_REG))]
13492 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13494 rol{w}\t{%2, %0|%0, %2}
13495 rol{w}\t{%b2, %0|%0, %b2}"
13496 [(set_attr "type" "rotate")
13497 (set_attr "mode" "HI")])
13500 [(set (match_operand:HI 0 "register_operand" "")
13501 (rotate:HI (match_dup 0) (const_int 8)))
13502 (clobber (reg:CC FLAGS_REG))]
13504 [(parallel [(set (strict_low_part (match_dup 0))
13505 (bswap:HI (match_dup 0)))
13506 (clobber (reg:CC FLAGS_REG))])]
13509 (define_expand "rotlqi3"
13510 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13511 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13512 (match_operand:QI 2 "nonmemory_operand" "")))]
13513 "TARGET_QIMODE_MATH"
13514 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13516 (define_insn "*rotlqi3_1_one_bit_slp"
13517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518 (rotate:QI (match_dup 0)
13519 (match_operand:QI 1 "const1_operand" "")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13524 [(set_attr "type" "rotate1")
13525 (set_attr "length_immediate" "0")
13526 (set_attr "mode" "QI")])
13528 (define_insn "*rotlqi3_1_one_bit"
13529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13530 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13531 (match_operand:QI 2 "const1_operand" "")))
13532 (clobber (reg:CC FLAGS_REG))]
13533 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13534 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13536 [(set_attr "type" "rotate")
13537 (set_attr "length_immediate" "0")
13538 (set_attr "mode" "QI")])
13540 (define_insn "*rotlqi3_1_slp"
13541 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13542 (rotate:QI (match_dup 0)
13543 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13544 (clobber (reg:CC FLAGS_REG))]
13545 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13546 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13548 rol{b}\t{%1, %0|%0, %1}
13549 rol{b}\t{%b1, %0|%0, %b1}"
13550 [(set_attr "type" "rotate1")
13551 (set_attr "mode" "QI")])
13553 (define_insn "*rotlqi3_1"
13554 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13555 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13556 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13560 rol{b}\t{%2, %0|%0, %2}
13561 rol{b}\t{%b2, %0|%0, %b2}"
13562 [(set_attr "type" "rotate")
13563 (set_attr "mode" "QI")])
13565 (define_expand "rotrdi3"
13566 [(set (match_operand:DI 0 "shiftdi_operand" "")
13567 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13568 (match_operand:QI 2 "nonmemory_operand" "")))]
13573 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13576 if (!const_1_to_31_operand (operands[2], VOIDmode))
13578 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13582 ;; Implement rotation using two double-precision shift instructions
13583 ;; and a scratch register.
13584 (define_insn_and_split "ix86_rotrdi3"
13585 [(set (match_operand:DI 0 "register_operand" "=r")
13586 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13587 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13588 (clobber (reg:CC FLAGS_REG))
13589 (clobber (match_scratch:SI 3 "=&r"))]
13592 "&& reload_completed"
13593 [(set (match_dup 3) (match_dup 4))
13595 [(set (match_dup 4)
13596 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13597 (ashift:SI (match_dup 5)
13598 (minus:QI (const_int 32) (match_dup 2)))))
13599 (clobber (reg:CC FLAGS_REG))])
13601 [(set (match_dup 5)
13602 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13603 (ashift:SI (match_dup 3)
13604 (minus:QI (const_int 32) (match_dup 2)))))
13605 (clobber (reg:CC FLAGS_REG))])]
13606 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13608 (define_insn "*rotrdi3_1_one_bit_rex64"
13609 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13610 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13611 (match_operand:QI 2 "const1_operand" "")))
13612 (clobber (reg:CC FLAGS_REG))]
13614 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13615 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13617 [(set_attr "type" "rotate")
13618 (set_attr "length_immediate" "0")
13619 (set_attr "mode" "DI")])
13621 (define_insn "*rotrdi3_1_rex64"
13622 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13623 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13624 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13625 (clobber (reg:CC FLAGS_REG))]
13626 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13628 ror{q}\t{%2, %0|%0, %2}
13629 ror{q}\t{%b2, %0|%0, %b2}"
13630 [(set_attr "type" "rotate")
13631 (set_attr "mode" "DI")])
13633 (define_expand "rotrsi3"
13634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13635 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13636 (match_operand:QI 2 "nonmemory_operand" "")))]
13638 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13640 (define_insn "*rotrsi3_1_one_bit"
13641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13642 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13643 (match_operand:QI 2 "const1_operand" "")))
13644 (clobber (reg:CC FLAGS_REG))]
13645 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13646 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13648 [(set_attr "type" "rotate")
13649 (set_attr "length_immediate" "0")
13650 (set_attr "mode" "SI")])
13652 (define_insn "*rotrsi3_1_one_bit_zext"
13653 [(set (match_operand:DI 0 "register_operand" "=r")
13655 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13656 (match_operand:QI 2 "const1_operand" ""))))
13657 (clobber (reg:CC FLAGS_REG))]
13659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13660 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13662 [(set_attr "type" "rotate")
13663 (set_attr "length_immediate" "0")
13664 (set_attr "mode" "SI")])
13666 (define_insn "*rotrsi3_1"
13667 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13668 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13669 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13670 (clobber (reg:CC FLAGS_REG))]
13671 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13673 ror{l}\t{%2, %0|%0, %2}
13674 ror{l}\t{%b2, %0|%0, %b2}"
13675 [(set_attr "type" "rotate")
13676 (set_attr "mode" "SI")])
13678 (define_insn "*rotrsi3_1_zext"
13679 [(set (match_operand:DI 0 "register_operand" "=r,r")
13681 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13682 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13683 (clobber (reg:CC FLAGS_REG))]
13684 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13686 ror{l}\t{%2, %k0|%k0, %2}
13687 ror{l}\t{%b2, %k0|%k0, %b2}"
13688 [(set_attr "type" "rotate")
13689 (set_attr "mode" "SI")])
13691 (define_expand "rotrhi3"
13692 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13693 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13694 (match_operand:QI 2 "nonmemory_operand" "")))]
13695 "TARGET_HIMODE_MATH"
13696 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13698 (define_insn "*rotrhi3_one_bit"
13699 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13700 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13701 (match_operand:QI 2 "const1_operand" "")))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13706 [(set_attr "type" "rotate")
13707 (set_attr "length_immediate" "0")
13708 (set_attr "mode" "HI")])
13710 (define_insn "*rotrhi3_1"
13711 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13712 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13713 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13714 (clobber (reg:CC FLAGS_REG))]
13715 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13717 ror{w}\t{%2, %0|%0, %2}
13718 ror{w}\t{%b2, %0|%0, %b2}"
13719 [(set_attr "type" "rotate")
13720 (set_attr "mode" "HI")])
13723 [(set (match_operand:HI 0 "register_operand" "")
13724 (rotatert:HI (match_dup 0) (const_int 8)))
13725 (clobber (reg:CC FLAGS_REG))]
13727 [(parallel [(set (strict_low_part (match_dup 0))
13728 (bswap:HI (match_dup 0)))
13729 (clobber (reg:CC FLAGS_REG))])]
13732 (define_expand "rotrqi3"
13733 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13734 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13735 (match_operand:QI 2 "nonmemory_operand" "")))]
13736 "TARGET_QIMODE_MATH"
13737 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13739 (define_insn "*rotrqi3_1_one_bit"
13740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13741 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13742 (match_operand:QI 2 "const1_operand" "")))
13743 (clobber (reg:CC FLAGS_REG))]
13744 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13745 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13747 [(set_attr "type" "rotate")
13748 (set_attr "length_immediate" "0")
13749 (set_attr "mode" "QI")])
13751 (define_insn "*rotrqi3_1_one_bit_slp"
13752 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13753 (rotatert:QI (match_dup 0)
13754 (match_operand:QI 1 "const1_operand" "")))
13755 (clobber (reg:CC FLAGS_REG))]
13756 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13757 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13759 [(set_attr "type" "rotate1")
13760 (set_attr "length_immediate" "0")
13761 (set_attr "mode" "QI")])
13763 (define_insn "*rotrqi3_1"
13764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13765 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13766 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13767 (clobber (reg:CC FLAGS_REG))]
13768 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13770 ror{b}\t{%2, %0|%0, %2}
13771 ror{b}\t{%b2, %0|%0, %b2}"
13772 [(set_attr "type" "rotate")
13773 (set_attr "mode" "QI")])
13775 (define_insn "*rotrqi3_1_slp"
13776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13777 (rotatert:QI (match_dup 0)
13778 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13779 (clobber (reg:CC FLAGS_REG))]
13780 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13783 ror{b}\t{%1, %0|%0, %1}
13784 ror{b}\t{%b1, %0|%0, %b1}"
13785 [(set_attr "type" "rotate1")
13786 (set_attr "mode" "QI")])
13788 ;; Bit set / bit test instructions
13790 (define_expand "extv"
13791 [(set (match_operand:SI 0 "register_operand" "")
13792 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13793 (match_operand:SI 2 "const8_operand" "")
13794 (match_operand:SI 3 "const8_operand" "")))]
13797 /* Handle extractions from %ah et al. */
13798 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13801 /* From mips.md: extract_bit_field doesn't verify that our source
13802 matches the predicate, so check it again here. */
13803 if (! ext_register_operand (operands[1], VOIDmode))
13807 (define_expand "extzv"
13808 [(set (match_operand:SI 0 "register_operand" "")
13809 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13810 (match_operand:SI 2 "const8_operand" "")
13811 (match_operand:SI 3 "const8_operand" "")))]
13814 /* Handle extractions from %ah et al. */
13815 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13818 /* From mips.md: extract_bit_field doesn't verify that our source
13819 matches the predicate, so check it again here. */
13820 if (! ext_register_operand (operands[1], VOIDmode))
13824 (define_expand "insv"
13825 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13826 (match_operand 1 "const8_operand" "")
13827 (match_operand 2 "const8_operand" ""))
13828 (match_operand 3 "register_operand" ""))]
13831 /* Handle insertions to %ah et al. */
13832 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13835 /* From mips.md: insert_bit_field doesn't verify that our source
13836 matches the predicate, so check it again here. */
13837 if (! ext_register_operand (operands[0], VOIDmode))
13841 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13843 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13848 ;; %%% bts, btr, btc, bt.
13849 ;; In general these instructions are *slow* when applied to memory,
13850 ;; since they enforce atomic operation. When applied to registers,
13851 ;; it depends on the cpu implementation. They're never faster than
13852 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13853 ;; no point. But in 64-bit, we can't hold the relevant immediates
13854 ;; within the instruction itself, so operating on bits in the high
13855 ;; 32-bits of a register becomes easier.
13857 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13858 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13859 ;; negdf respectively, so they can never be disabled entirely.
13861 (define_insn "*btsq"
13862 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13864 (match_operand:DI 1 "const_0_to_63_operand" ""))
13866 (clobber (reg:CC FLAGS_REG))]
13867 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13868 "bts{q}\t{%1, %0|%0, %1}"
13869 [(set_attr "type" "alu1")
13870 (set_attr "prefix_0f" "1")
13871 (set_attr "mode" "DI")])
13873 (define_insn "*btrq"
13874 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13876 (match_operand:DI 1 "const_0_to_63_operand" ""))
13878 (clobber (reg:CC FLAGS_REG))]
13879 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13880 "btr{q}\t{%1, %0|%0, %1}"
13881 [(set_attr "type" "alu1")
13882 (set_attr "prefix_0f" "1")
13883 (set_attr "mode" "DI")])
13885 (define_insn "*btcq"
13886 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13888 (match_operand:DI 1 "const_0_to_63_operand" ""))
13889 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13890 (clobber (reg:CC FLAGS_REG))]
13891 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13892 "btc{q}\t{%1, %0|%0, %1}"
13893 [(set_attr "type" "alu1")
13894 (set_attr "prefix_0f" "1")
13895 (set_attr "mode" "DI")])
13897 ;; Allow Nocona to avoid these instructions if a register is available.
13900 [(match_scratch:DI 2 "r")
13901 (parallel [(set (zero_extract:DI
13902 (match_operand:DI 0 "register_operand" "")
13904 (match_operand:DI 1 "const_0_to_63_operand" ""))
13906 (clobber (reg:CC FLAGS_REG))])]
13907 "TARGET_64BIT && !TARGET_USE_BT"
13910 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13913 if (HOST_BITS_PER_WIDE_INT >= 64)
13914 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13915 else if (i < HOST_BITS_PER_WIDE_INT)
13916 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13918 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13920 op1 = immed_double_const (lo, hi, DImode);
13923 emit_move_insn (operands[2], op1);
13927 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13932 [(match_scratch:DI 2 "r")
13933 (parallel [(set (zero_extract:DI
13934 (match_operand:DI 0 "register_operand" "")
13936 (match_operand:DI 1 "const_0_to_63_operand" ""))
13938 (clobber (reg:CC FLAGS_REG))])]
13939 "TARGET_64BIT && !TARGET_USE_BT"
13942 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13945 if (HOST_BITS_PER_WIDE_INT >= 64)
13946 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13947 else if (i < HOST_BITS_PER_WIDE_INT)
13948 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13950 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13952 op1 = immed_double_const (~lo, ~hi, DImode);
13955 emit_move_insn (operands[2], op1);
13959 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13964 [(match_scratch:DI 2 "r")
13965 (parallel [(set (zero_extract:DI
13966 (match_operand:DI 0 "register_operand" "")
13968 (match_operand:DI 1 "const_0_to_63_operand" ""))
13969 (not:DI (zero_extract:DI
13970 (match_dup 0) (const_int 1) (match_dup 1))))
13971 (clobber (reg:CC FLAGS_REG))])]
13972 "TARGET_64BIT && !TARGET_USE_BT"
13975 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13978 if (HOST_BITS_PER_WIDE_INT >= 64)
13979 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13980 else if (i < HOST_BITS_PER_WIDE_INT)
13981 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13983 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13985 op1 = immed_double_const (lo, hi, DImode);
13988 emit_move_insn (operands[2], op1);
13992 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13996 (define_insn "*btdi_rex64"
13997 [(set (reg:CCC FLAGS_REG)
14000 (match_operand:DI 0 "register_operand" "r")
14002 (match_operand:DI 1 "nonmemory_operand" "rN"))
14004 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14005 "bt{q}\t{%1, %0|%0, %1}"
14006 [(set_attr "type" "alu1")
14007 (set_attr "prefix_0f" "1")
14008 (set_attr "mode" "DI")])
14010 (define_insn "*btsi"
14011 [(set (reg:CCC FLAGS_REG)
14014 (match_operand:SI 0 "register_operand" "r")
14016 (match_operand:SI 1 "nonmemory_operand" "rN"))
14018 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14019 "bt{l}\t{%1, %0|%0, %1}"
14020 [(set_attr "type" "alu1")
14021 (set_attr "prefix_0f" "1")
14022 (set_attr "mode" "SI")])
14024 ;; Store-flag instructions.
14026 ;; For all sCOND expanders, also expand the compare or test insn that
14027 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14029 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14030 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14031 ;; way, which can later delete the movzx if only QImode is needed.
14033 (define_insn "*setcc_1"
14034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14035 (match_operator:QI 1 "ix86_comparison_operator"
14036 [(reg FLAGS_REG) (const_int 0)]))]
14039 [(set_attr "type" "setcc")
14040 (set_attr "mode" "QI")])
14042 (define_insn "*setcc_2"
14043 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14044 (match_operator:QI 1 "ix86_comparison_operator"
14045 [(reg FLAGS_REG) (const_int 0)]))]
14048 [(set_attr "type" "setcc")
14049 (set_attr "mode" "QI")])
14051 ;; In general it is not safe to assume too much about CCmode registers,
14052 ;; so simplify-rtx stops when it sees a second one. Under certain
14053 ;; conditions this is safe on x86, so help combine not create
14060 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14061 (ne:QI (match_operator 1 "ix86_comparison_operator"
14062 [(reg FLAGS_REG) (const_int 0)])
14065 [(set (match_dup 0) (match_dup 1))]
14067 PUT_MODE (operands[1], QImode);
14071 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14072 (ne:QI (match_operator 1 "ix86_comparison_operator"
14073 [(reg FLAGS_REG) (const_int 0)])
14076 [(set (match_dup 0) (match_dup 1))]
14078 PUT_MODE (operands[1], QImode);
14082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14083 (eq:QI (match_operator 1 "ix86_comparison_operator"
14084 [(reg FLAGS_REG) (const_int 0)])
14087 [(set (match_dup 0) (match_dup 1))]
14089 rtx new_op1 = copy_rtx (operands[1]);
14090 operands[1] = new_op1;
14091 PUT_MODE (new_op1, QImode);
14092 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14093 GET_MODE (XEXP (new_op1, 0))));
14095 /* Make sure that (a) the CCmode we have for the flags is strong
14096 enough for the reversed compare or (b) we have a valid FP compare. */
14097 if (! ix86_comparison_operator (new_op1, VOIDmode))
14102 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14103 (eq:QI (match_operator 1 "ix86_comparison_operator"
14104 [(reg FLAGS_REG) (const_int 0)])
14107 [(set (match_dup 0) (match_dup 1))]
14109 rtx new_op1 = copy_rtx (operands[1]);
14110 operands[1] = new_op1;
14111 PUT_MODE (new_op1, QImode);
14112 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14113 GET_MODE (XEXP (new_op1, 0))));
14115 /* Make sure that (a) the CCmode we have for the flags is strong
14116 enough for the reversed compare or (b) we have a valid FP compare. */
14117 if (! ix86_comparison_operator (new_op1, VOIDmode))
14121 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14122 ;; subsequent logical operations are used to imitate conditional moves.
14123 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14126 (define_insn "*avx_setcc<mode>"
14127 [(set (match_operand:MODEF 0 "register_operand" "=x")
14128 (match_operator:MODEF 1 "avx_comparison_float_operator"
14129 [(match_operand:MODEF 2 "register_operand" "x")
14130 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14132 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14133 [(set_attr "type" "ssecmp")
14134 (set_attr "prefix" "vex")
14135 (set_attr "length_immediate" "1")
14136 (set_attr "mode" "<MODE>")])
14138 (define_insn "*sse_setcc<mode>"
14139 [(set (match_operand:MODEF 0 "register_operand" "=x")
14140 (match_operator:MODEF 1 "sse_comparison_operator"
14141 [(match_operand:MODEF 2 "register_operand" "0")
14142 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14143 "SSE_FLOAT_MODE_P (<MODE>mode)"
14144 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14145 [(set_attr "type" "ssecmp")
14146 (set_attr "length_immediate" "1")
14147 (set_attr "mode" "<MODE>")])
14149 ;; Basic conditional jump instructions.
14150 ;; We ignore the overflow flag for signed branch instructions.
14152 (define_insn "*jcc_1"
14154 (if_then_else (match_operator 1 "ix86_comparison_operator"
14155 [(reg FLAGS_REG) (const_int 0)])
14156 (label_ref (match_operand 0 "" ""))
14160 [(set_attr "type" "ibr")
14161 (set_attr "modrm" "0")
14162 (set (attr "length")
14163 (if_then_else (and (ge (minus (match_dup 0) (pc))
14165 (lt (minus (match_dup 0) (pc))
14170 (define_insn "*jcc_2"
14172 (if_then_else (match_operator 1 "ix86_comparison_operator"
14173 [(reg FLAGS_REG) (const_int 0)])
14175 (label_ref (match_operand 0 "" ""))))]
14178 [(set_attr "type" "ibr")
14179 (set_attr "modrm" "0")
14180 (set (attr "length")
14181 (if_then_else (and (ge (minus (match_dup 0) (pc))
14183 (lt (minus (match_dup 0) (pc))
14188 ;; In general it is not safe to assume too much about CCmode registers,
14189 ;; so simplify-rtx stops when it sees a second one. Under certain
14190 ;; conditions this is safe on x86, so help combine not create
14198 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14199 [(reg FLAGS_REG) (const_int 0)])
14201 (label_ref (match_operand 1 "" ""))
14205 (if_then_else (match_dup 0)
14206 (label_ref (match_dup 1))
14209 PUT_MODE (operands[0], VOIDmode);
14214 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14215 [(reg FLAGS_REG) (const_int 0)])
14217 (label_ref (match_operand 1 "" ""))
14221 (if_then_else (match_dup 0)
14222 (label_ref (match_dup 1))
14225 rtx new_op0 = copy_rtx (operands[0]);
14226 operands[0] = new_op0;
14227 PUT_MODE (new_op0, VOIDmode);
14228 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14229 GET_MODE (XEXP (new_op0, 0))));
14231 /* Make sure that (a) the CCmode we have for the flags is strong
14232 enough for the reversed compare or (b) we have a valid FP compare. */
14233 if (! ix86_comparison_operator (new_op0, VOIDmode))
14237 ;; zero_extend in SImode is correct, since this is what combine pass
14238 ;; generates from shift insn with QImode operand. Actually, the mode of
14239 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14240 ;; appropriate modulo of the bit offset value.
14242 (define_insn_and_split "*jcc_btdi_rex64"
14244 (if_then_else (match_operator 0 "bt_comparison_operator"
14246 (match_operand:DI 1 "register_operand" "r")
14249 (match_operand:QI 2 "register_operand" "r")))
14251 (label_ref (match_operand 3 "" ""))
14253 (clobber (reg:CC FLAGS_REG))]
14254 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14257 [(set (reg:CCC FLAGS_REG)
14265 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14266 (label_ref (match_dup 3))
14269 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14271 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14274 ;; avoid useless masking of bit offset operand
14275 (define_insn_and_split "*jcc_btdi_mask_rex64"
14277 (if_then_else (match_operator 0 "bt_comparison_operator"
14279 (match_operand:DI 1 "register_operand" "r")
14282 (match_operand:SI 2 "register_operand" "r")
14283 (match_operand:SI 3 "const_int_operand" "n")))])
14284 (label_ref (match_operand 4 "" ""))
14286 (clobber (reg:CC FLAGS_REG))]
14287 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14288 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14291 [(set (reg:CCC FLAGS_REG)
14299 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14300 (label_ref (match_dup 4))
14303 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14305 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14308 (define_insn_and_split "*jcc_btsi"
14310 (if_then_else (match_operator 0 "bt_comparison_operator"
14312 (match_operand:SI 1 "register_operand" "r")
14315 (match_operand:QI 2 "register_operand" "r")))
14317 (label_ref (match_operand 3 "" ""))
14319 (clobber (reg:CC FLAGS_REG))]
14320 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14323 [(set (reg:CCC FLAGS_REG)
14331 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14332 (label_ref (match_dup 3))
14335 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14337 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14340 ;; avoid useless masking of bit offset operand
14341 (define_insn_and_split "*jcc_btsi_mask"
14343 (if_then_else (match_operator 0 "bt_comparison_operator"
14345 (match_operand:SI 1 "register_operand" "r")
14348 (match_operand:SI 2 "register_operand" "r")
14349 (match_operand:SI 3 "const_int_operand" "n")))])
14350 (label_ref (match_operand 4 "" ""))
14352 (clobber (reg:CC FLAGS_REG))]
14353 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14354 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14357 [(set (reg:CCC FLAGS_REG)
14365 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14366 (label_ref (match_dup 4))
14368 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14370 (define_insn_and_split "*jcc_btsi_1"
14372 (if_then_else (match_operator 0 "bt_comparison_operator"
14375 (match_operand:SI 1 "register_operand" "r")
14376 (match_operand:QI 2 "register_operand" "r"))
14379 (label_ref (match_operand 3 "" ""))
14381 (clobber (reg:CC FLAGS_REG))]
14382 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14385 [(set (reg:CCC FLAGS_REG)
14393 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14394 (label_ref (match_dup 3))
14397 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14399 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14402 ;; avoid useless masking of bit offset operand
14403 (define_insn_and_split "*jcc_btsi_mask_1"
14406 (match_operator 0 "bt_comparison_operator"
14409 (match_operand:SI 1 "register_operand" "r")
14412 (match_operand:SI 2 "register_operand" "r")
14413 (match_operand:SI 3 "const_int_operand" "n")) 0))
14416 (label_ref (match_operand 4 "" ""))
14418 (clobber (reg:CC FLAGS_REG))]
14419 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14420 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14423 [(set (reg:CCC FLAGS_REG)
14431 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14432 (label_ref (match_dup 4))
14434 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14436 ;; Define combination compare-and-branch fp compare instructions to help
14439 (define_insn "*fp_jcc_3_387"
14441 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14442 [(match_operand 1 "register_operand" "f")
14443 (match_operand 2 "nonimmediate_operand" "fm")])
14444 (label_ref (match_operand 3 "" ""))
14446 (clobber (reg:CCFP FPSR_REG))
14447 (clobber (reg:CCFP FLAGS_REG))
14448 (clobber (match_scratch:HI 4 "=a"))]
14450 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14451 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14452 && SELECT_CC_MODE (GET_CODE (operands[0]),
14453 operands[1], operands[2]) == CCFPmode
14457 (define_insn "*fp_jcc_4_387"
14459 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14460 [(match_operand 1 "register_operand" "f")
14461 (match_operand 2 "nonimmediate_operand" "fm")])
14463 (label_ref (match_operand 3 "" ""))))
14464 (clobber (reg:CCFP FPSR_REG))
14465 (clobber (reg:CCFP FLAGS_REG))
14466 (clobber (match_scratch:HI 4 "=a"))]
14468 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14469 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14470 && SELECT_CC_MODE (GET_CODE (operands[0]),
14471 operands[1], operands[2]) == CCFPmode
14475 (define_insn "*fp_jcc_5_387"
14477 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14478 [(match_operand 1 "register_operand" "f")
14479 (match_operand 2 "register_operand" "f")])
14480 (label_ref (match_operand 3 "" ""))
14482 (clobber (reg:CCFP FPSR_REG))
14483 (clobber (reg:CCFP FLAGS_REG))
14484 (clobber (match_scratch:HI 4 "=a"))]
14485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14486 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14490 (define_insn "*fp_jcc_6_387"
14492 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14493 [(match_operand 1 "register_operand" "f")
14494 (match_operand 2 "register_operand" "f")])
14496 (label_ref (match_operand 3 "" ""))))
14497 (clobber (reg:CCFP FPSR_REG))
14498 (clobber (reg:CCFP FLAGS_REG))
14499 (clobber (match_scratch:HI 4 "=a"))]
14500 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14501 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14505 (define_insn "*fp_jcc_7_387"
14507 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14508 [(match_operand 1 "register_operand" "f")
14509 (match_operand 2 "const0_operand" "")])
14510 (label_ref (match_operand 3 "" ""))
14512 (clobber (reg:CCFP FPSR_REG))
14513 (clobber (reg:CCFP FLAGS_REG))
14514 (clobber (match_scratch:HI 4 "=a"))]
14515 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14516 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14517 && SELECT_CC_MODE (GET_CODE (operands[0]),
14518 operands[1], operands[2]) == CCFPmode
14522 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14523 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14524 ;; with a precedence over other operators and is always put in the first
14525 ;; place. Swap condition and operands to match ficom instruction.
14527 (define_insn "*fp_jcc_8<mode>_387"
14529 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14530 [(match_operator 1 "float_operator"
14531 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14532 (match_operand 3 "register_operand" "f,f")])
14533 (label_ref (match_operand 4 "" ""))
14535 (clobber (reg:CCFP FPSR_REG))
14536 (clobber (reg:CCFP FLAGS_REG))
14537 (clobber (match_scratch:HI 5 "=a,a"))]
14538 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14539 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14540 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14541 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14547 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14548 [(match_operand 1 "register_operand" "")
14549 (match_operand 2 "nonimmediate_operand" "")])
14550 (match_operand 3 "" "")
14551 (match_operand 4 "" "")))
14552 (clobber (reg:CCFP FPSR_REG))
14553 (clobber (reg:CCFP FLAGS_REG))]
14557 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14558 operands[3], operands[4], NULL_RTX, NULL_RTX);
14564 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14565 [(match_operand 1 "register_operand" "")
14566 (match_operand 2 "general_operand" "")])
14567 (match_operand 3 "" "")
14568 (match_operand 4 "" "")))
14569 (clobber (reg:CCFP FPSR_REG))
14570 (clobber (reg:CCFP FLAGS_REG))
14571 (clobber (match_scratch:HI 5 "=a"))]
14575 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14576 operands[3], operands[4], operands[5], NULL_RTX);
14582 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14583 [(match_operator 1 "float_operator"
14584 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14585 (match_operand 3 "register_operand" "")])
14586 (match_operand 4 "" "")
14587 (match_operand 5 "" "")))
14588 (clobber (reg:CCFP FPSR_REG))
14589 (clobber (reg:CCFP FLAGS_REG))
14590 (clobber (match_scratch:HI 6 "=a"))]
14594 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14595 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14596 operands[3], operands[7],
14597 operands[4], operands[5], operands[6], NULL_RTX);
14601 ;; %%% Kill this when reload knows how to do it.
14604 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14605 [(match_operator 1 "float_operator"
14606 [(match_operand:X87MODEI12 2 "register_operand" "")])
14607 (match_operand 3 "register_operand" "")])
14608 (match_operand 4 "" "")
14609 (match_operand 5 "" "")))
14610 (clobber (reg:CCFP FPSR_REG))
14611 (clobber (reg:CCFP FLAGS_REG))
14612 (clobber (match_scratch:HI 6 "=a"))]
14616 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14617 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14618 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14619 operands[3], operands[7],
14620 operands[4], operands[5], operands[6], operands[2]);
14624 ;; Unconditional and other jump instructions
14626 (define_insn "jump"
14628 (label_ref (match_operand 0 "" "")))]
14631 [(set_attr "type" "ibr")
14632 (set (attr "length")
14633 (if_then_else (and (ge (minus (match_dup 0) (pc))
14635 (lt (minus (match_dup 0) (pc))
14639 (set_attr "modrm" "0")])
14641 (define_expand "indirect_jump"
14642 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14646 (define_insn "*indirect_jump"
14647 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14650 [(set_attr "type" "ibr")
14651 (set_attr "length_immediate" "0")])
14653 (define_expand "tablejump"
14654 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14655 (use (label_ref (match_operand 1 "" "")))])]
14658 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14659 relative. Convert the relative address to an absolute address. */
14663 enum rtx_code code;
14665 /* We can't use @GOTOFF for text labels on VxWorks;
14666 see gotoff_operand. */
14667 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14671 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14673 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14677 op1 = pic_offset_table_rtx;
14682 op0 = pic_offset_table_rtx;
14686 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14691 (define_insn "*tablejump_1"
14692 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14693 (use (label_ref (match_operand 1 "" "")))]
14696 [(set_attr "type" "ibr")
14697 (set_attr "length_immediate" "0")])
14699 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14702 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14703 (set (match_operand:QI 1 "register_operand" "")
14704 (match_operator:QI 2 "ix86_comparison_operator"
14705 [(reg FLAGS_REG) (const_int 0)]))
14706 (set (match_operand 3 "q_regs_operand" "")
14707 (zero_extend (match_dup 1)))]
14708 "(peep2_reg_dead_p (3, operands[1])
14709 || operands_match_p (operands[1], operands[3]))
14710 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14711 [(set (match_dup 4) (match_dup 0))
14712 (set (strict_low_part (match_dup 5))
14715 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14716 operands[5] = gen_lowpart (QImode, operands[3]);
14717 ix86_expand_clear (operands[3]);
14720 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14723 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14724 (set (match_operand:QI 1 "register_operand" "")
14725 (match_operator:QI 2 "ix86_comparison_operator"
14726 [(reg FLAGS_REG) (const_int 0)]))
14727 (parallel [(set (match_operand 3 "q_regs_operand" "")
14728 (zero_extend (match_dup 1)))
14729 (clobber (reg:CC FLAGS_REG))])]
14730 "(peep2_reg_dead_p (3, operands[1])
14731 || operands_match_p (operands[1], operands[3]))
14732 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14733 [(set (match_dup 4) (match_dup 0))
14734 (set (strict_low_part (match_dup 5))
14737 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14738 operands[5] = gen_lowpart (QImode, operands[3]);
14739 ix86_expand_clear (operands[3]);
14742 ;; Call instructions.
14744 ;; The predicates normally associated with named expanders are not properly
14745 ;; checked for calls. This is a bug in the generic code, but it isn't that
14746 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14748 ;; Call subroutine returning no value.
14750 (define_expand "call_pop"
14751 [(parallel [(call (match_operand:QI 0 "" "")
14752 (match_operand:SI 1 "" ""))
14753 (set (reg:SI SP_REG)
14754 (plus:SI (reg:SI SP_REG)
14755 (match_operand:SI 3 "" "")))])]
14758 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14762 (define_insn "*call_pop_0"
14763 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14764 (match_operand:SI 1 "" ""))
14765 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14766 (match_operand:SI 2 "immediate_operand" "")))]
14769 if (SIBLING_CALL_P (insn))
14772 return "call\t%P0";
14774 [(set_attr "type" "call")])
14776 (define_insn "*call_pop_1"
14777 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14778 (match_operand:SI 1 "" ""))
14779 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14780 (match_operand:SI 2 "immediate_operand" "i")))]
14781 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14783 if (constant_call_address_operand (operands[0], Pmode))
14784 return "call\t%P0";
14785 return "call\t%A0";
14787 [(set_attr "type" "call")])
14789 (define_insn "*sibcall_pop_1"
14790 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14791 (match_operand:SI 1 "" ""))
14792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14793 (match_operand:SI 2 "immediate_operand" "i,i")))]
14794 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14798 [(set_attr "type" "call")])
14800 (define_expand "call"
14801 [(call (match_operand:QI 0 "" "")
14802 (match_operand 1 "" ""))
14803 (use (match_operand 2 "" ""))]
14806 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14810 (define_expand "sibcall"
14811 [(call (match_operand:QI 0 "" "")
14812 (match_operand 1 "" ""))
14813 (use (match_operand 2 "" ""))]
14816 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14820 (define_insn "*call_0"
14821 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14822 (match_operand 1 "" ""))]
14825 if (SIBLING_CALL_P (insn))
14828 return "call\t%P0";
14830 [(set_attr "type" "call")])
14832 (define_insn "*call_1"
14833 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14834 (match_operand 1 "" ""))]
14835 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14837 if (constant_call_address_operand (operands[0], Pmode))
14838 return "call\t%P0";
14839 return "call\t%A0";
14841 [(set_attr "type" "call")])
14843 (define_insn "*sibcall_1"
14844 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14845 (match_operand 1 "" ""))]
14846 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14850 [(set_attr "type" "call")])
14852 (define_insn "*call_1_rex64"
14853 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14854 (match_operand 1 "" ""))]
14855 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14856 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14858 if (constant_call_address_operand (operands[0], Pmode))
14859 return "call\t%P0";
14860 return "call\t%A0";
14862 [(set_attr "type" "call")])
14864 (define_insn "*call_1_rex64_ms_sysv"
14865 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14866 (match_operand 1 "" ""))
14867 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14868 (clobber (reg:TI XMM6_REG))
14869 (clobber (reg:TI XMM7_REG))
14870 (clobber (reg:TI XMM8_REG))
14871 (clobber (reg:TI XMM9_REG))
14872 (clobber (reg:TI XMM10_REG))
14873 (clobber (reg:TI XMM11_REG))
14874 (clobber (reg:TI XMM12_REG))
14875 (clobber (reg:TI XMM13_REG))
14876 (clobber (reg:TI XMM14_REG))
14877 (clobber (reg:TI XMM15_REG))
14878 (clobber (reg:DI SI_REG))
14879 (clobber (reg:DI DI_REG))]
14880 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14882 if (constant_call_address_operand (operands[0], Pmode))
14883 return "call\t%P0";
14884 return "call\t%A0";
14886 [(set_attr "type" "call")])
14888 (define_insn "*call_1_rex64_large"
14889 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14890 (match_operand 1 "" ""))]
14891 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14893 [(set_attr "type" "call")])
14895 (define_insn "*sibcall_1_rex64"
14896 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14897 (match_operand 1 "" ""))]
14898 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14902 [(set_attr "type" "call")])
14904 ;; Call subroutine, returning value in operand 0
14905 (define_expand "call_value_pop"
14906 [(parallel [(set (match_operand 0 "" "")
14907 (call (match_operand:QI 1 "" "")
14908 (match_operand:SI 2 "" "")))
14909 (set (reg:SI SP_REG)
14910 (plus:SI (reg:SI SP_REG)
14911 (match_operand:SI 4 "" "")))])]
14914 ix86_expand_call (operands[0], operands[1], operands[2],
14915 operands[3], operands[4], 0);
14919 (define_expand "call_value"
14920 [(set (match_operand 0 "" "")
14921 (call (match_operand:QI 1 "" "")
14922 (match_operand:SI 2 "" "")))
14923 (use (match_operand:SI 3 "" ""))]
14924 ;; Operand 2 not used on the i386.
14927 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14931 (define_expand "sibcall_value"
14932 [(set (match_operand 0 "" "")
14933 (call (match_operand:QI 1 "" "")
14934 (match_operand:SI 2 "" "")))
14935 (use (match_operand:SI 3 "" ""))]
14936 ;; Operand 2 not used on the i386.
14939 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14943 ;; Call subroutine returning any type.
14945 (define_expand "untyped_call"
14946 [(parallel [(call (match_operand 0 "" "")
14948 (match_operand 1 "" "")
14949 (match_operand 2 "" "")])]
14954 /* In order to give reg-stack an easier job in validating two
14955 coprocessor registers as containing a possible return value,
14956 simply pretend the untyped call returns a complex long double
14959 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14960 and should have the default ABI. */
14962 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14963 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14964 operands[0], const0_rtx,
14965 GEN_INT ((TARGET_64BIT
14966 ? (ix86_abi == SYSV_ABI
14967 ? X86_64_SSE_REGPARM_MAX
14968 : X86_64_MS_SSE_REGPARM_MAX)
14969 : X86_32_SSE_REGPARM_MAX)
14973 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14975 rtx set = XVECEXP (operands[2], 0, i);
14976 emit_move_insn (SET_DEST (set), SET_SRC (set));
14979 /* The optimizer does not know that the call sets the function value
14980 registers we stored in the result block. We avoid problems by
14981 claiming that all hard registers are used and clobbered at this
14983 emit_insn (gen_blockage ());
14988 ;; Prologue and epilogue instructions
14990 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14991 ;; all of memory. This blocks insns from being moved across this point.
14993 (define_insn "blockage"
14994 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14997 [(set_attr "length" "0")])
14999 ;; Do not schedule instructions accessing memory across this point.
15001 (define_expand "memory_blockage"
15002 [(set (match_dup 0)
15003 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15006 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15007 MEM_VOLATILE_P (operands[0]) = 1;
15010 (define_insn "*memory_blockage"
15011 [(set (match_operand:BLK 0 "" "")
15012 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15015 [(set_attr "length" "0")])
15017 ;; As USE insns aren't meaningful after reload, this is used instead
15018 ;; to prevent deleting instructions setting registers for PIC code
15019 (define_insn "prologue_use"
15020 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15023 [(set_attr "length" "0")])
15025 ;; Insn emitted into the body of a function to return from a function.
15026 ;; This is only done if the function's epilogue is known to be simple.
15027 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15029 (define_expand "return"
15031 "ix86_can_use_return_insn_p ()"
15033 if (crtl->args.pops_args)
15035 rtx popc = GEN_INT (crtl->args.pops_args);
15036 emit_jump_insn (gen_return_pop_internal (popc));
15041 (define_insn "return_internal"
15045 [(set_attr "length" "1")
15046 (set_attr "atom_unit" "jeu")
15047 (set_attr "length_immediate" "0")
15048 (set_attr "modrm" "0")])
15050 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15051 ;; instruction Athlon and K8 have.
15053 (define_insn "return_internal_long"
15055 (unspec [(const_int 0)] UNSPEC_REP)]
15058 [(set_attr "length" "2")
15059 (set_attr "atom_unit" "jeu")
15060 (set_attr "length_immediate" "0")
15061 (set_attr "prefix_rep" "1")
15062 (set_attr "modrm" "0")])
15064 (define_insn "return_pop_internal"
15066 (use (match_operand:SI 0 "const_int_operand" ""))]
15069 [(set_attr "length" "3")
15070 (set_attr "atom_unit" "jeu")
15071 (set_attr "length_immediate" "2")
15072 (set_attr "modrm" "0")])
15074 (define_insn "return_indirect_internal"
15076 (use (match_operand:SI 0 "register_operand" "r"))]
15079 [(set_attr "type" "ibr")
15080 (set_attr "length_immediate" "0")])
15086 [(set_attr "length" "1")
15087 (set_attr "length_immediate" "0")
15088 (set_attr "modrm" "0")])
15090 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
15091 ;; branch prediction penalty for the third jump in a 16-byte
15095 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15098 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15099 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15101 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15102 The align insn is used to avoid 3 jump instructions in the row to improve
15103 branch prediction and the benefits hardly outweigh the cost of extra 8
15104 nops on the average inserted by full alignment pseudo operation. */
15108 [(set_attr "length" "16")])
15110 (define_expand "prologue"
15113 "ix86_expand_prologue (); DONE;")
15115 (define_insn "set_got"
15116 [(set (match_operand:SI 0 "register_operand" "=r")
15117 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15118 (clobber (reg:CC FLAGS_REG))]
15120 { return output_set_got (operands[0], NULL_RTX); }
15121 [(set_attr "type" "multi")
15122 (set_attr "length" "12")])
15124 (define_insn "set_got_labelled"
15125 [(set (match_operand:SI 0 "register_operand" "=r")
15126 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15128 (clobber (reg:CC FLAGS_REG))]
15130 { return output_set_got (operands[0], operands[1]); }
15131 [(set_attr "type" "multi")
15132 (set_attr "length" "12")])
15134 (define_insn "set_got_rex64"
15135 [(set (match_operand:DI 0 "register_operand" "=r")
15136 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15138 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15139 [(set_attr "type" "lea")
15140 (set_attr "length_address" "4")
15141 (set_attr "mode" "DI")])
15143 (define_insn "set_rip_rex64"
15144 [(set (match_operand:DI 0 "register_operand" "=r")
15145 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15147 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15148 [(set_attr "type" "lea")
15149 (set_attr "length_address" "4")
15150 (set_attr "mode" "DI")])
15152 (define_insn "set_got_offset_rex64"
15153 [(set (match_operand:DI 0 "register_operand" "=r")
15155 [(label_ref (match_operand 1 "" ""))]
15156 UNSPEC_SET_GOT_OFFSET))]
15158 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15159 [(set_attr "type" "imov")
15160 (set_attr "length_immediate" "0")
15161 (set_attr "length_address" "8")
15162 (set_attr "mode" "DI")])
15164 (define_expand "epilogue"
15167 "ix86_expand_epilogue (1); DONE;")
15169 (define_expand "sibcall_epilogue"
15172 "ix86_expand_epilogue (0); DONE;")
15174 (define_expand "eh_return"
15175 [(use (match_operand 0 "register_operand" ""))]
15178 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15180 /* Tricky bit: we write the address of the handler to which we will
15181 be returning into someone else's stack frame, one word below the
15182 stack address we wish to restore. */
15183 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15184 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15185 tmp = gen_rtx_MEM (Pmode, tmp);
15186 emit_move_insn (tmp, ra);
15188 emit_jump_insn (gen_eh_return_internal ());
15193 (define_insn_and_split "eh_return_internal"
15197 "epilogue_completed"
15199 "ix86_expand_epilogue (2); DONE;")
15201 (define_insn "leave"
15202 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15203 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15204 (clobber (mem:BLK (scratch)))]
15207 [(set_attr "type" "leave")])
15209 (define_insn "leave_rex64"
15210 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15211 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15212 (clobber (mem:BLK (scratch)))]
15215 [(set_attr "type" "leave")])
15217 (define_expand "ffssi2"
15219 [(set (match_operand:SI 0 "register_operand" "")
15220 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15221 (clobber (match_scratch:SI 2 ""))
15222 (clobber (reg:CC FLAGS_REG))])]
15227 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15232 (define_expand "ffs_cmove"
15233 [(set (match_dup 2) (const_int -1))
15234 (parallel [(set (reg:CCZ FLAGS_REG)
15235 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15237 (set (match_operand:SI 0 "register_operand" "")
15238 (ctz:SI (match_dup 1)))])
15239 (set (match_dup 0) (if_then_else:SI
15240 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15243 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15244 (clobber (reg:CC FLAGS_REG))])]
15246 "operands[2] = gen_reg_rtx (SImode);")
15248 (define_insn_and_split "*ffs_no_cmove"
15249 [(set (match_operand:SI 0 "register_operand" "=r")
15250 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15251 (clobber (match_scratch:SI 2 "=&q"))
15252 (clobber (reg:CC FLAGS_REG))]
15255 "&& reload_completed"
15256 [(parallel [(set (reg:CCZ FLAGS_REG)
15257 (compare:CCZ (match_dup 1) (const_int 0)))
15258 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15259 (set (strict_low_part (match_dup 3))
15260 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15261 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15262 (clobber (reg:CC FLAGS_REG))])
15263 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15264 (clobber (reg:CC FLAGS_REG))])
15265 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15266 (clobber (reg:CC FLAGS_REG))])]
15268 operands[3] = gen_lowpart (QImode, operands[2]);
15269 ix86_expand_clear (operands[2]);
15272 (define_insn "*ffssi_1"
15273 [(set (reg:CCZ FLAGS_REG)
15274 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15276 (set (match_operand:SI 0 "register_operand" "=r")
15277 (ctz:SI (match_dup 1)))]
15279 "bsf{l}\t{%1, %0|%0, %1}"
15280 [(set_attr "type" "alu1")
15281 (set_attr "prefix_0f" "1")
15282 (set_attr "mode" "SI")])
15284 (define_expand "ffsdi2"
15285 [(set (match_dup 2) (const_int -1))
15286 (parallel [(set (reg:CCZ FLAGS_REG)
15287 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15289 (set (match_operand:DI 0 "register_operand" "")
15290 (ctz:DI (match_dup 1)))])
15291 (set (match_dup 0) (if_then_else:DI
15292 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15295 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15296 (clobber (reg:CC FLAGS_REG))])]
15298 "operands[2] = gen_reg_rtx (DImode);")
15300 (define_insn "*ffsdi_1"
15301 [(set (reg:CCZ FLAGS_REG)
15302 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15304 (set (match_operand:DI 0 "register_operand" "=r")
15305 (ctz:DI (match_dup 1)))]
15307 "bsf{q}\t{%1, %0|%0, %1}"
15308 [(set_attr "type" "alu1")
15309 (set_attr "prefix_0f" "1")
15310 (set_attr "mode" "DI")])
15312 (define_insn "ctzsi2"
15313 [(set (match_operand:SI 0 "register_operand" "=r")
15314 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15315 (clobber (reg:CC FLAGS_REG))]
15317 "bsf{l}\t{%1, %0|%0, %1}"
15318 [(set_attr "type" "alu1")
15319 (set_attr "prefix_0f" "1")
15320 (set_attr "mode" "SI")])
15322 (define_insn "ctzdi2"
15323 [(set (match_operand:DI 0 "register_operand" "=r")
15324 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15325 (clobber (reg:CC FLAGS_REG))]
15327 "bsf{q}\t{%1, %0|%0, %1}"
15328 [(set_attr "type" "alu1")
15329 (set_attr "prefix_0f" "1")
15330 (set_attr "mode" "DI")])
15332 (define_expand "clzsi2"
15334 [(set (match_operand:SI 0 "register_operand" "")
15335 (minus:SI (const_int 31)
15336 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15337 (clobber (reg:CC FLAGS_REG))])
15339 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15340 (clobber (reg:CC FLAGS_REG))])]
15345 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15350 (define_insn "clzsi2_abm"
15351 [(set (match_operand:SI 0 "register_operand" "=r")
15352 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15353 (clobber (reg:CC FLAGS_REG))]
15355 "lzcnt{l}\t{%1, %0|%0, %1}"
15356 [(set_attr "prefix_rep" "1")
15357 (set_attr "type" "bitmanip")
15358 (set_attr "mode" "SI")])
15361 [(set (match_operand:SI 0 "register_operand" "=r")
15362 (minus:SI (const_int 31)
15363 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15364 (clobber (reg:CC FLAGS_REG))]
15366 "bsr{l}\t{%1, %0|%0, %1}"
15367 [(set_attr "type" "alu1")
15368 (set_attr "prefix_0f" "1")
15369 (set_attr "mode" "SI")])
15371 (define_insn "popcount<mode>2"
15372 [(set (match_operand:SWI248 0 "register_operand" "=r")
15374 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15375 (clobber (reg:CC FLAGS_REG))]
15379 return "popcnt\t{%1, %0|%0, %1}";
15381 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15384 [(set_attr "prefix_rep" "1")
15385 (set_attr "type" "bitmanip")
15386 (set_attr "mode" "<MODE>")])
15388 (define_insn "*popcount<mode>2_cmp"
15389 [(set (reg FLAGS_REG)
15392 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15394 (set (match_operand:SWI248 0 "register_operand" "=r")
15395 (popcount:SWI248 (match_dup 1)))]
15396 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15399 return "popcnt\t{%1, %0|%0, %1}";
15401 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15404 [(set_attr "prefix_rep" "1")
15405 (set_attr "type" "bitmanip")
15406 (set_attr "mode" "<MODE>")])
15408 (define_insn "*popcountsi2_cmp_zext"
15409 [(set (reg FLAGS_REG)
15411 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15413 (set (match_operand:DI 0 "register_operand" "=r")
15414 (zero_extend:DI(popcount:SI (match_dup 1))))]
15415 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15418 return "popcnt\t{%1, %0|%0, %1}";
15420 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15423 [(set_attr "prefix_rep" "1")
15424 (set_attr "type" "bitmanip")
15425 (set_attr "mode" "SI")])
15427 (define_expand "bswapsi2"
15428 [(set (match_operand:SI 0 "register_operand" "")
15429 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15432 if (!(TARGET_BSWAP || TARGET_MOVBE))
15434 rtx x = operands[0];
15436 emit_move_insn (x, operands[1]);
15437 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15438 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15439 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15444 (define_insn "*bswapsi_movbe"
15445 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
15446 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
15447 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15450 movbe\t{%1, %0|%0, %1}
15451 movbe\t{%1, %0|%0, %1}"
15452 [(set_attr "type" "*,imov,imov")
15453 (set_attr "modrm" "*,1,1")
15454 (set_attr "prefix_0f" "1")
15455 (set_attr "prefix_extra" "*,1,1")
15456 (set_attr "length" "2,*,*")
15457 (set_attr "mode" "SI")])
15459 (define_insn "*bswapsi_1"
15460 [(set (match_operand:SI 0 "register_operand" "=r")
15461 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15464 [(set_attr "prefix_0f" "1")
15465 (set_attr "length" "2")])
15467 (define_insn "*bswaphi_lowpart_1"
15468 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15469 (bswap:HI (match_dup 0)))
15470 (clobber (reg:CC FLAGS_REG))]
15471 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15473 xchg{b}\t{%h0, %b0|%b0, %h0}
15474 rol{w}\t{$8, %0|%0, 8}"
15475 [(set_attr "length" "2,4")
15476 (set_attr "mode" "QI,HI")])
15478 (define_insn "bswaphi_lowpart"
15479 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15480 (bswap:HI (match_dup 0)))
15481 (clobber (reg:CC FLAGS_REG))]
15483 "rol{w}\t{$8, %0|%0, 8}"
15484 [(set_attr "length" "4")
15485 (set_attr "mode" "HI")])
15487 (define_expand "bswapdi2"
15488 [(set (match_operand:DI 0 "register_operand" "")
15489 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
15493 (define_insn "*bswapdi_movbe"
15494 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
15495 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
15496 "TARGET_64BIT && TARGET_MOVBE
15497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15500 movbe\t{%1, %0|%0, %1}
15501 movbe\t{%1, %0|%0, %1}"
15502 [(set_attr "type" "*,imov,imov")
15503 (set_attr "modrm" "*,1,1")
15504 (set_attr "prefix_0f" "1")
15505 (set_attr "prefix_extra" "*,1,1")
15506 (set_attr "length" "3,*,*")
15507 (set_attr "mode" "DI")])
15509 (define_insn "*bswapdi_1"
15510 [(set (match_operand:DI 0 "register_operand" "=r")
15511 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15514 [(set_attr "prefix_0f" "1")
15515 (set_attr "length" "3")])
15517 (define_expand "clzdi2"
15519 [(set (match_operand:DI 0 "register_operand" "")
15520 (minus:DI (const_int 63)
15521 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15522 (clobber (reg:CC FLAGS_REG))])
15524 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15525 (clobber (reg:CC FLAGS_REG))])]
15530 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15535 (define_insn "clzdi2_abm"
15536 [(set (match_operand:DI 0 "register_operand" "=r")
15537 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15538 (clobber (reg:CC FLAGS_REG))]
15539 "TARGET_64BIT && TARGET_ABM"
15540 "lzcnt{q}\t{%1, %0|%0, %1}"
15541 [(set_attr "prefix_rep" "1")
15542 (set_attr "type" "bitmanip")
15543 (set_attr "mode" "DI")])
15545 (define_insn "bsr_rex64"
15546 [(set (match_operand:DI 0 "register_operand" "=r")
15547 (minus:DI (const_int 63)
15548 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15549 (clobber (reg:CC FLAGS_REG))]
15551 "bsr{q}\t{%1, %0|%0, %1}"
15552 [(set_attr "type" "alu1")
15553 (set_attr "prefix_0f" "1")
15554 (set_attr "mode" "DI")])
15556 (define_expand "clzhi2"
15558 [(set (match_operand:HI 0 "register_operand" "")
15559 (minus:HI (const_int 15)
15560 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15561 (clobber (reg:CC FLAGS_REG))])
15563 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15564 (clobber (reg:CC FLAGS_REG))])]
15569 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15574 (define_insn "clzhi2_abm"
15575 [(set (match_operand:HI 0 "register_operand" "=r")
15576 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15577 (clobber (reg:CC FLAGS_REG))]
15579 "lzcnt{w}\t{%1, %0|%0, %1}"
15580 [(set_attr "prefix_rep" "1")
15581 (set_attr "type" "bitmanip")
15582 (set_attr "mode" "HI")])
15584 (define_insn "*bsrhi"
15585 [(set (match_operand:HI 0 "register_operand" "=r")
15586 (minus:HI (const_int 15)
15587 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15588 (clobber (reg:CC FLAGS_REG))]
15590 "bsr{w}\t{%1, %0|%0, %1}"
15591 [(set_attr "type" "alu1")
15592 (set_attr "prefix_0f" "1")
15593 (set_attr "mode" "HI")])
15595 (define_expand "paritydi2"
15596 [(set (match_operand:DI 0 "register_operand" "")
15597 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15600 rtx scratch = gen_reg_rtx (QImode);
15603 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15604 NULL_RTX, operands[1]));
15606 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15607 gen_rtx_REG (CCmode, FLAGS_REG),
15609 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15612 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15615 rtx tmp = gen_reg_rtx (SImode);
15617 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15618 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15623 (define_insn_and_split "paritydi2_cmp"
15624 [(set (reg:CC FLAGS_REG)
15625 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15626 (clobber (match_scratch:DI 0 "=r"))
15627 (clobber (match_scratch:SI 1 "=&r"))
15628 (clobber (match_scratch:HI 2 "=Q"))]
15631 "&& reload_completed"
15633 [(set (match_dup 1)
15634 (xor:SI (match_dup 1) (match_dup 4)))
15635 (clobber (reg:CC FLAGS_REG))])
15637 [(set (reg:CC FLAGS_REG)
15638 (parity:CC (match_dup 1)))
15639 (clobber (match_dup 1))
15640 (clobber (match_dup 2))])]
15642 operands[4] = gen_lowpart (SImode, operands[3]);
15646 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15647 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15650 operands[1] = gen_highpart (SImode, operands[3]);
15653 (define_expand "paritysi2"
15654 [(set (match_operand:SI 0 "register_operand" "")
15655 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15658 rtx scratch = gen_reg_rtx (QImode);
15661 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15663 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15664 gen_rtx_REG (CCmode, FLAGS_REG),
15666 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15668 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15672 (define_insn_and_split "paritysi2_cmp"
15673 [(set (reg:CC FLAGS_REG)
15674 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15675 (clobber (match_scratch:SI 0 "=r"))
15676 (clobber (match_scratch:HI 1 "=&Q"))]
15679 "&& reload_completed"
15681 [(set (match_dup 1)
15682 (xor:HI (match_dup 1) (match_dup 3)))
15683 (clobber (reg:CC FLAGS_REG))])
15685 [(set (reg:CC FLAGS_REG)
15686 (parity:CC (match_dup 1)))
15687 (clobber (match_dup 1))])]
15689 operands[3] = gen_lowpart (HImode, operands[2]);
15691 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15692 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15695 (define_insn "*parityhi2_cmp"
15696 [(set (reg:CC FLAGS_REG)
15697 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15698 (clobber (match_scratch:HI 0 "=Q"))]
15700 "xor{b}\t{%h0, %b0|%b0, %h0}"
15701 [(set_attr "length" "2")
15702 (set_attr "mode" "HI")])
15704 (define_insn "*parityqi2_cmp"
15705 [(set (reg:CC FLAGS_REG)
15706 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15709 [(set_attr "length" "2")
15710 (set_attr "mode" "QI")])
15712 ;; Thread-local storage patterns for ELF.
15714 ;; Note that these code sequences must appear exactly as shown
15715 ;; in order to allow linker relaxation.
15717 (define_insn "*tls_global_dynamic_32_gnu"
15718 [(set (match_operand:SI 0 "register_operand" "=a")
15719 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15720 (match_operand:SI 2 "tls_symbolic_operand" "")
15721 (match_operand:SI 3 "call_insn_operand" "")]
15723 (clobber (match_scratch:SI 4 "=d"))
15724 (clobber (match_scratch:SI 5 "=c"))
15725 (clobber (reg:CC FLAGS_REG))]
15726 "!TARGET_64BIT && TARGET_GNU_TLS"
15727 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15728 [(set_attr "type" "multi")
15729 (set_attr "length" "12")])
15731 (define_insn "*tls_global_dynamic_32_sun"
15732 [(set (match_operand:SI 0 "register_operand" "=a")
15733 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15734 (match_operand:SI 2 "tls_symbolic_operand" "")
15735 (match_operand:SI 3 "call_insn_operand" "")]
15737 (clobber (match_scratch:SI 4 "=d"))
15738 (clobber (match_scratch:SI 5 "=c"))
15739 (clobber (reg:CC FLAGS_REG))]
15740 "!TARGET_64BIT && TARGET_SUN_TLS"
15741 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15742 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15743 [(set_attr "type" "multi")
15744 (set_attr "length" "14")])
15746 (define_expand "tls_global_dynamic_32"
15747 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15750 (match_operand:SI 1 "tls_symbolic_operand" "")
15753 (clobber (match_scratch:SI 4 ""))
15754 (clobber (match_scratch:SI 5 ""))
15755 (clobber (reg:CC FLAGS_REG))])]
15759 operands[2] = pic_offset_table_rtx;
15762 operands[2] = gen_reg_rtx (Pmode);
15763 emit_insn (gen_set_got (operands[2]));
15765 if (TARGET_GNU2_TLS)
15767 emit_insn (gen_tls_dynamic_gnu2_32
15768 (operands[0], operands[1], operands[2]));
15771 operands[3] = ix86_tls_get_addr ();
15774 (define_insn "*tls_global_dynamic_64"
15775 [(set (match_operand:DI 0 "register_operand" "=a")
15776 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15777 (match_operand:DI 3 "" "")))
15778 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15781 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15782 [(set_attr "type" "multi")
15783 (set_attr "length" "16")])
15785 (define_expand "tls_global_dynamic_64"
15786 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15787 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15788 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15792 if (TARGET_GNU2_TLS)
15794 emit_insn (gen_tls_dynamic_gnu2_64
15795 (operands[0], operands[1]));
15798 operands[2] = ix86_tls_get_addr ();
15801 (define_insn "*tls_local_dynamic_base_32_gnu"
15802 [(set (match_operand:SI 0 "register_operand" "=a")
15803 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15804 (match_operand:SI 2 "call_insn_operand" "")]
15805 UNSPEC_TLS_LD_BASE))
15806 (clobber (match_scratch:SI 3 "=d"))
15807 (clobber (match_scratch:SI 4 "=c"))
15808 (clobber (reg:CC FLAGS_REG))]
15809 "!TARGET_64BIT && TARGET_GNU_TLS"
15810 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15811 [(set_attr "type" "multi")
15812 (set_attr "length" "11")])
15814 (define_insn "*tls_local_dynamic_base_32_sun"
15815 [(set (match_operand:SI 0 "register_operand" "=a")
15816 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15817 (match_operand:SI 2 "call_insn_operand" "")]
15818 UNSPEC_TLS_LD_BASE))
15819 (clobber (match_scratch:SI 3 "=d"))
15820 (clobber (match_scratch:SI 4 "=c"))
15821 (clobber (reg:CC FLAGS_REG))]
15822 "!TARGET_64BIT && TARGET_SUN_TLS"
15823 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15824 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15825 [(set_attr "type" "multi")
15826 (set_attr "length" "13")])
15828 (define_expand "tls_local_dynamic_base_32"
15829 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15830 (unspec:SI [(match_dup 1) (match_dup 2)]
15831 UNSPEC_TLS_LD_BASE))
15832 (clobber (match_scratch:SI 3 ""))
15833 (clobber (match_scratch:SI 4 ""))
15834 (clobber (reg:CC FLAGS_REG))])]
15838 operands[1] = pic_offset_table_rtx;
15841 operands[1] = gen_reg_rtx (Pmode);
15842 emit_insn (gen_set_got (operands[1]));
15844 if (TARGET_GNU2_TLS)
15846 emit_insn (gen_tls_dynamic_gnu2_32
15847 (operands[0], ix86_tls_module_base (), operands[1]));
15850 operands[2] = ix86_tls_get_addr ();
15853 (define_insn "*tls_local_dynamic_base_64"
15854 [(set (match_operand:DI 0 "register_operand" "=a")
15855 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15856 (match_operand:DI 2 "" "")))
15857 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15859 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15860 [(set_attr "type" "multi")
15861 (set_attr "length" "12")])
15863 (define_expand "tls_local_dynamic_base_64"
15864 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15865 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15866 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15869 if (TARGET_GNU2_TLS)
15871 emit_insn (gen_tls_dynamic_gnu2_64
15872 (operands[0], ix86_tls_module_base ()));
15875 operands[1] = ix86_tls_get_addr ();
15878 ;; Local dynamic of a single variable is a lose. Show combine how
15879 ;; to convert that back to global dynamic.
15881 (define_insn_and_split "*tls_local_dynamic_32_once"
15882 [(set (match_operand:SI 0 "register_operand" "=a")
15883 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15884 (match_operand:SI 2 "call_insn_operand" "")]
15885 UNSPEC_TLS_LD_BASE)
15886 (const:SI (unspec:SI
15887 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15889 (clobber (match_scratch:SI 4 "=d"))
15890 (clobber (match_scratch:SI 5 "=c"))
15891 (clobber (reg:CC FLAGS_REG))]
15895 [(parallel [(set (match_dup 0)
15896 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15898 (clobber (match_dup 4))
15899 (clobber (match_dup 5))
15900 (clobber (reg:CC FLAGS_REG))])]
15903 ;; Load and add the thread base pointer from %gs:0.
15905 (define_insn "*load_tp_si"
15906 [(set (match_operand:SI 0 "register_operand" "=r")
15907 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15909 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15910 [(set_attr "type" "imov")
15911 (set_attr "modrm" "0")
15912 (set_attr "length" "7")
15913 (set_attr "memory" "load")
15914 (set_attr "imm_disp" "false")])
15916 (define_insn "*add_tp_si"
15917 [(set (match_operand:SI 0 "register_operand" "=r")
15918 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15919 (match_operand:SI 1 "register_operand" "0")))
15920 (clobber (reg:CC FLAGS_REG))]
15922 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15923 [(set_attr "type" "alu")
15924 (set_attr "modrm" "0")
15925 (set_attr "length" "7")
15926 (set_attr "memory" "load")
15927 (set_attr "imm_disp" "false")])
15929 (define_insn "*load_tp_di"
15930 [(set (match_operand:DI 0 "register_operand" "=r")
15931 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15933 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15934 [(set_attr "type" "imov")
15935 (set_attr "modrm" "0")
15936 (set_attr "length" "7")
15937 (set_attr "memory" "load")
15938 (set_attr "imm_disp" "false")])
15940 (define_insn "*add_tp_di"
15941 [(set (match_operand:DI 0 "register_operand" "=r")
15942 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15943 (match_operand:DI 1 "register_operand" "0")))
15944 (clobber (reg:CC FLAGS_REG))]
15946 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15947 [(set_attr "type" "alu")
15948 (set_attr "modrm" "0")
15949 (set_attr "length" "7")
15950 (set_attr "memory" "load")
15951 (set_attr "imm_disp" "false")])
15953 ;; GNU2 TLS patterns can be split.
15955 (define_expand "tls_dynamic_gnu2_32"
15956 [(set (match_dup 3)
15957 (plus:SI (match_operand:SI 2 "register_operand" "")
15959 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15962 [(set (match_operand:SI 0 "register_operand" "")
15963 (unspec:SI [(match_dup 1) (match_dup 3)
15964 (match_dup 2) (reg:SI SP_REG)]
15966 (clobber (reg:CC FLAGS_REG))])]
15967 "!TARGET_64BIT && TARGET_GNU2_TLS"
15969 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15970 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15973 (define_insn "*tls_dynamic_lea_32"
15974 [(set (match_operand:SI 0 "register_operand" "=r")
15975 (plus:SI (match_operand:SI 1 "register_operand" "b")
15977 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15978 UNSPEC_TLSDESC))))]
15979 "!TARGET_64BIT && TARGET_GNU2_TLS"
15980 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15981 [(set_attr "type" "lea")
15982 (set_attr "mode" "SI")
15983 (set_attr "length" "6")
15984 (set_attr "length_address" "4")])
15986 (define_insn "*tls_dynamic_call_32"
15987 [(set (match_operand:SI 0 "register_operand" "=a")
15988 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15989 (match_operand:SI 2 "register_operand" "0")
15990 ;; we have to make sure %ebx still points to the GOT
15991 (match_operand:SI 3 "register_operand" "b")
15994 (clobber (reg:CC FLAGS_REG))]
15995 "!TARGET_64BIT && TARGET_GNU2_TLS"
15996 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15997 [(set_attr "type" "call")
15998 (set_attr "length" "2")
15999 (set_attr "length_address" "0")])
16001 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16002 [(set (match_operand:SI 0 "register_operand" "=&a")
16004 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16005 (match_operand:SI 4 "" "")
16006 (match_operand:SI 2 "register_operand" "b")
16009 (const:SI (unspec:SI
16010 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16012 (clobber (reg:CC FLAGS_REG))]
16013 "!TARGET_64BIT && TARGET_GNU2_TLS"
16016 [(set (match_dup 0) (match_dup 5))]
16018 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16019 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16022 (define_expand "tls_dynamic_gnu2_64"
16023 [(set (match_dup 2)
16024 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16027 [(set (match_operand:DI 0 "register_operand" "")
16028 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16030 (clobber (reg:CC FLAGS_REG))])]
16031 "TARGET_64BIT && TARGET_GNU2_TLS"
16033 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16034 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16037 (define_insn "*tls_dynamic_lea_64"
16038 [(set (match_operand:DI 0 "register_operand" "=r")
16039 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16041 "TARGET_64BIT && TARGET_GNU2_TLS"
16042 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16043 [(set_attr "type" "lea")
16044 (set_attr "mode" "DI")
16045 (set_attr "length" "7")
16046 (set_attr "length_address" "4")])
16048 (define_insn "*tls_dynamic_call_64"
16049 [(set (match_operand:DI 0 "register_operand" "=a")
16050 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16051 (match_operand:DI 2 "register_operand" "0")
16054 (clobber (reg:CC FLAGS_REG))]
16055 "TARGET_64BIT && TARGET_GNU2_TLS"
16056 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16057 [(set_attr "type" "call")
16058 (set_attr "length" "2")
16059 (set_attr "length_address" "0")])
16061 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16062 [(set (match_operand:DI 0 "register_operand" "=&a")
16064 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16065 (match_operand:DI 3 "" "")
16068 (const:DI (unspec:DI
16069 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16071 (clobber (reg:CC FLAGS_REG))]
16072 "TARGET_64BIT && TARGET_GNU2_TLS"
16075 [(set (match_dup 0) (match_dup 4))]
16077 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16078 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16083 ;; These patterns match the binary 387 instructions for addM3, subM3,
16084 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16085 ;; SFmode. The first is the normal insn, the second the same insn but
16086 ;; with one operand a conversion, and the third the same insn but with
16087 ;; the other operand a conversion. The conversion may be SFmode or
16088 ;; SImode if the target mode DFmode, but only SImode if the target mode
16091 ;; Gcc is slightly more smart about handling normal two address instructions
16092 ;; so use special patterns for add and mull.
16094 (define_insn "*fop_<mode>_comm_mixed_avx"
16095 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16096 (match_operator:MODEF 3 "binary_fp_operator"
16097 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16098 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16099 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16100 && COMMUTATIVE_ARITH_P (operands[3])
16101 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16102 "* return output_387_binary_op (insn, operands);"
16103 [(set (attr "type")
16104 (if_then_else (eq_attr "alternative" "1")
16105 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16106 (const_string "ssemul")
16107 (const_string "sseadd"))
16108 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16109 (const_string "fmul")
16110 (const_string "fop"))))
16111 (set_attr "prefix" "orig,maybe_vex")
16112 (set_attr "mode" "<MODE>")])
16114 (define_insn "*fop_<mode>_comm_mixed"
16115 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16116 (match_operator:MODEF 3 "binary_fp_operator"
16117 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16118 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16119 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16120 && COMMUTATIVE_ARITH_P (operands[3])
16121 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16122 "* return output_387_binary_op (insn, operands);"
16123 [(set (attr "type")
16124 (if_then_else (eq_attr "alternative" "1")
16125 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16126 (const_string "ssemul")
16127 (const_string "sseadd"))
16128 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16129 (const_string "fmul")
16130 (const_string "fop"))))
16131 (set_attr "mode" "<MODE>")])
16133 (define_insn "*fop_<mode>_comm_avx"
16134 [(set (match_operand:MODEF 0 "register_operand" "=x")
16135 (match_operator:MODEF 3 "binary_fp_operator"
16136 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16137 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16138 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16139 && COMMUTATIVE_ARITH_P (operands[3])
16140 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16141 "* return output_387_binary_op (insn, operands);"
16142 [(set (attr "type")
16143 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16144 (const_string "ssemul")
16145 (const_string "sseadd")))
16146 (set_attr "prefix" "vex")
16147 (set_attr "mode" "<MODE>")])
16149 (define_insn "*fop_<mode>_comm_sse"
16150 [(set (match_operand:MODEF 0 "register_operand" "=x")
16151 (match_operator:MODEF 3 "binary_fp_operator"
16152 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16153 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16154 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16155 && COMMUTATIVE_ARITH_P (operands[3])
16156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16157 "* return output_387_binary_op (insn, operands);"
16158 [(set (attr "type")
16159 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16160 (const_string "ssemul")
16161 (const_string "sseadd")))
16162 (set_attr "mode" "<MODE>")])
16164 (define_insn "*fop_<mode>_comm_i387"
16165 [(set (match_operand:MODEF 0 "register_operand" "=f")
16166 (match_operator:MODEF 3 "binary_fp_operator"
16167 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16168 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16169 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16170 && COMMUTATIVE_ARITH_P (operands[3])
16171 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16172 "* return output_387_binary_op (insn, operands);"
16173 [(set (attr "type")
16174 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16175 (const_string "fmul")
16176 (const_string "fop")))
16177 (set_attr "mode" "<MODE>")])
16179 (define_insn "*fop_<mode>_1_mixed_avx"
16180 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16181 (match_operator:MODEF 3 "binary_fp_operator"
16182 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16183 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16184 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16185 && !COMMUTATIVE_ARITH_P (operands[3])
16186 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16187 "* return output_387_binary_op (insn, operands);"
16188 [(set (attr "type")
16189 (cond [(and (eq_attr "alternative" "2")
16190 (match_operand:MODEF 3 "mult_operator" ""))
16191 (const_string "ssemul")
16192 (and (eq_attr "alternative" "2")
16193 (match_operand:MODEF 3 "div_operator" ""))
16194 (const_string "ssediv")
16195 (eq_attr "alternative" "2")
16196 (const_string "sseadd")
16197 (match_operand:MODEF 3 "mult_operator" "")
16198 (const_string "fmul")
16199 (match_operand:MODEF 3 "div_operator" "")
16200 (const_string "fdiv")
16202 (const_string "fop")))
16203 (set_attr "prefix" "orig,orig,maybe_vex")
16204 (set_attr "mode" "<MODE>")])
16206 (define_insn "*fop_<mode>_1_mixed"
16207 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16208 (match_operator:MODEF 3 "binary_fp_operator"
16209 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16210 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16211 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16212 && !COMMUTATIVE_ARITH_P (operands[3])
16213 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16214 "* return output_387_binary_op (insn, operands);"
16215 [(set (attr "type")
16216 (cond [(and (eq_attr "alternative" "2")
16217 (match_operand:MODEF 3 "mult_operator" ""))
16218 (const_string "ssemul")
16219 (and (eq_attr "alternative" "2")
16220 (match_operand:MODEF 3 "div_operator" ""))
16221 (const_string "ssediv")
16222 (eq_attr "alternative" "2")
16223 (const_string "sseadd")
16224 (match_operand:MODEF 3 "mult_operator" "")
16225 (const_string "fmul")
16226 (match_operand:MODEF 3 "div_operator" "")
16227 (const_string "fdiv")
16229 (const_string "fop")))
16230 (set_attr "mode" "<MODE>")])
16232 (define_insn "*rcpsf2_sse"
16233 [(set (match_operand:SF 0 "register_operand" "=x")
16234 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16237 "%vrcpss\t{%1, %d0|%d0, %1}"
16238 [(set_attr "type" "sse")
16239 (set_attr "atom_sse_attr" "rcp")
16240 (set_attr "prefix" "maybe_vex")
16241 (set_attr "mode" "SF")])
16243 (define_insn "*fop_<mode>_1_avx"
16244 [(set (match_operand:MODEF 0 "register_operand" "=x")
16245 (match_operator:MODEF 3 "binary_fp_operator"
16246 [(match_operand:MODEF 1 "register_operand" "x")
16247 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16248 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16249 && !COMMUTATIVE_ARITH_P (operands[3])"
16250 "* return output_387_binary_op (insn, operands);"
16251 [(set (attr "type")
16252 (cond [(match_operand:MODEF 3 "mult_operator" "")
16253 (const_string "ssemul")
16254 (match_operand:MODEF 3 "div_operator" "")
16255 (const_string "ssediv")
16257 (const_string "sseadd")))
16258 (set_attr "prefix" "vex")
16259 (set_attr "mode" "<MODE>")])
16261 (define_insn "*fop_<mode>_1_sse"
16262 [(set (match_operand:MODEF 0 "register_operand" "=x")
16263 (match_operator:MODEF 3 "binary_fp_operator"
16264 [(match_operand:MODEF 1 "register_operand" "0")
16265 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16266 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16267 && !COMMUTATIVE_ARITH_P (operands[3])"
16268 "* return output_387_binary_op (insn, operands);"
16269 [(set (attr "type")
16270 (cond [(match_operand:MODEF 3 "mult_operator" "")
16271 (const_string "ssemul")
16272 (match_operand:MODEF 3 "div_operator" "")
16273 (const_string "ssediv")
16275 (const_string "sseadd")))
16276 (set_attr "mode" "<MODE>")])
16278 ;; This pattern is not fully shadowed by the pattern above.
16279 (define_insn "*fop_<mode>_1_i387"
16280 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16281 (match_operator:MODEF 3 "binary_fp_operator"
16282 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16283 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16284 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16285 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286 && !COMMUTATIVE_ARITH_P (operands[3])
16287 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16288 "* return output_387_binary_op (insn, operands);"
16289 [(set (attr "type")
16290 (cond [(match_operand:MODEF 3 "mult_operator" "")
16291 (const_string "fmul")
16292 (match_operand:MODEF 3 "div_operator" "")
16293 (const_string "fdiv")
16295 (const_string "fop")))
16296 (set_attr "mode" "<MODE>")])
16298 ;; ??? Add SSE splitters for these!
16299 (define_insn "*fop_<MODEF:mode>_2_i387"
16300 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16301 (match_operator:MODEF 3 "binary_fp_operator"
16303 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16304 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16305 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16306 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16307 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16308 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16309 [(set (attr "type")
16310 (cond [(match_operand:MODEF 3 "mult_operator" "")
16311 (const_string "fmul")
16312 (match_operand:MODEF 3 "div_operator" "")
16313 (const_string "fdiv")
16315 (const_string "fop")))
16316 (set_attr "fp_int_src" "true")
16317 (set_attr "mode" "<X87MODEI12:MODE>")])
16319 (define_insn "*fop_<MODEF:mode>_3_i387"
16320 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16321 (match_operator:MODEF 3 "binary_fp_operator"
16322 [(match_operand:MODEF 1 "register_operand" "0,0")
16324 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16325 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16326 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16327 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16328 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16329 [(set (attr "type")
16330 (cond [(match_operand:MODEF 3 "mult_operator" "")
16331 (const_string "fmul")
16332 (match_operand:MODEF 3 "div_operator" "")
16333 (const_string "fdiv")
16335 (const_string "fop")))
16336 (set_attr "fp_int_src" "true")
16337 (set_attr "mode" "<MODE>")])
16339 (define_insn "*fop_df_4_i387"
16340 [(set (match_operand:DF 0 "register_operand" "=f,f")
16341 (match_operator:DF 3 "binary_fp_operator"
16343 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16344 (match_operand:DF 2 "register_operand" "0,f")]))]
16345 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16346 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16347 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16348 "* return output_387_binary_op (insn, operands);"
16349 [(set (attr "type")
16350 (cond [(match_operand:DF 3 "mult_operator" "")
16351 (const_string "fmul")
16352 (match_operand:DF 3 "div_operator" "")
16353 (const_string "fdiv")
16355 (const_string "fop")))
16356 (set_attr "mode" "SF")])
16358 (define_insn "*fop_df_5_i387"
16359 [(set (match_operand:DF 0 "register_operand" "=f,f")
16360 (match_operator:DF 3 "binary_fp_operator"
16361 [(match_operand:DF 1 "register_operand" "0,f")
16363 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16364 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16365 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16366 "* return output_387_binary_op (insn, operands);"
16367 [(set (attr "type")
16368 (cond [(match_operand:DF 3 "mult_operator" "")
16369 (const_string "fmul")
16370 (match_operand:DF 3 "div_operator" "")
16371 (const_string "fdiv")
16373 (const_string "fop")))
16374 (set_attr "mode" "SF")])
16376 (define_insn "*fop_df_6_i387"
16377 [(set (match_operand:DF 0 "register_operand" "=f,f")
16378 (match_operator:DF 3 "binary_fp_operator"
16380 (match_operand:SF 1 "register_operand" "0,f"))
16382 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16383 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16384 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16385 "* return output_387_binary_op (insn, operands);"
16386 [(set (attr "type")
16387 (cond [(match_operand:DF 3 "mult_operator" "")
16388 (const_string "fmul")
16389 (match_operand:DF 3 "div_operator" "")
16390 (const_string "fdiv")
16392 (const_string "fop")))
16393 (set_attr "mode" "SF")])
16395 (define_insn "*fop_xf_comm_i387"
16396 [(set (match_operand:XF 0 "register_operand" "=f")
16397 (match_operator:XF 3 "binary_fp_operator"
16398 [(match_operand:XF 1 "register_operand" "%0")
16399 (match_operand:XF 2 "register_operand" "f")]))]
16401 && COMMUTATIVE_ARITH_P (operands[3])"
16402 "* return output_387_binary_op (insn, operands);"
16403 [(set (attr "type")
16404 (if_then_else (match_operand:XF 3 "mult_operator" "")
16405 (const_string "fmul")
16406 (const_string "fop")))
16407 (set_attr "mode" "XF")])
16409 (define_insn "*fop_xf_1_i387"
16410 [(set (match_operand:XF 0 "register_operand" "=f,f")
16411 (match_operator:XF 3 "binary_fp_operator"
16412 [(match_operand:XF 1 "register_operand" "0,f")
16413 (match_operand:XF 2 "register_operand" "f,0")]))]
16415 && !COMMUTATIVE_ARITH_P (operands[3])"
16416 "* return output_387_binary_op (insn, operands);"
16417 [(set (attr "type")
16418 (cond [(match_operand:XF 3 "mult_operator" "")
16419 (const_string "fmul")
16420 (match_operand:XF 3 "div_operator" "")
16421 (const_string "fdiv")
16423 (const_string "fop")))
16424 (set_attr "mode" "XF")])
16426 (define_insn "*fop_xf_2_i387"
16427 [(set (match_operand:XF 0 "register_operand" "=f,f")
16428 (match_operator:XF 3 "binary_fp_operator"
16430 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16431 (match_operand:XF 2 "register_operand" "0,0")]))]
16432 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16433 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16434 [(set (attr "type")
16435 (cond [(match_operand:XF 3 "mult_operator" "")
16436 (const_string "fmul")
16437 (match_operand:XF 3 "div_operator" "")
16438 (const_string "fdiv")
16440 (const_string "fop")))
16441 (set_attr "fp_int_src" "true")
16442 (set_attr "mode" "<MODE>")])
16444 (define_insn "*fop_xf_3_i387"
16445 [(set (match_operand:XF 0 "register_operand" "=f,f")
16446 (match_operator:XF 3 "binary_fp_operator"
16447 [(match_operand:XF 1 "register_operand" "0,0")
16449 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16450 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16451 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16452 [(set (attr "type")
16453 (cond [(match_operand:XF 3 "mult_operator" "")
16454 (const_string "fmul")
16455 (match_operand:XF 3 "div_operator" "")
16456 (const_string "fdiv")
16458 (const_string "fop")))
16459 (set_attr "fp_int_src" "true")
16460 (set_attr "mode" "<MODE>")])
16462 (define_insn "*fop_xf_4_i387"
16463 [(set (match_operand:XF 0 "register_operand" "=f,f")
16464 (match_operator:XF 3 "binary_fp_operator"
16466 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16467 (match_operand:XF 2 "register_operand" "0,f")]))]
16469 "* return output_387_binary_op (insn, operands);"
16470 [(set (attr "type")
16471 (cond [(match_operand:XF 3 "mult_operator" "")
16472 (const_string "fmul")
16473 (match_operand:XF 3 "div_operator" "")
16474 (const_string "fdiv")
16476 (const_string "fop")))
16477 (set_attr "mode" "<MODE>")])
16479 (define_insn "*fop_xf_5_i387"
16480 [(set (match_operand:XF 0 "register_operand" "=f,f")
16481 (match_operator:XF 3 "binary_fp_operator"
16482 [(match_operand:XF 1 "register_operand" "0,f")
16484 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16486 "* return output_387_binary_op (insn, operands);"
16487 [(set (attr "type")
16488 (cond [(match_operand:XF 3 "mult_operator" "")
16489 (const_string "fmul")
16490 (match_operand:XF 3 "div_operator" "")
16491 (const_string "fdiv")
16493 (const_string "fop")))
16494 (set_attr "mode" "<MODE>")])
16496 (define_insn "*fop_xf_6_i387"
16497 [(set (match_operand:XF 0 "register_operand" "=f,f")
16498 (match_operator:XF 3 "binary_fp_operator"
16500 (match_operand:MODEF 1 "register_operand" "0,f"))
16502 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16504 "* return output_387_binary_op (insn, operands);"
16505 [(set (attr "type")
16506 (cond [(match_operand:XF 3 "mult_operator" "")
16507 (const_string "fmul")
16508 (match_operand:XF 3 "div_operator" "")
16509 (const_string "fdiv")
16511 (const_string "fop")))
16512 (set_attr "mode" "<MODE>")])
16515 [(set (match_operand 0 "register_operand" "")
16516 (match_operator 3 "binary_fp_operator"
16517 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16518 (match_operand 2 "register_operand" "")]))]
16520 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16521 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16524 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16525 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16526 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16527 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16528 GET_MODE (operands[3]),
16531 ix86_free_from_memory (GET_MODE (operands[1]));
16536 [(set (match_operand 0 "register_operand" "")
16537 (match_operator 3 "binary_fp_operator"
16538 [(match_operand 1 "register_operand" "")
16539 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16541 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16542 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16545 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16546 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16547 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16548 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16549 GET_MODE (operands[3]),
16552 ix86_free_from_memory (GET_MODE (operands[2]));
16556 ;; FPU special functions.
16558 ;; This pattern implements a no-op XFmode truncation for
16559 ;; all fancy i386 XFmode math functions.
16561 (define_insn "truncxf<mode>2_i387_noop_unspec"
16562 [(set (match_operand:MODEF 0 "register_operand" "=f")
16563 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16564 UNSPEC_TRUNC_NOOP))]
16565 "TARGET_USE_FANCY_MATH_387"
16566 "* return output_387_reg_move (insn, operands);"
16567 [(set_attr "type" "fmov")
16568 (set_attr "mode" "<MODE>")])
16570 (define_insn "sqrtxf2"
16571 [(set (match_operand:XF 0 "register_operand" "=f")
16572 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16573 "TARGET_USE_FANCY_MATH_387"
16575 [(set_attr "type" "fpspc")
16576 (set_attr "mode" "XF")
16577 (set_attr "athlon_decode" "direct")
16578 (set_attr "amdfam10_decode" "direct")])
16580 (define_insn "sqrt_extend<mode>xf2_i387"
16581 [(set (match_operand:XF 0 "register_operand" "=f")
16584 (match_operand:MODEF 1 "register_operand" "0"))))]
16585 "TARGET_USE_FANCY_MATH_387"
16587 [(set_attr "type" "fpspc")
16588 (set_attr "mode" "XF")
16589 (set_attr "athlon_decode" "direct")
16590 (set_attr "amdfam10_decode" "direct")])
16592 (define_insn "*rsqrtsf2_sse"
16593 [(set (match_operand:SF 0 "register_operand" "=x")
16594 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16597 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16598 [(set_attr "type" "sse")
16599 (set_attr "atom_sse_attr" "rcp")
16600 (set_attr "prefix" "maybe_vex")
16601 (set_attr "mode" "SF")])
16603 (define_expand "rsqrtsf2"
16604 [(set (match_operand:SF 0 "register_operand" "")
16605 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16609 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16613 (define_insn "*sqrt<mode>2_sse"
16614 [(set (match_operand:MODEF 0 "register_operand" "=x")
16616 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16617 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16618 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16619 [(set_attr "type" "sse")
16620 (set_attr "atom_sse_attr" "sqrt")
16621 (set_attr "prefix" "maybe_vex")
16622 (set_attr "mode" "<MODE>")
16623 (set_attr "athlon_decode" "*")
16624 (set_attr "amdfam10_decode" "*")])
16626 (define_expand "sqrt<mode>2"
16627 [(set (match_operand:MODEF 0 "register_operand" "")
16629 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16630 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16631 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16633 if (<MODE>mode == SFmode
16634 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16635 && flag_finite_math_only && !flag_trapping_math
16636 && flag_unsafe_math_optimizations)
16638 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16642 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16644 rtx op0 = gen_reg_rtx (XFmode);
16645 rtx op1 = force_reg (<MODE>mode, operands[1]);
16647 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16648 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16653 (define_insn "fpremxf4_i387"
16654 [(set (match_operand:XF 0 "register_operand" "=f")
16655 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16656 (match_operand:XF 3 "register_operand" "1")]
16658 (set (match_operand:XF 1 "register_operand" "=u")
16659 (unspec:XF [(match_dup 2) (match_dup 3)]
16661 (set (reg:CCFP FPSR_REG)
16662 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16664 "TARGET_USE_FANCY_MATH_387"
16666 [(set_attr "type" "fpspc")
16667 (set_attr "mode" "XF")])
16669 (define_expand "fmodxf3"
16670 [(use (match_operand:XF 0 "register_operand" ""))
16671 (use (match_operand:XF 1 "general_operand" ""))
16672 (use (match_operand:XF 2 "general_operand" ""))]
16673 "TARGET_USE_FANCY_MATH_387"
16675 rtx label = gen_label_rtx ();
16677 rtx op1 = gen_reg_rtx (XFmode);
16678 rtx op2 = gen_reg_rtx (XFmode);
16680 emit_move_insn (op2, operands[2]);
16681 emit_move_insn (op1, operands[1]);
16683 emit_label (label);
16684 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16685 ix86_emit_fp_unordered_jump (label);
16686 LABEL_NUSES (label) = 1;
16688 emit_move_insn (operands[0], op1);
16692 (define_expand "fmod<mode>3"
16693 [(use (match_operand:MODEF 0 "register_operand" ""))
16694 (use (match_operand:MODEF 1 "general_operand" ""))
16695 (use (match_operand:MODEF 2 "general_operand" ""))]
16696 "TARGET_USE_FANCY_MATH_387"
16698 rtx label = gen_label_rtx ();
16700 rtx op1 = gen_reg_rtx (XFmode);
16701 rtx op2 = gen_reg_rtx (XFmode);
16703 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706 emit_label (label);
16707 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16708 ix86_emit_fp_unordered_jump (label);
16709 LABEL_NUSES (label) = 1;
16711 /* Truncate the result properly for strict SSE math. */
16712 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16713 && !TARGET_MIX_SSE_I387)
16714 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16716 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16721 (define_insn "fprem1xf4_i387"
16722 [(set (match_operand:XF 0 "register_operand" "=f")
16723 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16724 (match_operand:XF 3 "register_operand" "1")]
16726 (set (match_operand:XF 1 "register_operand" "=u")
16727 (unspec:XF [(match_dup 2) (match_dup 3)]
16729 (set (reg:CCFP FPSR_REG)
16730 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16732 "TARGET_USE_FANCY_MATH_387"
16734 [(set_attr "type" "fpspc")
16735 (set_attr "mode" "XF")])
16737 (define_expand "remainderxf3"
16738 [(use (match_operand:XF 0 "register_operand" ""))
16739 (use (match_operand:XF 1 "general_operand" ""))
16740 (use (match_operand:XF 2 "general_operand" ""))]
16741 "TARGET_USE_FANCY_MATH_387"
16743 rtx label = gen_label_rtx ();
16745 rtx op1 = gen_reg_rtx (XFmode);
16746 rtx op2 = gen_reg_rtx (XFmode);
16748 emit_move_insn (op2, operands[2]);
16749 emit_move_insn (op1, operands[1]);
16751 emit_label (label);
16752 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16753 ix86_emit_fp_unordered_jump (label);
16754 LABEL_NUSES (label) = 1;
16756 emit_move_insn (operands[0], op1);
16760 (define_expand "remainder<mode>3"
16761 [(use (match_operand:MODEF 0 "register_operand" ""))
16762 (use (match_operand:MODEF 1 "general_operand" ""))
16763 (use (match_operand:MODEF 2 "general_operand" ""))]
16764 "TARGET_USE_FANCY_MATH_387"
16766 rtx label = gen_label_rtx ();
16768 rtx op1 = gen_reg_rtx (XFmode);
16769 rtx op2 = gen_reg_rtx (XFmode);
16771 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16774 emit_label (label);
16776 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16777 ix86_emit_fp_unordered_jump (label);
16778 LABEL_NUSES (label) = 1;
16780 /* Truncate the result properly for strict SSE math. */
16781 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16782 && !TARGET_MIX_SSE_I387)
16783 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16785 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16790 (define_insn "*sinxf2_i387"
16791 [(set (match_operand:XF 0 "register_operand" "=f")
16792 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && flag_unsafe_math_optimizations"
16796 [(set_attr "type" "fpspc")
16797 (set_attr "mode" "XF")])
16799 (define_insn "*sin_extend<mode>xf2_i387"
16800 [(set (match_operand:XF 0 "register_operand" "=f")
16801 (unspec:XF [(float_extend:XF
16802 (match_operand:MODEF 1 "register_operand" "0"))]
16804 "TARGET_USE_FANCY_MATH_387
16805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16806 || TARGET_MIX_SSE_I387)
16807 && flag_unsafe_math_optimizations"
16809 [(set_attr "type" "fpspc")
16810 (set_attr "mode" "XF")])
16812 (define_insn "*cosxf2_i387"
16813 [(set (match_operand:XF 0 "register_operand" "=f")
16814 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16815 "TARGET_USE_FANCY_MATH_387
16816 && flag_unsafe_math_optimizations"
16818 [(set_attr "type" "fpspc")
16819 (set_attr "mode" "XF")])
16821 (define_insn "*cos_extend<mode>xf2_i387"
16822 [(set (match_operand:XF 0 "register_operand" "=f")
16823 (unspec:XF [(float_extend:XF
16824 (match_operand:MODEF 1 "register_operand" "0"))]
16826 "TARGET_USE_FANCY_MATH_387
16827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16828 || TARGET_MIX_SSE_I387)
16829 && flag_unsafe_math_optimizations"
16831 [(set_attr "type" "fpspc")
16832 (set_attr "mode" "XF")])
16834 ;; When sincos pattern is defined, sin and cos builtin functions will be
16835 ;; expanded to sincos pattern with one of its outputs left unused.
16836 ;; CSE pass will figure out if two sincos patterns can be combined,
16837 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16838 ;; depending on the unused output.
16840 (define_insn "sincosxf3"
16841 [(set (match_operand:XF 0 "register_operand" "=f")
16842 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16843 UNSPEC_SINCOS_COS))
16844 (set (match_operand:XF 1 "register_operand" "=u")
16845 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && flag_unsafe_math_optimizations"
16849 [(set_attr "type" "fpspc")
16850 (set_attr "mode" "XF")])
16853 [(set (match_operand:XF 0 "register_operand" "")
16854 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16855 UNSPEC_SINCOS_COS))
16856 (set (match_operand:XF 1 "register_operand" "")
16857 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16858 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16859 && !(reload_completed || reload_in_progress)"
16860 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16864 [(set (match_operand:XF 0 "register_operand" "")
16865 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16866 UNSPEC_SINCOS_COS))
16867 (set (match_operand:XF 1 "register_operand" "")
16868 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16869 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16870 && !(reload_completed || reload_in_progress)"
16871 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16874 (define_insn "sincos_extend<mode>xf3_i387"
16875 [(set (match_operand:XF 0 "register_operand" "=f")
16876 (unspec:XF [(float_extend:XF
16877 (match_operand:MODEF 2 "register_operand" "0"))]
16878 UNSPEC_SINCOS_COS))
16879 (set (match_operand:XF 1 "register_operand" "=u")
16880 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16883 || TARGET_MIX_SSE_I387)
16884 && flag_unsafe_math_optimizations"
16886 [(set_attr "type" "fpspc")
16887 (set_attr "mode" "XF")])
16890 [(set (match_operand:XF 0 "register_operand" "")
16891 (unspec:XF [(float_extend:XF
16892 (match_operand:MODEF 2 "register_operand" ""))]
16893 UNSPEC_SINCOS_COS))
16894 (set (match_operand:XF 1 "register_operand" "")
16895 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16896 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16897 && !(reload_completed || reload_in_progress)"
16898 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16902 [(set (match_operand:XF 0 "register_operand" "")
16903 (unspec:XF [(float_extend:XF
16904 (match_operand:MODEF 2 "register_operand" ""))]
16905 UNSPEC_SINCOS_COS))
16906 (set (match_operand:XF 1 "register_operand" "")
16907 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16908 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16909 && !(reload_completed || reload_in_progress)"
16910 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16913 (define_expand "sincos<mode>3"
16914 [(use (match_operand:MODEF 0 "register_operand" ""))
16915 (use (match_operand:MODEF 1 "register_operand" ""))
16916 (use (match_operand:MODEF 2 "register_operand" ""))]
16917 "TARGET_USE_FANCY_MATH_387
16918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16919 || TARGET_MIX_SSE_I387)
16920 && flag_unsafe_math_optimizations"
16922 rtx op0 = gen_reg_rtx (XFmode);
16923 rtx op1 = gen_reg_rtx (XFmode);
16925 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16926 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16927 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16931 (define_insn "fptanxf4_i387"
16932 [(set (match_operand:XF 0 "register_operand" "=f")
16933 (match_operand:XF 3 "const_double_operand" "F"))
16934 (set (match_operand:XF 1 "register_operand" "=u")
16935 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16937 "TARGET_USE_FANCY_MATH_387
16938 && flag_unsafe_math_optimizations
16939 && standard_80387_constant_p (operands[3]) == 2"
16941 [(set_attr "type" "fpspc")
16942 (set_attr "mode" "XF")])
16944 (define_insn "fptan_extend<mode>xf4_i387"
16945 [(set (match_operand:MODEF 0 "register_operand" "=f")
16946 (match_operand:MODEF 3 "const_double_operand" "F"))
16947 (set (match_operand:XF 1 "register_operand" "=u")
16948 (unspec:XF [(float_extend:XF
16949 (match_operand:MODEF 2 "register_operand" "0"))]
16951 "TARGET_USE_FANCY_MATH_387
16952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953 || TARGET_MIX_SSE_I387)
16954 && flag_unsafe_math_optimizations
16955 && standard_80387_constant_p (operands[3]) == 2"
16957 [(set_attr "type" "fpspc")
16958 (set_attr "mode" "XF")])
16960 (define_expand "tanxf2"
16961 [(use (match_operand:XF 0 "register_operand" ""))
16962 (use (match_operand:XF 1 "register_operand" ""))]
16963 "TARGET_USE_FANCY_MATH_387
16964 && flag_unsafe_math_optimizations"
16966 rtx one = gen_reg_rtx (XFmode);
16967 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16969 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16973 (define_expand "tan<mode>2"
16974 [(use (match_operand:MODEF 0 "register_operand" ""))
16975 (use (match_operand:MODEF 1 "register_operand" ""))]
16976 "TARGET_USE_FANCY_MATH_387
16977 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16978 || TARGET_MIX_SSE_I387)
16979 && flag_unsafe_math_optimizations"
16981 rtx op0 = gen_reg_rtx (XFmode);
16983 rtx one = gen_reg_rtx (<MODE>mode);
16984 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16986 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16987 operands[1], op2));
16988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16992 (define_insn "*fpatanxf3_i387"
16993 [(set (match_operand:XF 0 "register_operand" "=f")
16994 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16995 (match_operand:XF 2 "register_operand" "u")]
16997 (clobber (match_scratch:XF 3 "=2"))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && flag_unsafe_math_optimizations"
17001 [(set_attr "type" "fpspc")
17002 (set_attr "mode" "XF")])
17004 (define_insn "fpatan_extend<mode>xf3_i387"
17005 [(set (match_operand:XF 0 "register_operand" "=f")
17006 (unspec:XF [(float_extend:XF
17007 (match_operand:MODEF 1 "register_operand" "0"))
17009 (match_operand:MODEF 2 "register_operand" "u"))]
17011 (clobber (match_scratch:XF 3 "=2"))]
17012 "TARGET_USE_FANCY_MATH_387
17013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17014 || TARGET_MIX_SSE_I387)
17015 && flag_unsafe_math_optimizations"
17017 [(set_attr "type" "fpspc")
17018 (set_attr "mode" "XF")])
17020 (define_expand "atan2xf3"
17021 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17022 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17023 (match_operand:XF 1 "register_operand" "")]
17025 (clobber (match_scratch:XF 3 ""))])]
17026 "TARGET_USE_FANCY_MATH_387
17027 && flag_unsafe_math_optimizations"
17030 (define_expand "atan2<mode>3"
17031 [(use (match_operand:MODEF 0 "register_operand" ""))
17032 (use (match_operand:MODEF 1 "register_operand" ""))
17033 (use (match_operand:MODEF 2 "register_operand" ""))]
17034 "TARGET_USE_FANCY_MATH_387
17035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17036 || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17039 rtx op0 = gen_reg_rtx (XFmode);
17041 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17042 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17046 (define_expand "atanxf2"
17047 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17048 (unspec:XF [(match_dup 2)
17049 (match_operand:XF 1 "register_operand" "")]
17051 (clobber (match_scratch:XF 3 ""))])]
17052 "TARGET_USE_FANCY_MATH_387
17053 && flag_unsafe_math_optimizations"
17055 operands[2] = gen_reg_rtx (XFmode);
17056 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17059 (define_expand "atan<mode>2"
17060 [(use (match_operand:MODEF 0 "register_operand" ""))
17061 (use (match_operand:MODEF 1 "register_operand" ""))]
17062 "TARGET_USE_FANCY_MATH_387
17063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064 || TARGET_MIX_SSE_I387)
17065 && flag_unsafe_math_optimizations"
17067 rtx op0 = gen_reg_rtx (XFmode);
17069 rtx op2 = gen_reg_rtx (<MODE>mode);
17070 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17072 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077 (define_expand "asinxf2"
17078 [(set (match_dup 2)
17079 (mult:XF (match_operand:XF 1 "register_operand" "")
17081 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17082 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17083 (parallel [(set (match_operand:XF 0 "register_operand" "")
17084 (unspec:XF [(match_dup 5) (match_dup 1)]
17086 (clobber (match_scratch:XF 6 ""))])]
17087 "TARGET_USE_FANCY_MATH_387
17088 && flag_unsafe_math_optimizations"
17092 if (optimize_insn_for_size_p ())
17095 for (i = 2; i < 6; i++)
17096 operands[i] = gen_reg_rtx (XFmode);
17098 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17101 (define_expand "asin<mode>2"
17102 [(use (match_operand:MODEF 0 "register_operand" ""))
17103 (use (match_operand:MODEF 1 "general_operand" ""))]
17104 "TARGET_USE_FANCY_MATH_387
17105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17106 || TARGET_MIX_SSE_I387)
17107 && flag_unsafe_math_optimizations"
17109 rtx op0 = gen_reg_rtx (XFmode);
17110 rtx op1 = gen_reg_rtx (XFmode);
17112 if (optimize_insn_for_size_p ())
17115 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17116 emit_insn (gen_asinxf2 (op0, op1));
17117 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17121 (define_expand "acosxf2"
17122 [(set (match_dup 2)
17123 (mult:XF (match_operand:XF 1 "register_operand" "")
17125 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17126 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17127 (parallel [(set (match_operand:XF 0 "register_operand" "")
17128 (unspec:XF [(match_dup 1) (match_dup 5)]
17130 (clobber (match_scratch:XF 6 ""))])]
17131 "TARGET_USE_FANCY_MATH_387
17132 && flag_unsafe_math_optimizations"
17136 if (optimize_insn_for_size_p ())
17139 for (i = 2; i < 6; i++)
17140 operands[i] = gen_reg_rtx (XFmode);
17142 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17145 (define_expand "acos<mode>2"
17146 [(use (match_operand:MODEF 0 "register_operand" ""))
17147 (use (match_operand:MODEF 1 "general_operand" ""))]
17148 "TARGET_USE_FANCY_MATH_387
17149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17150 || TARGET_MIX_SSE_I387)
17151 && flag_unsafe_math_optimizations"
17153 rtx op0 = gen_reg_rtx (XFmode);
17154 rtx op1 = gen_reg_rtx (XFmode);
17156 if (optimize_insn_for_size_p ())
17159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160 emit_insn (gen_acosxf2 (op0, op1));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17165 (define_insn "fyl2xxf3_i387"
17166 [(set (match_operand:XF 0 "register_operand" "=f")
17167 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17168 (match_operand:XF 2 "register_operand" "u")]
17170 (clobber (match_scratch:XF 3 "=2"))]
17171 "TARGET_USE_FANCY_MATH_387
17172 && flag_unsafe_math_optimizations"
17174 [(set_attr "type" "fpspc")
17175 (set_attr "mode" "XF")])
17177 (define_insn "fyl2x_extend<mode>xf3_i387"
17178 [(set (match_operand:XF 0 "register_operand" "=f")
17179 (unspec:XF [(float_extend:XF
17180 (match_operand:MODEF 1 "register_operand" "0"))
17181 (match_operand:XF 2 "register_operand" "u")]
17183 (clobber (match_scratch:XF 3 "=2"))]
17184 "TARGET_USE_FANCY_MATH_387
17185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17186 || TARGET_MIX_SSE_I387)
17187 && flag_unsafe_math_optimizations"
17189 [(set_attr "type" "fpspc")
17190 (set_attr "mode" "XF")])
17192 (define_expand "logxf2"
17193 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17194 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17195 (match_dup 2)] UNSPEC_FYL2X))
17196 (clobber (match_scratch:XF 3 ""))])]
17197 "TARGET_USE_FANCY_MATH_387
17198 && flag_unsafe_math_optimizations"
17200 operands[2] = gen_reg_rtx (XFmode);
17201 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17204 (define_expand "log<mode>2"
17205 [(use (match_operand:MODEF 0 "register_operand" ""))
17206 (use (match_operand:MODEF 1 "register_operand" ""))]
17207 "TARGET_USE_FANCY_MATH_387
17208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17209 || TARGET_MIX_SSE_I387)
17210 && flag_unsafe_math_optimizations"
17212 rtx op0 = gen_reg_rtx (XFmode);
17214 rtx op2 = gen_reg_rtx (XFmode);
17215 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17217 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17222 (define_expand "log10xf2"
17223 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17224 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17225 (match_dup 2)] UNSPEC_FYL2X))
17226 (clobber (match_scratch:XF 3 ""))])]
17227 "TARGET_USE_FANCY_MATH_387
17228 && flag_unsafe_math_optimizations"
17230 operands[2] = gen_reg_rtx (XFmode);
17231 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17234 (define_expand "log10<mode>2"
17235 [(use (match_operand:MODEF 0 "register_operand" ""))
17236 (use (match_operand:MODEF 1 "register_operand" ""))]
17237 "TARGET_USE_FANCY_MATH_387
17238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17239 || TARGET_MIX_SSE_I387)
17240 && flag_unsafe_math_optimizations"
17242 rtx op0 = gen_reg_rtx (XFmode);
17244 rtx op2 = gen_reg_rtx (XFmode);
17245 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17247 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17248 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17252 (define_expand "log2xf2"
17253 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17254 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17255 (match_dup 2)] UNSPEC_FYL2X))
17256 (clobber (match_scratch:XF 3 ""))])]
17257 "TARGET_USE_FANCY_MATH_387
17258 && flag_unsafe_math_optimizations"
17260 operands[2] = gen_reg_rtx (XFmode);
17261 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17264 (define_expand "log2<mode>2"
17265 [(use (match_operand:MODEF 0 "register_operand" ""))
17266 (use (match_operand:MODEF 1 "register_operand" ""))]
17267 "TARGET_USE_FANCY_MATH_387
17268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17269 || TARGET_MIX_SSE_I387)
17270 && flag_unsafe_math_optimizations"
17272 rtx op0 = gen_reg_rtx (XFmode);
17274 rtx op2 = gen_reg_rtx (XFmode);
17275 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17277 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17278 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17282 (define_insn "fyl2xp1xf3_i387"
17283 [(set (match_operand:XF 0 "register_operand" "=f")
17284 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17285 (match_operand:XF 2 "register_operand" "u")]
17287 (clobber (match_scratch:XF 3 "=2"))]
17288 "TARGET_USE_FANCY_MATH_387
17289 && flag_unsafe_math_optimizations"
17291 [(set_attr "type" "fpspc")
17292 (set_attr "mode" "XF")])
17294 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17295 [(set (match_operand:XF 0 "register_operand" "=f")
17296 (unspec:XF [(float_extend:XF
17297 (match_operand:MODEF 1 "register_operand" "0"))
17298 (match_operand:XF 2 "register_operand" "u")]
17300 (clobber (match_scratch:XF 3 "=2"))]
17301 "TARGET_USE_FANCY_MATH_387
17302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17303 || TARGET_MIX_SSE_I387)
17304 && flag_unsafe_math_optimizations"
17306 [(set_attr "type" "fpspc")
17307 (set_attr "mode" "XF")])
17309 (define_expand "log1pxf2"
17310 [(use (match_operand:XF 0 "register_operand" ""))
17311 (use (match_operand:XF 1 "register_operand" ""))]
17312 "TARGET_USE_FANCY_MATH_387
17313 && flag_unsafe_math_optimizations"
17315 if (optimize_insn_for_size_p ())
17318 ix86_emit_i387_log1p (operands[0], operands[1]);
17322 (define_expand "log1p<mode>2"
17323 [(use (match_operand:MODEF 0 "register_operand" ""))
17324 (use (match_operand:MODEF 1 "register_operand" ""))]
17325 "TARGET_USE_FANCY_MATH_387
17326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17327 || TARGET_MIX_SSE_I387)
17328 && flag_unsafe_math_optimizations"
17332 if (optimize_insn_for_size_p ())
17335 op0 = gen_reg_rtx (XFmode);
17337 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17339 ix86_emit_i387_log1p (op0, operands[1]);
17340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17344 (define_insn "fxtractxf3_i387"
17345 [(set (match_operand:XF 0 "register_operand" "=f")
17346 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17347 UNSPEC_XTRACT_FRACT))
17348 (set (match_operand:XF 1 "register_operand" "=u")
17349 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17350 "TARGET_USE_FANCY_MATH_387
17351 && flag_unsafe_math_optimizations"
17353 [(set_attr "type" "fpspc")
17354 (set_attr "mode" "XF")])
17356 (define_insn "fxtract_extend<mode>xf3_i387"
17357 [(set (match_operand:XF 0 "register_operand" "=f")
17358 (unspec:XF [(float_extend:XF
17359 (match_operand:MODEF 2 "register_operand" "0"))]
17360 UNSPEC_XTRACT_FRACT))
17361 (set (match_operand:XF 1 "register_operand" "=u")
17362 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17363 "TARGET_USE_FANCY_MATH_387
17364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17365 || TARGET_MIX_SSE_I387)
17366 && flag_unsafe_math_optimizations"
17368 [(set_attr "type" "fpspc")
17369 (set_attr "mode" "XF")])
17371 (define_expand "logbxf2"
17372 [(parallel [(set (match_dup 2)
17373 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17374 UNSPEC_XTRACT_FRACT))
17375 (set (match_operand:XF 0 "register_operand" "")
17376 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17377 "TARGET_USE_FANCY_MATH_387
17378 && flag_unsafe_math_optimizations"
17380 operands[2] = gen_reg_rtx (XFmode);
17383 (define_expand "logb<mode>2"
17384 [(use (match_operand:MODEF 0 "register_operand" ""))
17385 (use (match_operand:MODEF 1 "register_operand" ""))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388 || TARGET_MIX_SSE_I387)
17389 && flag_unsafe_math_optimizations"
17391 rtx op0 = gen_reg_rtx (XFmode);
17392 rtx op1 = gen_reg_rtx (XFmode);
17394 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17399 (define_expand "ilogbxf2"
17400 [(use (match_operand:SI 0 "register_operand" ""))
17401 (use (match_operand:XF 1 "register_operand" ""))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && flag_unsafe_math_optimizations"
17407 if (optimize_insn_for_size_p ())
17410 op0 = gen_reg_rtx (XFmode);
17411 op1 = gen_reg_rtx (XFmode);
17413 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17414 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17418 (define_expand "ilogb<mode>2"
17419 [(use (match_operand:SI 0 "register_operand" ""))
17420 (use (match_operand:MODEF 1 "register_operand" ""))]
17421 "TARGET_USE_FANCY_MATH_387
17422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17423 || TARGET_MIX_SSE_I387)
17424 && flag_unsafe_math_optimizations"
17428 if (optimize_insn_for_size_p ())
17431 op0 = gen_reg_rtx (XFmode);
17432 op1 = gen_reg_rtx (XFmode);
17434 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17435 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17439 (define_insn "*f2xm1xf2_i387"
17440 [(set (match_operand:XF 0 "register_operand" "=f")
17441 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17443 "TARGET_USE_FANCY_MATH_387
17444 && flag_unsafe_math_optimizations"
17446 [(set_attr "type" "fpspc")
17447 (set_attr "mode" "XF")])
17449 (define_insn "*fscalexf4_i387"
17450 [(set (match_operand:XF 0 "register_operand" "=f")
17451 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17452 (match_operand:XF 3 "register_operand" "1")]
17453 UNSPEC_FSCALE_FRACT))
17454 (set (match_operand:XF 1 "register_operand" "=u")
17455 (unspec:XF [(match_dup 2) (match_dup 3)]
17456 UNSPEC_FSCALE_EXP))]
17457 "TARGET_USE_FANCY_MATH_387
17458 && flag_unsafe_math_optimizations"
17460 [(set_attr "type" "fpspc")
17461 (set_attr "mode" "XF")])
17463 (define_expand "expNcorexf3"
17464 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17465 (match_operand:XF 2 "register_operand" "")))
17466 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17467 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17468 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17469 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17470 (parallel [(set (match_operand:XF 0 "register_operand" "")
17471 (unspec:XF [(match_dup 8) (match_dup 4)]
17472 UNSPEC_FSCALE_FRACT))
17474 (unspec:XF [(match_dup 8) (match_dup 4)]
17475 UNSPEC_FSCALE_EXP))])]
17476 "TARGET_USE_FANCY_MATH_387
17477 && flag_unsafe_math_optimizations"
17481 if (optimize_insn_for_size_p ())
17484 for (i = 3; i < 10; i++)
17485 operands[i] = gen_reg_rtx (XFmode);
17487 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17490 (define_expand "expxf2"
17491 [(use (match_operand:XF 0 "register_operand" ""))
17492 (use (match_operand:XF 1 "register_operand" ""))]
17493 "TARGET_USE_FANCY_MATH_387
17494 && flag_unsafe_math_optimizations"
17498 if (optimize_insn_for_size_p ())
17501 op2 = gen_reg_rtx (XFmode);
17502 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17504 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17508 (define_expand "exp<mode>2"
17509 [(use (match_operand:MODEF 0 "register_operand" ""))
17510 (use (match_operand:MODEF 1 "general_operand" ""))]
17511 "TARGET_USE_FANCY_MATH_387
17512 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17513 || TARGET_MIX_SSE_I387)
17514 && flag_unsafe_math_optimizations"
17518 if (optimize_insn_for_size_p ())
17521 op0 = gen_reg_rtx (XFmode);
17522 op1 = gen_reg_rtx (XFmode);
17524 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17525 emit_insn (gen_expxf2 (op0, op1));
17526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17530 (define_expand "exp10xf2"
17531 [(use (match_operand:XF 0 "register_operand" ""))
17532 (use (match_operand:XF 1 "register_operand" ""))]
17533 "TARGET_USE_FANCY_MATH_387
17534 && flag_unsafe_math_optimizations"
17538 if (optimize_insn_for_size_p ())
17541 op2 = gen_reg_rtx (XFmode);
17542 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17544 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17548 (define_expand "exp10<mode>2"
17549 [(use (match_operand:MODEF 0 "register_operand" ""))
17550 (use (match_operand:MODEF 1 "general_operand" ""))]
17551 "TARGET_USE_FANCY_MATH_387
17552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17553 || TARGET_MIX_SSE_I387)
17554 && flag_unsafe_math_optimizations"
17558 if (optimize_insn_for_size_p ())
17561 op0 = gen_reg_rtx (XFmode);
17562 op1 = gen_reg_rtx (XFmode);
17564 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17565 emit_insn (gen_exp10xf2 (op0, op1));
17566 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17570 (define_expand "exp2xf2"
17571 [(use (match_operand:XF 0 "register_operand" ""))
17572 (use (match_operand:XF 1 "register_operand" ""))]
17573 "TARGET_USE_FANCY_MATH_387
17574 && flag_unsafe_math_optimizations"
17578 if (optimize_insn_for_size_p ())
17581 op2 = gen_reg_rtx (XFmode);
17582 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17584 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17588 (define_expand "exp2<mode>2"
17589 [(use (match_operand:MODEF 0 "register_operand" ""))
17590 (use (match_operand:MODEF 1 "general_operand" ""))]
17591 "TARGET_USE_FANCY_MATH_387
17592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17593 || TARGET_MIX_SSE_I387)
17594 && flag_unsafe_math_optimizations"
17598 if (optimize_insn_for_size_p ())
17601 op0 = gen_reg_rtx (XFmode);
17602 op1 = gen_reg_rtx (XFmode);
17604 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17605 emit_insn (gen_exp2xf2 (op0, op1));
17606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17610 (define_expand "expm1xf2"
17611 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17613 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17614 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17615 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17616 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17617 (parallel [(set (match_dup 7)
17618 (unspec:XF [(match_dup 6) (match_dup 4)]
17619 UNSPEC_FSCALE_FRACT))
17621 (unspec:XF [(match_dup 6) (match_dup 4)]
17622 UNSPEC_FSCALE_EXP))])
17623 (parallel [(set (match_dup 10)
17624 (unspec:XF [(match_dup 9) (match_dup 8)]
17625 UNSPEC_FSCALE_FRACT))
17626 (set (match_dup 11)
17627 (unspec:XF [(match_dup 9) (match_dup 8)]
17628 UNSPEC_FSCALE_EXP))])
17629 (set (match_dup 12) (minus:XF (match_dup 10)
17630 (float_extend:XF (match_dup 13))))
17631 (set (match_operand:XF 0 "register_operand" "")
17632 (plus:XF (match_dup 12) (match_dup 7)))]
17633 "TARGET_USE_FANCY_MATH_387
17634 && flag_unsafe_math_optimizations"
17638 if (optimize_insn_for_size_p ())
17641 for (i = 2; i < 13; i++)
17642 operands[i] = gen_reg_rtx (XFmode);
17645 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17647 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17650 (define_expand "expm1<mode>2"
17651 [(use (match_operand:MODEF 0 "register_operand" ""))
17652 (use (match_operand:MODEF 1 "general_operand" ""))]
17653 "TARGET_USE_FANCY_MATH_387
17654 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17655 || TARGET_MIX_SSE_I387)
17656 && flag_unsafe_math_optimizations"
17660 if (optimize_insn_for_size_p ())
17663 op0 = gen_reg_rtx (XFmode);
17664 op1 = gen_reg_rtx (XFmode);
17666 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17667 emit_insn (gen_expm1xf2 (op0, op1));
17668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17672 (define_expand "ldexpxf3"
17673 [(set (match_dup 3)
17674 (float:XF (match_operand:SI 2 "register_operand" "")))
17675 (parallel [(set (match_operand:XF 0 " register_operand" "")
17676 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17678 UNSPEC_FSCALE_FRACT))
17680 (unspec:XF [(match_dup 1) (match_dup 3)]
17681 UNSPEC_FSCALE_EXP))])]
17682 "TARGET_USE_FANCY_MATH_387
17683 && flag_unsafe_math_optimizations"
17685 if (optimize_insn_for_size_p ())
17688 operands[3] = gen_reg_rtx (XFmode);
17689 operands[4] = gen_reg_rtx (XFmode);
17692 (define_expand "ldexp<mode>3"
17693 [(use (match_operand:MODEF 0 "register_operand" ""))
17694 (use (match_operand:MODEF 1 "general_operand" ""))
17695 (use (match_operand:SI 2 "register_operand" ""))]
17696 "TARGET_USE_FANCY_MATH_387
17697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17698 || TARGET_MIX_SSE_I387)
17699 && flag_unsafe_math_optimizations"
17703 if (optimize_insn_for_size_p ())
17706 op0 = gen_reg_rtx (XFmode);
17707 op1 = gen_reg_rtx (XFmode);
17709 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17710 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17711 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17715 (define_expand "scalbxf3"
17716 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17717 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17718 (match_operand:XF 2 "register_operand" "")]
17719 UNSPEC_FSCALE_FRACT))
17721 (unspec:XF [(match_dup 1) (match_dup 2)]
17722 UNSPEC_FSCALE_EXP))])]
17723 "TARGET_USE_FANCY_MATH_387
17724 && flag_unsafe_math_optimizations"
17726 if (optimize_insn_for_size_p ())
17729 operands[3] = gen_reg_rtx (XFmode);
17732 (define_expand "scalb<mode>3"
17733 [(use (match_operand:MODEF 0 "register_operand" ""))
17734 (use (match_operand:MODEF 1 "general_operand" ""))
17735 (use (match_operand:MODEF 2 "general_operand" ""))]
17736 "TARGET_USE_FANCY_MATH_387
17737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17738 || TARGET_MIX_SSE_I387)
17739 && flag_unsafe_math_optimizations"
17743 if (optimize_insn_for_size_p ())
17746 op0 = gen_reg_rtx (XFmode);
17747 op1 = gen_reg_rtx (XFmode);
17748 op2 = gen_reg_rtx (XFmode);
17750 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17751 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17752 emit_insn (gen_scalbxf3 (op0, op1, op2));
17753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17757 (define_expand "significandxf2"
17758 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17759 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17760 UNSPEC_XTRACT_FRACT))
17762 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17763 "TARGET_USE_FANCY_MATH_387
17764 && flag_unsafe_math_optimizations"
17766 operands[2] = gen_reg_rtx (XFmode);
17769 (define_expand "significand<mode>2"
17770 [(use (match_operand:MODEF 0 "register_operand" ""))
17771 (use (match_operand:MODEF 1 "register_operand" ""))]
17772 "TARGET_USE_FANCY_MATH_387
17773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774 || TARGET_MIX_SSE_I387)
17775 && flag_unsafe_math_optimizations"
17777 rtx op0 = gen_reg_rtx (XFmode);
17778 rtx op1 = gen_reg_rtx (XFmode);
17780 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17786 (define_insn "sse4_1_round<mode>2"
17787 [(set (match_operand:MODEF 0 "register_operand" "=x")
17788 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17789 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17792 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17793 [(set_attr "type" "ssecvt")
17794 (set_attr "prefix_extra" "1")
17795 (set_attr "prefix" "maybe_vex")
17796 (set_attr "mode" "<MODE>")])
17798 (define_insn "rintxf2"
17799 [(set (match_operand:XF 0 "register_operand" "=f")
17800 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17802 "TARGET_USE_FANCY_MATH_387
17803 && flag_unsafe_math_optimizations"
17805 [(set_attr "type" "fpspc")
17806 (set_attr "mode" "XF")])
17808 (define_expand "rint<mode>2"
17809 [(use (match_operand:MODEF 0 "register_operand" ""))
17810 (use (match_operand:MODEF 1 "register_operand" ""))]
17811 "(TARGET_USE_FANCY_MATH_387
17812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17813 || TARGET_MIX_SSE_I387)
17814 && flag_unsafe_math_optimizations)
17815 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17816 && !flag_trapping_math)"
17818 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17819 && !flag_trapping_math)
17821 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17824 emit_insn (gen_sse4_1_round<mode>2
17825 (operands[0], operands[1], GEN_INT (0x04)));
17827 ix86_expand_rint (operand0, operand1);
17831 rtx op0 = gen_reg_rtx (XFmode);
17832 rtx op1 = gen_reg_rtx (XFmode);
17834 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17835 emit_insn (gen_rintxf2 (op0, op1));
17837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17842 (define_expand "round<mode>2"
17843 [(match_operand:MODEF 0 "register_operand" "")
17844 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17845 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17846 && !flag_trapping_math && !flag_rounding_math"
17848 if (optimize_insn_for_size_p ())
17850 if (TARGET_64BIT || (<MODE>mode != DFmode))
17851 ix86_expand_round (operand0, operand1);
17853 ix86_expand_rounddf_32 (operand0, operand1);
17857 (define_insn_and_split "*fistdi2_1"
17858 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17859 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17861 "TARGET_USE_FANCY_MATH_387
17862 && can_create_pseudo_p ()"
17867 if (memory_operand (operands[0], VOIDmode))
17868 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17871 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17872 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17877 [(set_attr "type" "fpspc")
17878 (set_attr "mode" "DI")])
17880 (define_insn "fistdi2"
17881 [(set (match_operand:DI 0 "memory_operand" "=m")
17882 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17884 (clobber (match_scratch:XF 2 "=&1f"))]
17885 "TARGET_USE_FANCY_MATH_387"
17886 "* return output_fix_trunc (insn, operands, 0);"
17887 [(set_attr "type" "fpspc")
17888 (set_attr "mode" "DI")])
17890 (define_insn "fistdi2_with_temp"
17891 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17892 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17894 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17895 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17896 "TARGET_USE_FANCY_MATH_387"
17898 [(set_attr "type" "fpspc")
17899 (set_attr "mode" "DI")])
17902 [(set (match_operand:DI 0 "register_operand" "")
17903 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17905 (clobber (match_operand:DI 2 "memory_operand" ""))
17906 (clobber (match_scratch 3 ""))]
17908 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17909 (clobber (match_dup 3))])
17910 (set (match_dup 0) (match_dup 2))]
17914 [(set (match_operand:DI 0 "memory_operand" "")
17915 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17917 (clobber (match_operand:DI 2 "memory_operand" ""))
17918 (clobber (match_scratch 3 ""))]
17920 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17921 (clobber (match_dup 3))])]
17924 (define_insn_and_split "*fist<mode>2_1"
17925 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17926 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17928 "TARGET_USE_FANCY_MATH_387
17929 && can_create_pseudo_p ()"
17934 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17935 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17939 [(set_attr "type" "fpspc")
17940 (set_attr "mode" "<MODE>")])
17942 (define_insn "fist<mode>2"
17943 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17944 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17946 "TARGET_USE_FANCY_MATH_387"
17947 "* return output_fix_trunc (insn, operands, 0);"
17948 [(set_attr "type" "fpspc")
17949 (set_attr "mode" "<MODE>")])
17951 (define_insn "fist<mode>2_with_temp"
17952 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17953 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17955 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17956 "TARGET_USE_FANCY_MATH_387"
17958 [(set_attr "type" "fpspc")
17959 (set_attr "mode" "<MODE>")])
17962 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17963 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17965 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17967 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17968 (set (match_dup 0) (match_dup 2))]
17972 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17973 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17975 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17977 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17980 (define_expand "lrintxf<mode>2"
17981 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17982 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17984 "TARGET_USE_FANCY_MATH_387"
17987 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17988 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17989 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17990 UNSPEC_FIX_NOTRUNC))]
17991 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17992 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17995 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17996 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17997 (match_operand:MODEF 1 "register_operand" "")]
17998 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17999 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18000 && !flag_trapping_math && !flag_rounding_math"
18002 if (optimize_insn_for_size_p ())
18004 ix86_expand_lround (operand0, operand1);
18008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18009 (define_insn_and_split "frndintxf2_floor"
18010 [(set (match_operand:XF 0 "register_operand" "")
18011 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18012 UNSPEC_FRNDINT_FLOOR))
18013 (clobber (reg:CC FLAGS_REG))]
18014 "TARGET_USE_FANCY_MATH_387
18015 && flag_unsafe_math_optimizations
18016 && can_create_pseudo_p ()"
18021 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18023 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18024 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18026 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18027 operands[2], operands[3]));
18030 [(set_attr "type" "frndint")
18031 (set_attr "i387_cw" "floor")
18032 (set_attr "mode" "XF")])
18034 (define_insn "frndintxf2_floor_i387"
18035 [(set (match_operand:XF 0 "register_operand" "=f")
18036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18037 UNSPEC_FRNDINT_FLOOR))
18038 (use (match_operand:HI 2 "memory_operand" "m"))
18039 (use (match_operand:HI 3 "memory_operand" "m"))]
18040 "TARGET_USE_FANCY_MATH_387
18041 && flag_unsafe_math_optimizations"
18042 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18043 [(set_attr "type" "frndint")
18044 (set_attr "i387_cw" "floor")
18045 (set_attr "mode" "XF")])
18047 (define_expand "floorxf2"
18048 [(use (match_operand:XF 0 "register_operand" ""))
18049 (use (match_operand:XF 1 "register_operand" ""))]
18050 "TARGET_USE_FANCY_MATH_387
18051 && flag_unsafe_math_optimizations"
18053 if (optimize_insn_for_size_p ())
18055 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18059 (define_expand "floor<mode>2"
18060 [(use (match_operand:MODEF 0 "register_operand" ""))
18061 (use (match_operand:MODEF 1 "register_operand" ""))]
18062 "(TARGET_USE_FANCY_MATH_387
18063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18064 || TARGET_MIX_SSE_I387)
18065 && flag_unsafe_math_optimizations)
18066 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18067 && !flag_trapping_math)"
18069 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18070 && !flag_trapping_math
18071 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18073 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18076 emit_insn (gen_sse4_1_round<mode>2
18077 (operands[0], operands[1], GEN_INT (0x01)));
18078 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18079 ix86_expand_floorceil (operand0, operand1, true);
18081 ix86_expand_floorceildf_32 (operand0, operand1, true);
18087 if (optimize_insn_for_size_p ())
18090 op0 = gen_reg_rtx (XFmode);
18091 op1 = gen_reg_rtx (XFmode);
18092 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18093 emit_insn (gen_frndintxf2_floor (op0, op1));
18095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18100 (define_insn_and_split "*fist<mode>2_floor_1"
18101 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18102 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18103 UNSPEC_FIST_FLOOR))
18104 (clobber (reg:CC FLAGS_REG))]
18105 "TARGET_USE_FANCY_MATH_387
18106 && flag_unsafe_math_optimizations
18107 && can_create_pseudo_p ()"
18112 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18114 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18116 if (memory_operand (operands[0], VOIDmode))
18117 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18118 operands[2], operands[3]));
18121 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18122 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18123 operands[2], operands[3],
18128 [(set_attr "type" "fistp")
18129 (set_attr "i387_cw" "floor")
18130 (set_attr "mode" "<MODE>")])
18132 (define_insn "fistdi2_floor"
18133 [(set (match_operand:DI 0 "memory_operand" "=m")
18134 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18135 UNSPEC_FIST_FLOOR))
18136 (use (match_operand:HI 2 "memory_operand" "m"))
18137 (use (match_operand:HI 3 "memory_operand" "m"))
18138 (clobber (match_scratch:XF 4 "=&1f"))]
18139 "TARGET_USE_FANCY_MATH_387
18140 && flag_unsafe_math_optimizations"
18141 "* return output_fix_trunc (insn, operands, 0);"
18142 [(set_attr "type" "fistp")
18143 (set_attr "i387_cw" "floor")
18144 (set_attr "mode" "DI")])
18146 (define_insn "fistdi2_floor_with_temp"
18147 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18148 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18149 UNSPEC_FIST_FLOOR))
18150 (use (match_operand:HI 2 "memory_operand" "m,m"))
18151 (use (match_operand:HI 3 "memory_operand" "m,m"))
18152 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18153 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18154 "TARGET_USE_FANCY_MATH_387
18155 && flag_unsafe_math_optimizations"
18157 [(set_attr "type" "fistp")
18158 (set_attr "i387_cw" "floor")
18159 (set_attr "mode" "DI")])
18162 [(set (match_operand:DI 0 "register_operand" "")
18163 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18164 UNSPEC_FIST_FLOOR))
18165 (use (match_operand:HI 2 "memory_operand" ""))
18166 (use (match_operand:HI 3 "memory_operand" ""))
18167 (clobber (match_operand:DI 4 "memory_operand" ""))
18168 (clobber (match_scratch 5 ""))]
18170 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18171 (use (match_dup 2))
18172 (use (match_dup 3))
18173 (clobber (match_dup 5))])
18174 (set (match_dup 0) (match_dup 4))]
18178 [(set (match_operand:DI 0 "memory_operand" "")
18179 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18180 UNSPEC_FIST_FLOOR))
18181 (use (match_operand:HI 2 "memory_operand" ""))
18182 (use (match_operand:HI 3 "memory_operand" ""))
18183 (clobber (match_operand:DI 4 "memory_operand" ""))
18184 (clobber (match_scratch 5 ""))]
18186 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18187 (use (match_dup 2))
18188 (use (match_dup 3))
18189 (clobber (match_dup 5))])]
18192 (define_insn "fist<mode>2_floor"
18193 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18194 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18195 UNSPEC_FIST_FLOOR))
18196 (use (match_operand:HI 2 "memory_operand" "m"))
18197 (use (match_operand:HI 3 "memory_operand" "m"))]
18198 "TARGET_USE_FANCY_MATH_387
18199 && flag_unsafe_math_optimizations"
18200 "* return output_fix_trunc (insn, operands, 0);"
18201 [(set_attr "type" "fistp")
18202 (set_attr "i387_cw" "floor")
18203 (set_attr "mode" "<MODE>")])
18205 (define_insn "fist<mode>2_floor_with_temp"
18206 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18207 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18208 UNSPEC_FIST_FLOOR))
18209 (use (match_operand:HI 2 "memory_operand" "m,m"))
18210 (use (match_operand:HI 3 "memory_operand" "m,m"))
18211 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18212 "TARGET_USE_FANCY_MATH_387
18213 && flag_unsafe_math_optimizations"
18215 [(set_attr "type" "fistp")
18216 (set_attr "i387_cw" "floor")
18217 (set_attr "mode" "<MODE>")])
18220 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18221 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18222 UNSPEC_FIST_FLOOR))
18223 (use (match_operand:HI 2 "memory_operand" ""))
18224 (use (match_operand:HI 3 "memory_operand" ""))
18225 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18227 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18228 UNSPEC_FIST_FLOOR))
18229 (use (match_dup 2))
18230 (use (match_dup 3))])
18231 (set (match_dup 0) (match_dup 4))]
18235 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18236 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18237 UNSPEC_FIST_FLOOR))
18238 (use (match_operand:HI 2 "memory_operand" ""))
18239 (use (match_operand:HI 3 "memory_operand" ""))
18240 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18242 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18243 UNSPEC_FIST_FLOOR))
18244 (use (match_dup 2))
18245 (use (match_dup 3))])]
18248 (define_expand "lfloorxf<mode>2"
18249 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18250 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18251 UNSPEC_FIST_FLOOR))
18252 (clobber (reg:CC FLAGS_REG))])]
18253 "TARGET_USE_FANCY_MATH_387
18254 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18255 && flag_unsafe_math_optimizations"
18258 (define_expand "lfloor<mode>di2"
18259 [(match_operand:DI 0 "nonimmediate_operand" "")
18260 (match_operand:MODEF 1 "register_operand" "")]
18261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18262 && !flag_trapping_math"
18264 if (optimize_insn_for_size_p ())
18266 ix86_expand_lfloorceil (operand0, operand1, true);
18270 (define_expand "lfloor<mode>si2"
18271 [(match_operand:SI 0 "nonimmediate_operand" "")
18272 (match_operand:MODEF 1 "register_operand" "")]
18273 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18274 && !flag_trapping_math"
18276 if (optimize_insn_for_size_p () && TARGET_64BIT)
18278 ix86_expand_lfloorceil (operand0, operand1, true);
18282 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18283 (define_insn_and_split "frndintxf2_ceil"
18284 [(set (match_operand:XF 0 "register_operand" "")
18285 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18286 UNSPEC_FRNDINT_CEIL))
18287 (clobber (reg:CC FLAGS_REG))]
18288 "TARGET_USE_FANCY_MATH_387
18289 && flag_unsafe_math_optimizations
18290 && can_create_pseudo_p ()"
18295 ix86_optimize_mode_switching[I387_CEIL] = 1;
18297 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18298 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18300 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18301 operands[2], operands[3]));
18304 [(set_attr "type" "frndint")
18305 (set_attr "i387_cw" "ceil")
18306 (set_attr "mode" "XF")])
18308 (define_insn "frndintxf2_ceil_i387"
18309 [(set (match_operand:XF 0 "register_operand" "=f")
18310 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18311 UNSPEC_FRNDINT_CEIL))
18312 (use (match_operand:HI 2 "memory_operand" "m"))
18313 (use (match_operand:HI 3 "memory_operand" "m"))]
18314 "TARGET_USE_FANCY_MATH_387
18315 && flag_unsafe_math_optimizations"
18316 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18317 [(set_attr "type" "frndint")
18318 (set_attr "i387_cw" "ceil")
18319 (set_attr "mode" "XF")])
18321 (define_expand "ceilxf2"
18322 [(use (match_operand:XF 0 "register_operand" ""))
18323 (use (match_operand:XF 1 "register_operand" ""))]
18324 "TARGET_USE_FANCY_MATH_387
18325 && flag_unsafe_math_optimizations"
18327 if (optimize_insn_for_size_p ())
18329 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18333 (define_expand "ceil<mode>2"
18334 [(use (match_operand:MODEF 0 "register_operand" ""))
18335 (use (match_operand:MODEF 1 "register_operand" ""))]
18336 "(TARGET_USE_FANCY_MATH_387
18337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18338 || TARGET_MIX_SSE_I387)
18339 && flag_unsafe_math_optimizations)
18340 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18341 && !flag_trapping_math)"
18343 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18344 && !flag_trapping_math
18345 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18348 emit_insn (gen_sse4_1_round<mode>2
18349 (operands[0], operands[1], GEN_INT (0x02)));
18350 else if (optimize_insn_for_size_p ())
18352 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18353 ix86_expand_floorceil (operand0, operand1, false);
18355 ix86_expand_floorceildf_32 (operand0, operand1, false);
18361 if (optimize_insn_for_size_p ())
18364 op0 = gen_reg_rtx (XFmode);
18365 op1 = gen_reg_rtx (XFmode);
18366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18367 emit_insn (gen_frndintxf2_ceil (op0, op1));
18369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18374 (define_insn_and_split "*fist<mode>2_ceil_1"
18375 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18376 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18378 (clobber (reg:CC FLAGS_REG))]
18379 "TARGET_USE_FANCY_MATH_387
18380 && flag_unsafe_math_optimizations
18381 && can_create_pseudo_p ()"
18386 ix86_optimize_mode_switching[I387_CEIL] = 1;
18388 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18389 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18390 if (memory_operand (operands[0], VOIDmode))
18391 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18392 operands[2], operands[3]));
18395 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18396 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18397 operands[2], operands[3],
18402 [(set_attr "type" "fistp")
18403 (set_attr "i387_cw" "ceil")
18404 (set_attr "mode" "<MODE>")])
18406 (define_insn "fistdi2_ceil"
18407 [(set (match_operand:DI 0 "memory_operand" "=m")
18408 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18410 (use (match_operand:HI 2 "memory_operand" "m"))
18411 (use (match_operand:HI 3 "memory_operand" "m"))
18412 (clobber (match_scratch:XF 4 "=&1f"))]
18413 "TARGET_USE_FANCY_MATH_387
18414 && flag_unsafe_math_optimizations"
18415 "* return output_fix_trunc (insn, operands, 0);"
18416 [(set_attr "type" "fistp")
18417 (set_attr "i387_cw" "ceil")
18418 (set_attr "mode" "DI")])
18420 (define_insn "fistdi2_ceil_with_temp"
18421 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18422 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18424 (use (match_operand:HI 2 "memory_operand" "m,m"))
18425 (use (match_operand:HI 3 "memory_operand" "m,m"))
18426 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18427 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18428 "TARGET_USE_FANCY_MATH_387
18429 && flag_unsafe_math_optimizations"
18431 [(set_attr "type" "fistp")
18432 (set_attr "i387_cw" "ceil")
18433 (set_attr "mode" "DI")])
18436 [(set (match_operand:DI 0 "register_operand" "")
18437 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18439 (use (match_operand:HI 2 "memory_operand" ""))
18440 (use (match_operand:HI 3 "memory_operand" ""))
18441 (clobber (match_operand:DI 4 "memory_operand" ""))
18442 (clobber (match_scratch 5 ""))]
18444 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18445 (use (match_dup 2))
18446 (use (match_dup 3))
18447 (clobber (match_dup 5))])
18448 (set (match_dup 0) (match_dup 4))]
18452 [(set (match_operand:DI 0 "memory_operand" "")
18453 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18455 (use (match_operand:HI 2 "memory_operand" ""))
18456 (use (match_operand:HI 3 "memory_operand" ""))
18457 (clobber (match_operand:DI 4 "memory_operand" ""))
18458 (clobber (match_scratch 5 ""))]
18460 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18461 (use (match_dup 2))
18462 (use (match_dup 3))
18463 (clobber (match_dup 5))])]
18466 (define_insn "fist<mode>2_ceil"
18467 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18468 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18470 (use (match_operand:HI 2 "memory_operand" "m"))
18471 (use (match_operand:HI 3 "memory_operand" "m"))]
18472 "TARGET_USE_FANCY_MATH_387
18473 && flag_unsafe_math_optimizations"
18474 "* return output_fix_trunc (insn, operands, 0);"
18475 [(set_attr "type" "fistp")
18476 (set_attr "i387_cw" "ceil")
18477 (set_attr "mode" "<MODE>")])
18479 (define_insn "fist<mode>2_ceil_with_temp"
18480 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18481 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18483 (use (match_operand:HI 2 "memory_operand" "m,m"))
18484 (use (match_operand:HI 3 "memory_operand" "m,m"))
18485 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18486 "TARGET_USE_FANCY_MATH_387
18487 && flag_unsafe_math_optimizations"
18489 [(set_attr "type" "fistp")
18490 (set_attr "i387_cw" "ceil")
18491 (set_attr "mode" "<MODE>")])
18494 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18495 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18497 (use (match_operand:HI 2 "memory_operand" ""))
18498 (use (match_operand:HI 3 "memory_operand" ""))
18499 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18501 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18503 (use (match_dup 2))
18504 (use (match_dup 3))])
18505 (set (match_dup 0) (match_dup 4))]
18509 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18510 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18512 (use (match_operand:HI 2 "memory_operand" ""))
18513 (use (match_operand:HI 3 "memory_operand" ""))
18514 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18516 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18518 (use (match_dup 2))
18519 (use (match_dup 3))])]
18522 (define_expand "lceilxf<mode>2"
18523 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18524 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18526 (clobber (reg:CC FLAGS_REG))])]
18527 "TARGET_USE_FANCY_MATH_387
18528 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18529 && flag_unsafe_math_optimizations"
18532 (define_expand "lceil<mode>di2"
18533 [(match_operand:DI 0 "nonimmediate_operand" "")
18534 (match_operand:MODEF 1 "register_operand" "")]
18535 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18536 && !flag_trapping_math"
18538 ix86_expand_lfloorceil (operand0, operand1, false);
18542 (define_expand "lceil<mode>si2"
18543 [(match_operand:SI 0 "nonimmediate_operand" "")
18544 (match_operand:MODEF 1 "register_operand" "")]
18545 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18546 && !flag_trapping_math"
18548 ix86_expand_lfloorceil (operand0, operand1, false);
18552 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18553 (define_insn_and_split "frndintxf2_trunc"
18554 [(set (match_operand:XF 0 "register_operand" "")
18555 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18556 UNSPEC_FRNDINT_TRUNC))
18557 (clobber (reg:CC FLAGS_REG))]
18558 "TARGET_USE_FANCY_MATH_387
18559 && flag_unsafe_math_optimizations
18560 && can_create_pseudo_p ()"
18565 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18567 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18568 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18570 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18571 operands[2], operands[3]));
18574 [(set_attr "type" "frndint")
18575 (set_attr "i387_cw" "trunc")
18576 (set_attr "mode" "XF")])
18578 (define_insn "frndintxf2_trunc_i387"
18579 [(set (match_operand:XF 0 "register_operand" "=f")
18580 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18581 UNSPEC_FRNDINT_TRUNC))
18582 (use (match_operand:HI 2 "memory_operand" "m"))
18583 (use (match_operand:HI 3 "memory_operand" "m"))]
18584 "TARGET_USE_FANCY_MATH_387
18585 && flag_unsafe_math_optimizations"
18586 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18587 [(set_attr "type" "frndint")
18588 (set_attr "i387_cw" "trunc")
18589 (set_attr "mode" "XF")])
18591 (define_expand "btruncxf2"
18592 [(use (match_operand:XF 0 "register_operand" ""))
18593 (use (match_operand:XF 1 "register_operand" ""))]
18594 "TARGET_USE_FANCY_MATH_387
18595 && flag_unsafe_math_optimizations"
18597 if (optimize_insn_for_size_p ())
18599 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18603 (define_expand "btrunc<mode>2"
18604 [(use (match_operand:MODEF 0 "register_operand" ""))
18605 (use (match_operand:MODEF 1 "register_operand" ""))]
18606 "(TARGET_USE_FANCY_MATH_387
18607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18608 || TARGET_MIX_SSE_I387)
18609 && flag_unsafe_math_optimizations)
18610 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18611 && !flag_trapping_math)"
18613 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18614 && !flag_trapping_math
18615 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18618 emit_insn (gen_sse4_1_round<mode>2
18619 (operands[0], operands[1], GEN_INT (0x03)));
18620 else if (optimize_insn_for_size_p ())
18622 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18623 ix86_expand_trunc (operand0, operand1);
18625 ix86_expand_truncdf_32 (operand0, operand1);
18631 if (optimize_insn_for_size_p ())
18634 op0 = gen_reg_rtx (XFmode);
18635 op1 = gen_reg_rtx (XFmode);
18636 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18637 emit_insn (gen_frndintxf2_trunc (op0, op1));
18639 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18644 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18645 (define_insn_and_split "frndintxf2_mask_pm"
18646 [(set (match_operand:XF 0 "register_operand" "")
18647 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18648 UNSPEC_FRNDINT_MASK_PM))
18649 (clobber (reg:CC FLAGS_REG))]
18650 "TARGET_USE_FANCY_MATH_387
18651 && flag_unsafe_math_optimizations
18652 && can_create_pseudo_p ()"
18657 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18659 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18660 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18662 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18663 operands[2], operands[3]));
18666 [(set_attr "type" "frndint")
18667 (set_attr "i387_cw" "mask_pm")
18668 (set_attr "mode" "XF")])
18670 (define_insn "frndintxf2_mask_pm_i387"
18671 [(set (match_operand:XF 0 "register_operand" "=f")
18672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18673 UNSPEC_FRNDINT_MASK_PM))
18674 (use (match_operand:HI 2 "memory_operand" "m"))
18675 (use (match_operand:HI 3 "memory_operand" "m"))]
18676 "TARGET_USE_FANCY_MATH_387
18677 && flag_unsafe_math_optimizations"
18678 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18679 [(set_attr "type" "frndint")
18680 (set_attr "i387_cw" "mask_pm")
18681 (set_attr "mode" "XF")])
18683 (define_expand "nearbyintxf2"
18684 [(use (match_operand:XF 0 "register_operand" ""))
18685 (use (match_operand:XF 1 "register_operand" ""))]
18686 "TARGET_USE_FANCY_MATH_387
18687 && flag_unsafe_math_optimizations"
18689 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18694 (define_expand "nearbyint<mode>2"
18695 [(use (match_operand:MODEF 0 "register_operand" ""))
18696 (use (match_operand:MODEF 1 "register_operand" ""))]
18697 "TARGET_USE_FANCY_MATH_387
18698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18699 || TARGET_MIX_SSE_I387)
18700 && flag_unsafe_math_optimizations"
18702 rtx op0 = gen_reg_rtx (XFmode);
18703 rtx op1 = gen_reg_rtx (XFmode);
18705 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18706 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18708 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18712 (define_insn "fxam<mode>2_i387"
18713 [(set (match_operand:HI 0 "register_operand" "=a")
18715 [(match_operand:X87MODEF 1 "register_operand" "f")]
18717 "TARGET_USE_FANCY_MATH_387"
18718 "fxam\n\tfnstsw\t%0"
18719 [(set_attr "type" "multi")
18720 (set_attr "length" "4")
18721 (set_attr "unit" "i387")
18722 (set_attr "mode" "<MODE>")])
18724 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18725 [(set (match_operand:HI 0 "register_operand" "")
18727 [(match_operand:MODEF 1 "memory_operand" "")]
18729 "TARGET_USE_FANCY_MATH_387
18730 && can_create_pseudo_p ()"
18733 [(set (match_dup 2)(match_dup 1))
18735 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18737 operands[2] = gen_reg_rtx (<MODE>mode);
18739 MEM_VOLATILE_P (operands[1]) = 1;
18741 [(set_attr "type" "multi")
18742 (set_attr "unit" "i387")
18743 (set_attr "mode" "<MODE>")])
18745 (define_expand "isinfxf2"
18746 [(use (match_operand:SI 0 "register_operand" ""))
18747 (use (match_operand:XF 1 "register_operand" ""))]
18748 "TARGET_USE_FANCY_MATH_387
18749 && TARGET_C99_FUNCTIONS"
18751 rtx mask = GEN_INT (0x45);
18752 rtx val = GEN_INT (0x05);
18756 rtx scratch = gen_reg_rtx (HImode);
18757 rtx res = gen_reg_rtx (QImode);
18759 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18761 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18762 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18763 cond = gen_rtx_fmt_ee (EQ, QImode,
18764 gen_rtx_REG (CCmode, FLAGS_REG),
18766 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18767 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18771 (define_expand "isinf<mode>2"
18772 [(use (match_operand:SI 0 "register_operand" ""))
18773 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18774 "TARGET_USE_FANCY_MATH_387
18775 && TARGET_C99_FUNCTIONS
18776 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18778 rtx mask = GEN_INT (0x45);
18779 rtx val = GEN_INT (0x05);
18783 rtx scratch = gen_reg_rtx (HImode);
18784 rtx res = gen_reg_rtx (QImode);
18786 /* Remove excess precision by forcing value through memory. */
18787 if (memory_operand (operands[1], VOIDmode))
18788 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18791 enum ix86_stack_slot slot = (virtuals_instantiated
18794 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18796 emit_move_insn (temp, operands[1]);
18797 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18800 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18801 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18802 cond = gen_rtx_fmt_ee (EQ, QImode,
18803 gen_rtx_REG (CCmode, FLAGS_REG),
18805 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18806 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18810 (define_expand "signbit<mode>2"
18811 [(use (match_operand:SI 0 "register_operand" ""))
18812 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18813 "TARGET_USE_FANCY_MATH_387
18814 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18816 rtx mask = GEN_INT (0x0200);
18818 rtx scratch = gen_reg_rtx (HImode);
18820 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18821 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18825 ;; Block operation instructions
18828 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18831 [(set_attr "length" "1")
18832 (set_attr "length_immediate" "0")
18833 (set_attr "modrm" "0")])
18835 (define_expand "movmemsi"
18836 [(use (match_operand:BLK 0 "memory_operand" ""))
18837 (use (match_operand:BLK 1 "memory_operand" ""))
18838 (use (match_operand:SI 2 "nonmemory_operand" ""))
18839 (use (match_operand:SI 3 "const_int_operand" ""))
18840 (use (match_operand:SI 4 "const_int_operand" ""))
18841 (use (match_operand:SI 5 "const_int_operand" ""))]
18844 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18845 operands[4], operands[5]))
18851 (define_expand "movmemdi"
18852 [(use (match_operand:BLK 0 "memory_operand" ""))
18853 (use (match_operand:BLK 1 "memory_operand" ""))
18854 (use (match_operand:DI 2 "nonmemory_operand" ""))
18855 (use (match_operand:DI 3 "const_int_operand" ""))
18856 (use (match_operand:SI 4 "const_int_operand" ""))
18857 (use (match_operand:SI 5 "const_int_operand" ""))]
18860 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18861 operands[4], operands[5]))
18867 ;; Most CPUs don't like single string operations
18868 ;; Handle this case here to simplify previous expander.
18870 (define_expand "strmov"
18871 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18872 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18873 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18874 (clobber (reg:CC FLAGS_REG))])
18875 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18876 (clobber (reg:CC FLAGS_REG))])]
18879 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18881 /* If .md ever supports :P for Pmode, these can be directly
18882 in the pattern above. */
18883 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18884 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18886 /* Can't use this if the user has appropriated esi or edi. */
18887 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18888 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18890 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18891 operands[2], operands[3],
18892 operands[5], operands[6]));
18896 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18899 (define_expand "strmov_singleop"
18900 [(parallel [(set (match_operand 1 "memory_operand" "")
18901 (match_operand 3 "memory_operand" ""))
18902 (set (match_operand 0 "register_operand" "")
18903 (match_operand 4 "" ""))
18904 (set (match_operand 2 "register_operand" "")
18905 (match_operand 5 "" ""))])]
18907 "ix86_current_function_needs_cld = 1;")
18909 (define_insn "*strmovdi_rex_1"
18910 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18911 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18912 (set (match_operand:DI 0 "register_operand" "=D")
18913 (plus:DI (match_dup 2)
18915 (set (match_operand:DI 1 "register_operand" "=S")
18916 (plus:DI (match_dup 3)
18920 [(set_attr "type" "str")
18921 (set_attr "mode" "DI")
18922 (set_attr "memory" "both")])
18924 (define_insn "*strmovsi_1"
18925 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18926 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18927 (set (match_operand:SI 0 "register_operand" "=D")
18928 (plus:SI (match_dup 2)
18930 (set (match_operand:SI 1 "register_operand" "=S")
18931 (plus:SI (match_dup 3)
18935 [(set_attr "type" "str")
18936 (set_attr "mode" "SI")
18937 (set_attr "memory" "both")])
18939 (define_insn "*strmovsi_rex_1"
18940 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18941 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18942 (set (match_operand:DI 0 "register_operand" "=D")
18943 (plus:DI (match_dup 2)
18945 (set (match_operand:DI 1 "register_operand" "=S")
18946 (plus:DI (match_dup 3)
18950 [(set_attr "type" "str")
18951 (set_attr "mode" "SI")
18952 (set_attr "memory" "both")])
18954 (define_insn "*strmovhi_1"
18955 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18956 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18957 (set (match_operand:SI 0 "register_operand" "=D")
18958 (plus:SI (match_dup 2)
18960 (set (match_operand:SI 1 "register_operand" "=S")
18961 (plus:SI (match_dup 3)
18965 [(set_attr "type" "str")
18966 (set_attr "memory" "both")
18967 (set_attr "mode" "HI")])
18969 (define_insn "*strmovhi_rex_1"
18970 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18971 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18972 (set (match_operand:DI 0 "register_operand" "=D")
18973 (plus:DI (match_dup 2)
18975 (set (match_operand:DI 1 "register_operand" "=S")
18976 (plus:DI (match_dup 3)
18980 [(set_attr "type" "str")
18981 (set_attr "memory" "both")
18982 (set_attr "mode" "HI")])
18984 (define_insn "*strmovqi_1"
18985 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18986 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18987 (set (match_operand:SI 0 "register_operand" "=D")
18988 (plus:SI (match_dup 2)
18990 (set (match_operand:SI 1 "register_operand" "=S")
18991 (plus:SI (match_dup 3)
18995 [(set_attr "type" "str")
18996 (set_attr "memory" "both")
18997 (set_attr "mode" "QI")])
18999 (define_insn "*strmovqi_rex_1"
19000 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19001 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19002 (set (match_operand:DI 0 "register_operand" "=D")
19003 (plus:DI (match_dup 2)
19005 (set (match_operand:DI 1 "register_operand" "=S")
19006 (plus:DI (match_dup 3)
19010 [(set_attr "type" "str")
19011 (set_attr "memory" "both")
19012 (set_attr "prefix_rex" "0")
19013 (set_attr "mode" "QI")])
19015 (define_expand "rep_mov"
19016 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19017 (set (match_operand 0 "register_operand" "")
19018 (match_operand 5 "" ""))
19019 (set (match_operand 2 "register_operand" "")
19020 (match_operand 6 "" ""))
19021 (set (match_operand 1 "memory_operand" "")
19022 (match_operand 3 "memory_operand" ""))
19023 (use (match_dup 4))])]
19025 "ix86_current_function_needs_cld = 1;")
19027 (define_insn "*rep_movdi_rex64"
19028 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19029 (set (match_operand:DI 0 "register_operand" "=D")
19030 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19032 (match_operand:DI 3 "register_operand" "0")))
19033 (set (match_operand:DI 1 "register_operand" "=S")
19034 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19035 (match_operand:DI 4 "register_operand" "1")))
19036 (set (mem:BLK (match_dup 3))
19037 (mem:BLK (match_dup 4)))
19038 (use (match_dup 5))]
19041 [(set_attr "type" "str")
19042 (set_attr "prefix_rep" "1")
19043 (set_attr "memory" "both")
19044 (set_attr "mode" "DI")])
19046 (define_insn "*rep_movsi"
19047 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19048 (set (match_operand:SI 0 "register_operand" "=D")
19049 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19051 (match_operand:SI 3 "register_operand" "0")))
19052 (set (match_operand:SI 1 "register_operand" "=S")
19053 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19054 (match_operand:SI 4 "register_operand" "1")))
19055 (set (mem:BLK (match_dup 3))
19056 (mem:BLK (match_dup 4)))
19057 (use (match_dup 5))]
19060 [(set_attr "type" "str")
19061 (set_attr "prefix_rep" "1")
19062 (set_attr "memory" "both")
19063 (set_attr "mode" "SI")])
19065 (define_insn "*rep_movsi_rex64"
19066 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19067 (set (match_operand:DI 0 "register_operand" "=D")
19068 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19070 (match_operand:DI 3 "register_operand" "0")))
19071 (set (match_operand:DI 1 "register_operand" "=S")
19072 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19073 (match_operand:DI 4 "register_operand" "1")))
19074 (set (mem:BLK (match_dup 3))
19075 (mem:BLK (match_dup 4)))
19076 (use (match_dup 5))]
19079 [(set_attr "type" "str")
19080 (set_attr "prefix_rep" "1")
19081 (set_attr "memory" "both")
19082 (set_attr "mode" "SI")])
19084 (define_insn "*rep_movqi"
19085 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19086 (set (match_operand:SI 0 "register_operand" "=D")
19087 (plus:SI (match_operand:SI 3 "register_operand" "0")
19088 (match_operand:SI 5 "register_operand" "2")))
19089 (set (match_operand:SI 1 "register_operand" "=S")
19090 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19091 (set (mem:BLK (match_dup 3))
19092 (mem:BLK (match_dup 4)))
19093 (use (match_dup 5))]
19096 [(set_attr "type" "str")
19097 (set_attr "prefix_rep" "1")
19098 (set_attr "memory" "both")
19099 (set_attr "mode" "SI")])
19101 (define_insn "*rep_movqi_rex64"
19102 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19103 (set (match_operand:DI 0 "register_operand" "=D")
19104 (plus:DI (match_operand:DI 3 "register_operand" "0")
19105 (match_operand:DI 5 "register_operand" "2")))
19106 (set (match_operand:DI 1 "register_operand" "=S")
19107 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19108 (set (mem:BLK (match_dup 3))
19109 (mem:BLK (match_dup 4)))
19110 (use (match_dup 5))]
19113 [(set_attr "type" "str")
19114 (set_attr "prefix_rep" "1")
19115 (set_attr "memory" "both")
19116 (set_attr "mode" "SI")])
19118 (define_expand "setmemsi"
19119 [(use (match_operand:BLK 0 "memory_operand" ""))
19120 (use (match_operand:SI 1 "nonmemory_operand" ""))
19121 (use (match_operand 2 "const_int_operand" ""))
19122 (use (match_operand 3 "const_int_operand" ""))
19123 (use (match_operand:SI 4 "const_int_operand" ""))
19124 (use (match_operand:SI 5 "const_int_operand" ""))]
19127 if (ix86_expand_setmem (operands[0], operands[1],
19128 operands[2], operands[3],
19129 operands[4], operands[5]))
19135 (define_expand "setmemdi"
19136 [(use (match_operand:BLK 0 "memory_operand" ""))
19137 (use (match_operand:DI 1 "nonmemory_operand" ""))
19138 (use (match_operand 2 "const_int_operand" ""))
19139 (use (match_operand 3 "const_int_operand" ""))
19140 (use (match_operand 4 "const_int_operand" ""))
19141 (use (match_operand 5 "const_int_operand" ""))]
19144 if (ix86_expand_setmem (operands[0], operands[1],
19145 operands[2], operands[3],
19146 operands[4], operands[5]))
19152 ;; Most CPUs don't like single string operations
19153 ;; Handle this case here to simplify previous expander.
19155 (define_expand "strset"
19156 [(set (match_operand 1 "memory_operand" "")
19157 (match_operand 2 "register_operand" ""))
19158 (parallel [(set (match_operand 0 "register_operand" "")
19160 (clobber (reg:CC FLAGS_REG))])]
19163 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19164 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19166 /* If .md ever supports :P for Pmode, this can be directly
19167 in the pattern above. */
19168 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19169 GEN_INT (GET_MODE_SIZE (GET_MODE
19171 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19173 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19179 (define_expand "strset_singleop"
19180 [(parallel [(set (match_operand 1 "memory_operand" "")
19181 (match_operand 2 "register_operand" ""))
19182 (set (match_operand 0 "register_operand" "")
19183 (match_operand 3 "" ""))])]
19185 "ix86_current_function_needs_cld = 1;")
19187 (define_insn "*strsetdi_rex_1"
19188 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19189 (match_operand:DI 2 "register_operand" "a"))
19190 (set (match_operand:DI 0 "register_operand" "=D")
19191 (plus:DI (match_dup 1)
19195 [(set_attr "type" "str")
19196 (set_attr "memory" "store")
19197 (set_attr "mode" "DI")])
19199 (define_insn "*strsetsi_1"
19200 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19201 (match_operand:SI 2 "register_operand" "a"))
19202 (set (match_operand:SI 0 "register_operand" "=D")
19203 (plus:SI (match_dup 1)
19207 [(set_attr "type" "str")
19208 (set_attr "memory" "store")
19209 (set_attr "mode" "SI")])
19211 (define_insn "*strsetsi_rex_1"
19212 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19213 (match_operand:SI 2 "register_operand" "a"))
19214 (set (match_operand:DI 0 "register_operand" "=D")
19215 (plus:DI (match_dup 1)
19219 [(set_attr "type" "str")
19220 (set_attr "memory" "store")
19221 (set_attr "mode" "SI")])
19223 (define_insn "*strsethi_1"
19224 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19225 (match_operand:HI 2 "register_operand" "a"))
19226 (set (match_operand:SI 0 "register_operand" "=D")
19227 (plus:SI (match_dup 1)
19231 [(set_attr "type" "str")
19232 (set_attr "memory" "store")
19233 (set_attr "mode" "HI")])
19235 (define_insn "*strsethi_rex_1"
19236 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19237 (match_operand:HI 2 "register_operand" "a"))
19238 (set (match_operand:DI 0 "register_operand" "=D")
19239 (plus:DI (match_dup 1)
19243 [(set_attr "type" "str")
19244 (set_attr "memory" "store")
19245 (set_attr "mode" "HI")])
19247 (define_insn "*strsetqi_1"
19248 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19249 (match_operand:QI 2 "register_operand" "a"))
19250 (set (match_operand:SI 0 "register_operand" "=D")
19251 (plus:SI (match_dup 1)
19255 [(set_attr "type" "str")
19256 (set_attr "memory" "store")
19257 (set_attr "mode" "QI")])
19259 (define_insn "*strsetqi_rex_1"
19260 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19261 (match_operand:QI 2 "register_operand" "a"))
19262 (set (match_operand:DI 0 "register_operand" "=D")
19263 (plus:DI (match_dup 1)
19267 [(set_attr "type" "str")
19268 (set_attr "memory" "store")
19269 (set_attr "prefix_rex" "0")
19270 (set_attr "mode" "QI")])
19272 (define_expand "rep_stos"
19273 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19274 (set (match_operand 0 "register_operand" "")
19275 (match_operand 4 "" ""))
19276 (set (match_operand 2 "memory_operand" "") (const_int 0))
19277 (use (match_operand 3 "register_operand" ""))
19278 (use (match_dup 1))])]
19280 "ix86_current_function_needs_cld = 1;")
19282 (define_insn "*rep_stosdi_rex64"
19283 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19284 (set (match_operand:DI 0 "register_operand" "=D")
19285 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19287 (match_operand:DI 3 "register_operand" "0")))
19288 (set (mem:BLK (match_dup 3))
19290 (use (match_operand:DI 2 "register_operand" "a"))
19291 (use (match_dup 4))]
19294 [(set_attr "type" "str")
19295 (set_attr "prefix_rep" "1")
19296 (set_attr "memory" "store")
19297 (set_attr "mode" "DI")])
19299 (define_insn "*rep_stossi"
19300 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19301 (set (match_operand:SI 0 "register_operand" "=D")
19302 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19304 (match_operand:SI 3 "register_operand" "0")))
19305 (set (mem:BLK (match_dup 3))
19307 (use (match_operand:SI 2 "register_operand" "a"))
19308 (use (match_dup 4))]
19311 [(set_attr "type" "str")
19312 (set_attr "prefix_rep" "1")
19313 (set_attr "memory" "store")
19314 (set_attr "mode" "SI")])
19316 (define_insn "*rep_stossi_rex64"
19317 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19318 (set (match_operand:DI 0 "register_operand" "=D")
19319 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19321 (match_operand:DI 3 "register_operand" "0")))
19322 (set (mem:BLK (match_dup 3))
19324 (use (match_operand:SI 2 "register_operand" "a"))
19325 (use (match_dup 4))]
19328 [(set_attr "type" "str")
19329 (set_attr "prefix_rep" "1")
19330 (set_attr "memory" "store")
19331 (set_attr "mode" "SI")])
19333 (define_insn "*rep_stosqi"
19334 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19335 (set (match_operand:SI 0 "register_operand" "=D")
19336 (plus:SI (match_operand:SI 3 "register_operand" "0")
19337 (match_operand:SI 4 "register_operand" "1")))
19338 (set (mem:BLK (match_dup 3))
19340 (use (match_operand:QI 2 "register_operand" "a"))
19341 (use (match_dup 4))]
19344 [(set_attr "type" "str")
19345 (set_attr "prefix_rep" "1")
19346 (set_attr "memory" "store")
19347 (set_attr "mode" "QI")])
19349 (define_insn "*rep_stosqi_rex64"
19350 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19351 (set (match_operand:DI 0 "register_operand" "=D")
19352 (plus:DI (match_operand:DI 3 "register_operand" "0")
19353 (match_operand:DI 4 "register_operand" "1")))
19354 (set (mem:BLK (match_dup 3))
19356 (use (match_operand:QI 2 "register_operand" "a"))
19357 (use (match_dup 4))]
19360 [(set_attr "type" "str")
19361 (set_attr "prefix_rep" "1")
19362 (set_attr "memory" "store")
19363 (set_attr "prefix_rex" "0")
19364 (set_attr "mode" "QI")])
19366 (define_expand "cmpstrnsi"
19367 [(set (match_operand:SI 0 "register_operand" "")
19368 (compare:SI (match_operand:BLK 1 "general_operand" "")
19369 (match_operand:BLK 2 "general_operand" "")))
19370 (use (match_operand 3 "general_operand" ""))
19371 (use (match_operand 4 "immediate_operand" ""))]
19374 rtx addr1, addr2, out, outlow, count, countreg, align;
19376 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19379 /* Can't use this if the user has appropriated esi or edi. */
19380 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19385 out = gen_reg_rtx (SImode);
19387 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19388 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19389 if (addr1 != XEXP (operands[1], 0))
19390 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19391 if (addr2 != XEXP (operands[2], 0))
19392 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19394 count = operands[3];
19395 countreg = ix86_zero_extend_to_Pmode (count);
19397 /* %%% Iff we are testing strict equality, we can use known alignment
19398 to good advantage. This may be possible with combine, particularly
19399 once cc0 is dead. */
19400 align = operands[4];
19402 if (CONST_INT_P (count))
19404 if (INTVAL (count) == 0)
19406 emit_move_insn (operands[0], const0_rtx);
19409 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19410 operands[1], operands[2]));
19415 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19417 emit_insn (gen_cmpsi_1 (countreg, countreg));
19418 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19419 operands[1], operands[2]));
19422 outlow = gen_lowpart (QImode, out);
19423 emit_insn (gen_cmpintqi (outlow));
19424 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19426 if (operands[0] != out)
19427 emit_move_insn (operands[0], out);
19432 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19434 (define_expand "cmpintqi"
19435 [(set (match_dup 1)
19436 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19438 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19439 (parallel [(set (match_operand:QI 0 "register_operand" "")
19440 (minus:QI (match_dup 1)
19442 (clobber (reg:CC FLAGS_REG))])]
19444 "operands[1] = gen_reg_rtx (QImode);
19445 operands[2] = gen_reg_rtx (QImode);")
19447 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19448 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19450 (define_expand "cmpstrnqi_nz_1"
19451 [(parallel [(set (reg:CC FLAGS_REG)
19452 (compare:CC (match_operand 4 "memory_operand" "")
19453 (match_operand 5 "memory_operand" "")))
19454 (use (match_operand 2 "register_operand" ""))
19455 (use (match_operand:SI 3 "immediate_operand" ""))
19456 (clobber (match_operand 0 "register_operand" ""))
19457 (clobber (match_operand 1 "register_operand" ""))
19458 (clobber (match_dup 2))])]
19460 "ix86_current_function_needs_cld = 1;")
19462 (define_insn "*cmpstrnqi_nz_1"
19463 [(set (reg:CC FLAGS_REG)
19464 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19465 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19466 (use (match_operand:SI 6 "register_operand" "2"))
19467 (use (match_operand:SI 3 "immediate_operand" "i"))
19468 (clobber (match_operand:SI 0 "register_operand" "=S"))
19469 (clobber (match_operand:SI 1 "register_operand" "=D"))
19470 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19473 [(set_attr "type" "str")
19474 (set_attr "mode" "QI")
19475 (set_attr "prefix_rep" "1")])
19477 (define_insn "*cmpstrnqi_nz_rex_1"
19478 [(set (reg:CC FLAGS_REG)
19479 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19480 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19481 (use (match_operand:DI 6 "register_operand" "2"))
19482 (use (match_operand:SI 3 "immediate_operand" "i"))
19483 (clobber (match_operand:DI 0 "register_operand" "=S"))
19484 (clobber (match_operand:DI 1 "register_operand" "=D"))
19485 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19488 [(set_attr "type" "str")
19489 (set_attr "mode" "QI")
19490 (set_attr "prefix_rex" "0")
19491 (set_attr "prefix_rep" "1")])
19493 ;; The same, but the count is not known to not be zero.
19495 (define_expand "cmpstrnqi_1"
19496 [(parallel [(set (reg:CC FLAGS_REG)
19497 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19499 (compare:CC (match_operand 4 "memory_operand" "")
19500 (match_operand 5 "memory_operand" ""))
19502 (use (match_operand:SI 3 "immediate_operand" ""))
19503 (use (reg:CC FLAGS_REG))
19504 (clobber (match_operand 0 "register_operand" ""))
19505 (clobber (match_operand 1 "register_operand" ""))
19506 (clobber (match_dup 2))])]
19508 "ix86_current_function_needs_cld = 1;")
19510 (define_insn "*cmpstrnqi_1"
19511 [(set (reg:CC FLAGS_REG)
19512 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19514 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19515 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19517 (use (match_operand:SI 3 "immediate_operand" "i"))
19518 (use (reg:CC FLAGS_REG))
19519 (clobber (match_operand:SI 0 "register_operand" "=S"))
19520 (clobber (match_operand:SI 1 "register_operand" "=D"))
19521 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19524 [(set_attr "type" "str")
19525 (set_attr "mode" "QI")
19526 (set_attr "prefix_rep" "1")])
19528 (define_insn "*cmpstrnqi_rex_1"
19529 [(set (reg:CC FLAGS_REG)
19530 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19532 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19533 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19535 (use (match_operand:SI 3 "immediate_operand" "i"))
19536 (use (reg:CC FLAGS_REG))
19537 (clobber (match_operand:DI 0 "register_operand" "=S"))
19538 (clobber (match_operand:DI 1 "register_operand" "=D"))
19539 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19542 [(set_attr "type" "str")
19543 (set_attr "mode" "QI")
19544 (set_attr "prefix_rex" "0")
19545 (set_attr "prefix_rep" "1")])
19547 (define_expand "strlensi"
19548 [(set (match_operand:SI 0 "register_operand" "")
19549 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19550 (match_operand:QI 2 "immediate_operand" "")
19551 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19554 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19560 (define_expand "strlendi"
19561 [(set (match_operand:DI 0 "register_operand" "")
19562 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19563 (match_operand:QI 2 "immediate_operand" "")
19564 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19567 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19573 (define_expand "strlenqi_1"
19574 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19575 (clobber (match_operand 1 "register_operand" ""))
19576 (clobber (reg:CC FLAGS_REG))])]
19578 "ix86_current_function_needs_cld = 1;")
19580 (define_insn "*strlenqi_1"
19581 [(set (match_operand:SI 0 "register_operand" "=&c")
19582 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19583 (match_operand:QI 2 "register_operand" "a")
19584 (match_operand:SI 3 "immediate_operand" "i")
19585 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19586 (clobber (match_operand:SI 1 "register_operand" "=D"))
19587 (clobber (reg:CC FLAGS_REG))]
19590 [(set_attr "type" "str")
19591 (set_attr "mode" "QI")
19592 (set_attr "prefix_rep" "1")])
19594 (define_insn "*strlenqi_rex_1"
19595 [(set (match_operand:DI 0 "register_operand" "=&c")
19596 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19597 (match_operand:QI 2 "register_operand" "a")
19598 (match_operand:DI 3 "immediate_operand" "i")
19599 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19600 (clobber (match_operand:DI 1 "register_operand" "=D"))
19601 (clobber (reg:CC FLAGS_REG))]
19604 [(set_attr "type" "str")
19605 (set_attr "mode" "QI")
19606 (set_attr "prefix_rex" "0")
19607 (set_attr "prefix_rep" "1")])
19609 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19610 ;; handled in combine, but it is not currently up to the task.
19611 ;; When used for their truth value, the cmpstrn* expanders generate
19620 ;; The intermediate three instructions are unnecessary.
19622 ;; This one handles cmpstrn*_nz_1...
19625 (set (reg:CC FLAGS_REG)
19626 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19627 (mem:BLK (match_operand 5 "register_operand" ""))))
19628 (use (match_operand 6 "register_operand" ""))
19629 (use (match_operand:SI 3 "immediate_operand" ""))
19630 (clobber (match_operand 0 "register_operand" ""))
19631 (clobber (match_operand 1 "register_operand" ""))
19632 (clobber (match_operand 2 "register_operand" ""))])
19633 (set (match_operand:QI 7 "register_operand" "")
19634 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19635 (set (match_operand:QI 8 "register_operand" "")
19636 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19637 (set (reg FLAGS_REG)
19638 (compare (match_dup 7) (match_dup 8)))
19640 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19642 (set (reg:CC FLAGS_REG)
19643 (compare:CC (mem:BLK (match_dup 4))
19644 (mem:BLK (match_dup 5))))
19645 (use (match_dup 6))
19646 (use (match_dup 3))
19647 (clobber (match_dup 0))
19648 (clobber (match_dup 1))
19649 (clobber (match_dup 2))])]
19652 ;; ...and this one handles cmpstrn*_1.
19655 (set (reg:CC FLAGS_REG)
19656 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19658 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19659 (mem:BLK (match_operand 5 "register_operand" "")))
19661 (use (match_operand:SI 3 "immediate_operand" ""))
19662 (use (reg:CC FLAGS_REG))
19663 (clobber (match_operand 0 "register_operand" ""))
19664 (clobber (match_operand 1 "register_operand" ""))
19665 (clobber (match_operand 2 "register_operand" ""))])
19666 (set (match_operand:QI 7 "register_operand" "")
19667 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19668 (set (match_operand:QI 8 "register_operand" "")
19669 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19670 (set (reg FLAGS_REG)
19671 (compare (match_dup 7) (match_dup 8)))
19673 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19675 (set (reg:CC FLAGS_REG)
19676 (if_then_else:CC (ne (match_dup 6)
19678 (compare:CC (mem:BLK (match_dup 4))
19679 (mem:BLK (match_dup 5)))
19681 (use (match_dup 3))
19682 (use (reg:CC FLAGS_REG))
19683 (clobber (match_dup 0))
19684 (clobber (match_dup 1))
19685 (clobber (match_dup 2))])]
19690 ;; Conditional move instructions.
19692 (define_expand "movdicc"
19693 [(set (match_operand:DI 0 "register_operand" "")
19694 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19695 (match_operand:DI 2 "general_operand" "")
19696 (match_operand:DI 3 "general_operand" "")))]
19698 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19700 (define_insn "x86_movdicc_0_m1_rex64"
19701 [(set (match_operand:DI 0 "register_operand" "=r")
19702 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19705 (clobber (reg:CC FLAGS_REG))]
19708 ; Since we don't have the proper number of operands for an alu insn,
19709 ; fill in all the blanks.
19710 [(set_attr "type" "alu")
19711 (set_attr "use_carry" "1")
19712 (set_attr "pent_pair" "pu")
19713 (set_attr "memory" "none")
19714 (set_attr "imm_disp" "false")
19715 (set_attr "mode" "DI")
19716 (set_attr "length_immediate" "0")])
19718 (define_insn "*x86_movdicc_0_m1_se"
19719 [(set (match_operand:DI 0 "register_operand" "=r")
19720 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19723 (clobber (reg:CC FLAGS_REG))]
19726 [(set_attr "type" "alu")
19727 (set_attr "use_carry" "1")
19728 (set_attr "pent_pair" "pu")
19729 (set_attr "memory" "none")
19730 (set_attr "imm_disp" "false")
19731 (set_attr "mode" "DI")
19732 (set_attr "length_immediate" "0")])
19734 (define_insn "*movdicc_c_rex64"
19735 [(set (match_operand:DI 0 "register_operand" "=r,r")
19736 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19737 [(reg FLAGS_REG) (const_int 0)])
19738 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19739 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19740 "TARGET_64BIT && TARGET_CMOVE
19741 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19743 cmov%O2%C1\t{%2, %0|%0, %2}
19744 cmov%O2%c1\t{%3, %0|%0, %3}"
19745 [(set_attr "type" "icmov")
19746 (set_attr "mode" "DI")])
19748 (define_expand "movsicc"
19749 [(set (match_operand:SI 0 "register_operand" "")
19750 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19751 (match_operand:SI 2 "general_operand" "")
19752 (match_operand:SI 3 "general_operand" "")))]
19754 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19756 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19757 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19758 ;; So just document what we're doing explicitly.
19760 (define_insn "x86_movsicc_0_m1"
19761 [(set (match_operand:SI 0 "register_operand" "=r")
19762 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19765 (clobber (reg:CC FLAGS_REG))]
19768 ; Since we don't have the proper number of operands for an alu insn,
19769 ; fill in all the blanks.
19770 [(set_attr "type" "alu")
19771 (set_attr "use_carry" "1")
19772 (set_attr "pent_pair" "pu")
19773 (set_attr "memory" "none")
19774 (set_attr "imm_disp" "false")
19775 (set_attr "mode" "SI")
19776 (set_attr "length_immediate" "0")])
19778 (define_insn "*x86_movsicc_0_m1_se"
19779 [(set (match_operand:SI 0 "register_operand" "=r")
19780 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19783 (clobber (reg:CC FLAGS_REG))]
19786 [(set_attr "type" "alu")
19787 (set_attr "use_carry" "1")
19788 (set_attr "pent_pair" "pu")
19789 (set_attr "memory" "none")
19790 (set_attr "imm_disp" "false")
19791 (set_attr "mode" "SI")
19792 (set_attr "length_immediate" "0")])
19794 (define_insn "*movsicc_noc"
19795 [(set (match_operand:SI 0 "register_operand" "=r,r")
19796 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19797 [(reg FLAGS_REG) (const_int 0)])
19798 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19799 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19801 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19803 cmov%O2%C1\t{%2, %0|%0, %2}
19804 cmov%O2%c1\t{%3, %0|%0, %3}"
19805 [(set_attr "type" "icmov")
19806 (set_attr "mode" "SI")])
19808 (define_expand "movhicc"
19809 [(set (match_operand:HI 0 "register_operand" "")
19810 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19811 (match_operand:HI 2 "general_operand" "")
19812 (match_operand:HI 3 "general_operand" "")))]
19813 "TARGET_HIMODE_MATH"
19814 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19816 (define_insn "*movhicc_noc"
19817 [(set (match_operand:HI 0 "register_operand" "=r,r")
19818 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19819 [(reg FLAGS_REG) (const_int 0)])
19820 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19821 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19823 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19825 cmov%O2%C1\t{%2, %0|%0, %2}
19826 cmov%O2%c1\t{%3, %0|%0, %3}"
19827 [(set_attr "type" "icmov")
19828 (set_attr "mode" "HI")])
19830 (define_expand "movqicc"
19831 [(set (match_operand:QI 0 "register_operand" "")
19832 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19833 (match_operand:QI 2 "general_operand" "")
19834 (match_operand:QI 3 "general_operand" "")))]
19835 "TARGET_QIMODE_MATH"
19836 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19838 (define_insn_and_split "*movqicc_noc"
19839 [(set (match_operand:QI 0 "register_operand" "=r,r")
19840 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19841 [(match_operand 4 "flags_reg_operand" "")
19843 (match_operand:QI 2 "register_operand" "r,0")
19844 (match_operand:QI 3 "register_operand" "0,r")))]
19845 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19847 "&& reload_completed"
19848 [(set (match_dup 0)
19849 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19852 "operands[0] = gen_lowpart (SImode, operands[0]);
19853 operands[2] = gen_lowpart (SImode, operands[2]);
19854 operands[3] = gen_lowpart (SImode, operands[3]);"
19855 [(set_attr "type" "icmov")
19856 (set_attr "mode" "SI")])
19858 (define_expand "mov<mode>cc"
19859 [(set (match_operand:X87MODEF 0 "register_operand" "")
19860 (if_then_else:X87MODEF
19861 (match_operand 1 "ix86_fp_comparison_operator" "")
19862 (match_operand:X87MODEF 2 "register_operand" "")
19863 (match_operand:X87MODEF 3 "register_operand" "")))]
19864 "(TARGET_80387 && TARGET_CMOVE)
19865 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19866 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19868 (define_insn "*movsfcc_1_387"
19869 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19870 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19871 [(reg FLAGS_REG) (const_int 0)])
19872 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19873 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19874 "TARGET_80387 && TARGET_CMOVE
19875 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19877 fcmov%F1\t{%2, %0|%0, %2}
19878 fcmov%f1\t{%3, %0|%0, %3}
19879 cmov%O2%C1\t{%2, %0|%0, %2}
19880 cmov%O2%c1\t{%3, %0|%0, %3}"
19881 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19882 (set_attr "mode" "SF,SF,SI,SI")])
19884 (define_insn "*movdfcc_1"
19885 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19886 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19887 [(reg FLAGS_REG) (const_int 0)])
19888 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19889 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19890 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19891 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19893 fcmov%F1\t{%2, %0|%0, %2}
19894 fcmov%f1\t{%3, %0|%0, %3}
19897 [(set_attr "type" "fcmov,fcmov,multi,multi")
19898 (set_attr "mode" "DF")])
19900 (define_insn "*movdfcc_1_rex64"
19901 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19902 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19903 [(reg FLAGS_REG) (const_int 0)])
19904 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19905 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19906 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19907 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19909 fcmov%F1\t{%2, %0|%0, %2}
19910 fcmov%f1\t{%3, %0|%0, %3}
19911 cmov%O2%C1\t{%2, %0|%0, %2}
19912 cmov%O2%c1\t{%3, %0|%0, %3}"
19913 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19914 (set_attr "mode" "DF")])
19917 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19918 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19919 [(match_operand 4 "flags_reg_operand" "")
19921 (match_operand:DF 2 "nonimmediate_operand" "")
19922 (match_operand:DF 3 "nonimmediate_operand" "")))]
19923 "!TARGET_64BIT && reload_completed"
19924 [(set (match_dup 2)
19925 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19929 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19932 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19933 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19935 (define_insn "*movxfcc_1"
19936 [(set (match_operand:XF 0 "register_operand" "=f,f")
19937 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19938 [(reg FLAGS_REG) (const_int 0)])
19939 (match_operand:XF 2 "register_operand" "f,0")
19940 (match_operand:XF 3 "register_operand" "0,f")))]
19941 "TARGET_80387 && TARGET_CMOVE"
19943 fcmov%F1\t{%2, %0|%0, %2}
19944 fcmov%f1\t{%3, %0|%0, %3}"
19945 [(set_attr "type" "fcmov")
19946 (set_attr "mode" "XF")])
19948 ;; These versions of the min/max patterns are intentionally ignorant of
19949 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19950 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19951 ;; are undefined in this condition, we're certain this is correct.
19953 (define_insn "*avx_<code><mode>3"
19954 [(set (match_operand:MODEF 0 "register_operand" "=x")
19956 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19957 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19958 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19959 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19960 [(set_attr "type" "sseadd")
19961 (set_attr "prefix" "vex")
19962 (set_attr "mode" "<MODE>")])
19964 (define_insn "<code><mode>3"
19965 [(set (match_operand:MODEF 0 "register_operand" "=x")
19967 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19968 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19969 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19970 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19971 [(set_attr "type" "sseadd")
19972 (set_attr "mode" "<MODE>")])
19974 ;; These versions of the min/max patterns implement exactly the operations
19975 ;; min = (op1 < op2 ? op1 : op2)
19976 ;; max = (!(op1 < op2) ? op1 : op2)
19977 ;; Their operands are not commutative, and thus they may be used in the
19978 ;; presence of -0.0 and NaN.
19980 (define_insn "*avx_ieee_smin<mode>3"
19981 [(set (match_operand:MODEF 0 "register_operand" "=x")
19983 [(match_operand:MODEF 1 "register_operand" "x")
19984 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19986 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19987 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19988 [(set_attr "type" "sseadd")
19989 (set_attr "prefix" "vex")
19990 (set_attr "mode" "<MODE>")])
19992 (define_insn "*ieee_smin<mode>3"
19993 [(set (match_operand:MODEF 0 "register_operand" "=x")
19995 [(match_operand:MODEF 1 "register_operand" "0")
19996 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19998 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19999 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20000 [(set_attr "type" "sseadd")
20001 (set_attr "mode" "<MODE>")])
20003 (define_insn "*avx_ieee_smax<mode>3"
20004 [(set (match_operand:MODEF 0 "register_operand" "=x")
20006 [(match_operand:MODEF 1 "register_operand" "0")
20007 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20009 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20010 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20011 [(set_attr "type" "sseadd")
20012 (set_attr "prefix" "vex")
20013 (set_attr "mode" "<MODE>")])
20015 (define_insn "*ieee_smax<mode>3"
20016 [(set (match_operand:MODEF 0 "register_operand" "=x")
20018 [(match_operand:MODEF 1 "register_operand" "0")
20019 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20021 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20022 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20023 [(set_attr "type" "sseadd")
20024 (set_attr "mode" "<MODE>")])
20026 ;; Make two stack loads independent:
20028 ;; fld %st(0) -> fld bb
20029 ;; fmul bb fmul %st(1), %st
20031 ;; Actually we only match the last two instructions for simplicity.
20033 [(set (match_operand 0 "fp_register_operand" "")
20034 (match_operand 1 "fp_register_operand" ""))
20036 (match_operator 2 "binary_fp_operator"
20038 (match_operand 3 "memory_operand" "")]))]
20039 "REGNO (operands[0]) != REGNO (operands[1])"
20040 [(set (match_dup 0) (match_dup 3))
20041 (set (match_dup 0) (match_dup 4))]
20043 ;; The % modifier is not operational anymore in peephole2's, so we have to
20044 ;; swap the operands manually in the case of addition and multiplication.
20045 "if (COMMUTATIVE_ARITH_P (operands[2]))
20046 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20047 operands[0], operands[1]);
20049 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20050 operands[1], operands[0]);")
20052 ;; Conditional addition patterns
20053 (define_expand "add<mode>cc"
20054 [(match_operand:SWI 0 "register_operand" "")
20055 (match_operand 1 "comparison_operator" "")
20056 (match_operand:SWI 2 "register_operand" "")
20057 (match_operand:SWI 3 "const_int_operand" "")]
20059 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20062 ;; Misc patterns (?)
20064 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20065 ;; Otherwise there will be nothing to keep
20067 ;; [(set (reg ebp) (reg esp))]
20068 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20069 ;; (clobber (eflags)]
20070 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20072 ;; in proper program order.
20073 (define_insn "pro_epilogue_adjust_stack_1"
20074 [(set (match_operand:SI 0 "register_operand" "=r,r")
20075 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20076 (match_operand:SI 2 "immediate_operand" "i,i")))
20077 (clobber (reg:CC FLAGS_REG))
20078 (clobber (mem:BLK (scratch)))]
20081 switch (get_attr_type (insn))
20084 return "mov{l}\t{%1, %0|%0, %1}";
20087 if (CONST_INT_P (operands[2])
20088 && (INTVAL (operands[2]) == 128
20089 || (INTVAL (operands[2]) < 0
20090 && INTVAL (operands[2]) != -128)))
20092 operands[2] = GEN_INT (-INTVAL (operands[2]));
20093 return "sub{l}\t{%2, %0|%0, %2}";
20095 return "add{l}\t{%2, %0|%0, %2}";
20098 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20099 return "lea{l}\t{%a2, %0|%0, %a2}";
20102 gcc_unreachable ();
20105 [(set (attr "type")
20106 (cond [(and (eq_attr "alternative" "0")
20107 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20108 (const_string "alu")
20109 (match_operand:SI 2 "const0_operand" "")
20110 (const_string "imov")
20112 (const_string "lea")))
20113 (set (attr "length_immediate")
20114 (cond [(eq_attr "type" "imov")
20116 (and (eq_attr "type" "alu")
20117 (match_operand 2 "const128_operand" ""))
20120 (const_string "*")))
20121 (set_attr "mode" "SI")])
20123 (define_insn "pro_epilogue_adjust_stack_rex64"
20124 [(set (match_operand:DI 0 "register_operand" "=r,r")
20125 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20126 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20127 (clobber (reg:CC FLAGS_REG))
20128 (clobber (mem:BLK (scratch)))]
20131 switch (get_attr_type (insn))
20134 return "mov{q}\t{%1, %0|%0, %1}";
20137 if (CONST_INT_P (operands[2])
20138 /* Avoid overflows. */
20139 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20140 && (INTVAL (operands[2]) == 128
20141 || (INTVAL (operands[2]) < 0
20142 && INTVAL (operands[2]) != -128)))
20144 operands[2] = GEN_INT (-INTVAL (operands[2]));
20145 return "sub{q}\t{%2, %0|%0, %2}";
20147 return "add{q}\t{%2, %0|%0, %2}";
20150 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20151 return "lea{q}\t{%a2, %0|%0, %a2}";
20154 gcc_unreachable ();
20157 [(set (attr "type")
20158 (cond [(and (eq_attr "alternative" "0")
20159 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20160 (const_string "alu")
20161 (match_operand:DI 2 "const0_operand" "")
20162 (const_string "imov")
20164 (const_string "lea")))
20165 (set (attr "length_immediate")
20166 (cond [(eq_attr "type" "imov")
20168 (and (eq_attr "type" "alu")
20169 (match_operand 2 "const128_operand" ""))
20172 (const_string "*")))
20173 (set_attr "mode" "DI")])
20175 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20176 [(set (match_operand:DI 0 "register_operand" "=r,r")
20177 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20178 (match_operand:DI 3 "immediate_operand" "i,i")))
20179 (use (match_operand:DI 2 "register_operand" "r,r"))
20180 (clobber (reg:CC FLAGS_REG))
20181 (clobber (mem:BLK (scratch)))]
20184 switch (get_attr_type (insn))
20187 return "add{q}\t{%2, %0|%0, %2}";
20190 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20191 return "lea{q}\t{%a2, %0|%0, %a2}";
20194 gcc_unreachable ();
20197 [(set_attr "type" "alu,lea")
20198 (set_attr "mode" "DI")])
20200 (define_insn "allocate_stack_worker_32"
20201 [(set (match_operand:SI 0 "register_operand" "=a")
20202 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20203 UNSPECV_STACK_PROBE))
20204 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20205 (clobber (reg:CC FLAGS_REG))]
20206 "!TARGET_64BIT && TARGET_STACK_PROBE"
20208 [(set_attr "type" "multi")
20209 (set_attr "length" "5")])
20211 (define_insn "allocate_stack_worker_64"
20212 [(set (match_operand:DI 0 "register_operand" "=a")
20213 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20214 UNSPECV_STACK_PROBE))
20215 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20216 (clobber (reg:DI R10_REG))
20217 (clobber (reg:DI R11_REG))
20218 (clobber (reg:CC FLAGS_REG))]
20219 "TARGET_64BIT && TARGET_STACK_PROBE"
20221 [(set_attr "type" "multi")
20222 (set_attr "length" "5")])
20224 (define_expand "allocate_stack"
20225 [(match_operand 0 "register_operand" "")
20226 (match_operand 1 "general_operand" "")]
20227 "TARGET_STACK_PROBE"
20231 #ifndef CHECK_STACK_LIMIT
20232 #define CHECK_STACK_LIMIT 0
20235 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20236 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20238 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20239 stack_pointer_rtx, 0, OPTAB_DIRECT);
20240 if (x != stack_pointer_rtx)
20241 emit_move_insn (stack_pointer_rtx, x);
20245 x = copy_to_mode_reg (Pmode, operands[1]);
20247 x = gen_allocate_stack_worker_64 (x, x);
20249 x = gen_allocate_stack_worker_32 (x, x);
20253 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20257 (define_expand "builtin_setjmp_receiver"
20258 [(label_ref (match_operand 0 "" ""))]
20259 "!TARGET_64BIT && flag_pic"
20265 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20266 rtx label_rtx = gen_label_rtx ();
20267 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20268 xops[0] = xops[1] = picreg;
20269 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20270 ix86_expand_binary_operator (MINUS, SImode, xops);
20274 emit_insn (gen_set_got (pic_offset_table_rtx));
20278 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20281 [(set (match_operand 0 "register_operand" "")
20282 (match_operator 3 "promotable_binary_operator"
20283 [(match_operand 1 "register_operand" "")
20284 (match_operand 2 "aligned_operand" "")]))
20285 (clobber (reg:CC FLAGS_REG))]
20286 "! TARGET_PARTIAL_REG_STALL && reload_completed
20287 && ((GET_MODE (operands[0]) == HImode
20288 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20289 /* ??? next two lines just !satisfies_constraint_K (...) */
20290 || !CONST_INT_P (operands[2])
20291 || satisfies_constraint_K (operands[2])))
20292 || (GET_MODE (operands[0]) == QImode
20293 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20294 [(parallel [(set (match_dup 0)
20295 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20296 (clobber (reg:CC FLAGS_REG))])]
20297 "operands[0] = gen_lowpart (SImode, operands[0]);
20298 operands[1] = gen_lowpart (SImode, operands[1]);
20299 if (GET_CODE (operands[3]) != ASHIFT)
20300 operands[2] = gen_lowpart (SImode, operands[2]);
20301 PUT_MODE (operands[3], SImode);")
20303 ; Promote the QImode tests, as i386 has encoding of the AND
20304 ; instruction with 32-bit sign-extended immediate and thus the
20305 ; instruction size is unchanged, except in the %eax case for
20306 ; which it is increased by one byte, hence the ! optimize_size.
20308 [(set (match_operand 0 "flags_reg_operand" "")
20309 (match_operator 2 "compare_operator"
20310 [(and (match_operand 3 "aligned_operand" "")
20311 (match_operand 4 "const_int_operand" ""))
20313 (set (match_operand 1 "register_operand" "")
20314 (and (match_dup 3) (match_dup 4)))]
20315 "! TARGET_PARTIAL_REG_STALL && reload_completed
20316 && optimize_insn_for_speed_p ()
20317 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20318 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20319 /* Ensure that the operand will remain sign-extended immediate. */
20320 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20321 [(parallel [(set (match_dup 0)
20322 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20325 (and:SI (match_dup 3) (match_dup 4)))])]
20328 = gen_int_mode (INTVAL (operands[4])
20329 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20330 operands[1] = gen_lowpart (SImode, operands[1]);
20331 operands[3] = gen_lowpart (SImode, operands[3]);
20334 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20335 ; the TEST instruction with 32-bit sign-extended immediate and thus
20336 ; the instruction size would at least double, which is not what we
20337 ; want even with ! optimize_size.
20339 [(set (match_operand 0 "flags_reg_operand" "")
20340 (match_operator 1 "compare_operator"
20341 [(and (match_operand:HI 2 "aligned_operand" "")
20342 (match_operand:HI 3 "const_int_operand" ""))
20344 "! TARGET_PARTIAL_REG_STALL && reload_completed
20345 && ! TARGET_FAST_PREFIX
20346 && optimize_insn_for_speed_p ()
20347 /* Ensure that the operand will remain sign-extended immediate. */
20348 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20349 [(set (match_dup 0)
20350 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20354 = gen_int_mode (INTVAL (operands[3])
20355 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20356 operands[2] = gen_lowpart (SImode, operands[2]);
20360 [(set (match_operand 0 "register_operand" "")
20361 (neg (match_operand 1 "register_operand" "")))
20362 (clobber (reg:CC FLAGS_REG))]
20363 "! TARGET_PARTIAL_REG_STALL && reload_completed
20364 && (GET_MODE (operands[0]) == HImode
20365 || (GET_MODE (operands[0]) == QImode
20366 && (TARGET_PROMOTE_QImode
20367 || optimize_insn_for_size_p ())))"
20368 [(parallel [(set (match_dup 0)
20369 (neg:SI (match_dup 1)))
20370 (clobber (reg:CC FLAGS_REG))])]
20371 "operands[0] = gen_lowpart (SImode, operands[0]);
20372 operands[1] = gen_lowpart (SImode, operands[1]);")
20375 [(set (match_operand 0 "register_operand" "")
20376 (not (match_operand 1 "register_operand" "")))]
20377 "! TARGET_PARTIAL_REG_STALL && reload_completed
20378 && (GET_MODE (operands[0]) == HImode
20379 || (GET_MODE (operands[0]) == QImode
20380 && (TARGET_PROMOTE_QImode
20381 || optimize_insn_for_size_p ())))"
20382 [(set (match_dup 0)
20383 (not:SI (match_dup 1)))]
20384 "operands[0] = gen_lowpart (SImode, operands[0]);
20385 operands[1] = gen_lowpart (SImode, operands[1]);")
20388 [(set (match_operand 0 "register_operand" "")
20389 (if_then_else (match_operator 1 "comparison_operator"
20390 [(reg FLAGS_REG) (const_int 0)])
20391 (match_operand 2 "register_operand" "")
20392 (match_operand 3 "register_operand" "")))]
20393 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20394 && (GET_MODE (operands[0]) == HImode
20395 || (GET_MODE (operands[0]) == QImode
20396 && (TARGET_PROMOTE_QImode
20397 || optimize_insn_for_size_p ())))"
20398 [(set (match_dup 0)
20399 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20400 "operands[0] = gen_lowpart (SImode, operands[0]);
20401 operands[2] = gen_lowpart (SImode, operands[2]);
20402 operands[3] = gen_lowpart (SImode, operands[3]);")
20405 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20406 ;; transform a complex memory operation into two memory to register operations.
20408 ;; Don't push memory operands
20410 [(set (match_operand:SI 0 "push_operand" "")
20411 (match_operand:SI 1 "memory_operand" ""))
20412 (match_scratch:SI 2 "r")]
20413 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20414 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20415 [(set (match_dup 2) (match_dup 1))
20416 (set (match_dup 0) (match_dup 2))]
20420 [(set (match_operand:DI 0 "push_operand" "")
20421 (match_operand:DI 1 "memory_operand" ""))
20422 (match_scratch:DI 2 "r")]
20423 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20424 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20425 [(set (match_dup 2) (match_dup 1))
20426 (set (match_dup 0) (match_dup 2))]
20429 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20432 [(set (match_operand:SF 0 "push_operand" "")
20433 (match_operand:SF 1 "memory_operand" ""))
20434 (match_scratch:SF 2 "r")]
20435 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20436 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20437 [(set (match_dup 2) (match_dup 1))
20438 (set (match_dup 0) (match_dup 2))]
20442 [(set (match_operand:HI 0 "push_operand" "")
20443 (match_operand:HI 1 "memory_operand" ""))
20444 (match_scratch:HI 2 "r")]
20445 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20446 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20447 [(set (match_dup 2) (match_dup 1))
20448 (set (match_dup 0) (match_dup 2))]
20452 [(set (match_operand:QI 0 "push_operand" "")
20453 (match_operand:QI 1 "memory_operand" ""))
20454 (match_scratch:QI 2 "q")]
20455 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20456 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20457 [(set (match_dup 2) (match_dup 1))
20458 (set (match_dup 0) (match_dup 2))]
20461 ;; Don't move an immediate directly to memory when the instruction
20464 [(match_scratch:SI 1 "r")
20465 (set (match_operand:SI 0 "memory_operand" "")
20467 "optimize_insn_for_speed_p ()
20468 && ! TARGET_USE_MOV0
20469 && TARGET_SPLIT_LONG_MOVES
20470 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20471 && peep2_regno_dead_p (0, FLAGS_REG)"
20472 [(parallel [(set (match_dup 1) (const_int 0))
20473 (clobber (reg:CC FLAGS_REG))])
20474 (set (match_dup 0) (match_dup 1))]
20478 [(match_scratch:HI 1 "r")
20479 (set (match_operand:HI 0 "memory_operand" "")
20481 "optimize_insn_for_speed_p ()
20482 && ! TARGET_USE_MOV0
20483 && TARGET_SPLIT_LONG_MOVES
20484 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20485 && peep2_regno_dead_p (0, FLAGS_REG)"
20486 [(parallel [(set (match_dup 2) (const_int 0))
20487 (clobber (reg:CC FLAGS_REG))])
20488 (set (match_dup 0) (match_dup 1))]
20489 "operands[2] = gen_lowpart (SImode, operands[1]);")
20492 [(match_scratch:QI 1 "q")
20493 (set (match_operand:QI 0 "memory_operand" "")
20495 "optimize_insn_for_speed_p ()
20496 && ! TARGET_USE_MOV0
20497 && TARGET_SPLIT_LONG_MOVES
20498 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20499 && peep2_regno_dead_p (0, FLAGS_REG)"
20500 [(parallel [(set (match_dup 2) (const_int 0))
20501 (clobber (reg:CC FLAGS_REG))])
20502 (set (match_dup 0) (match_dup 1))]
20503 "operands[2] = gen_lowpart (SImode, operands[1]);")
20506 [(match_scratch:SI 2 "r")
20507 (set (match_operand:SI 0 "memory_operand" "")
20508 (match_operand:SI 1 "immediate_operand" ""))]
20509 "optimize_insn_for_speed_p ()
20510 && TARGET_SPLIT_LONG_MOVES
20511 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20512 [(set (match_dup 2) (match_dup 1))
20513 (set (match_dup 0) (match_dup 2))]
20517 [(match_scratch:HI 2 "r")
20518 (set (match_operand:HI 0 "memory_operand" "")
20519 (match_operand:HI 1 "immediate_operand" ""))]
20520 "optimize_insn_for_speed_p ()
20521 && TARGET_SPLIT_LONG_MOVES
20522 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20523 [(set (match_dup 2) (match_dup 1))
20524 (set (match_dup 0) (match_dup 2))]
20528 [(match_scratch:QI 2 "q")
20529 (set (match_operand:QI 0 "memory_operand" "")
20530 (match_operand:QI 1 "immediate_operand" ""))]
20531 "optimize_insn_for_speed_p ()
20532 && TARGET_SPLIT_LONG_MOVES
20533 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20534 [(set (match_dup 2) (match_dup 1))
20535 (set (match_dup 0) (match_dup 2))]
20538 ;; Don't compare memory with zero, load and use a test instead.
20540 [(set (match_operand 0 "flags_reg_operand" "")
20541 (match_operator 1 "compare_operator"
20542 [(match_operand:SI 2 "memory_operand" "")
20544 (match_scratch:SI 3 "r")]
20545 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20546 [(set (match_dup 3) (match_dup 2))
20547 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20550 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20551 ;; Don't split NOTs with a displacement operand, because resulting XOR
20552 ;; will not be pairable anyway.
20554 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20555 ;; represented using a modRM byte. The XOR replacement is long decoded,
20556 ;; so this split helps here as well.
20558 ;; Note: Can't do this as a regular split because we can't get proper
20559 ;; lifetime information then.
20562 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20563 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20564 "optimize_insn_for_speed_p ()
20565 && ((TARGET_NOT_UNPAIRABLE
20566 && (!MEM_P (operands[0])
20567 || !memory_displacement_operand (operands[0], SImode)))
20568 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20569 && peep2_regno_dead_p (0, FLAGS_REG)"
20570 [(parallel [(set (match_dup 0)
20571 (xor:SI (match_dup 1) (const_int -1)))
20572 (clobber (reg:CC FLAGS_REG))])]
20576 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20577 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20578 "optimize_insn_for_speed_p ()
20579 && ((TARGET_NOT_UNPAIRABLE
20580 && (!MEM_P (operands[0])
20581 || !memory_displacement_operand (operands[0], HImode)))
20582 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20583 && peep2_regno_dead_p (0, FLAGS_REG)"
20584 [(parallel [(set (match_dup 0)
20585 (xor:HI (match_dup 1) (const_int -1)))
20586 (clobber (reg:CC FLAGS_REG))])]
20590 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20591 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20592 "optimize_insn_for_speed_p ()
20593 && ((TARGET_NOT_UNPAIRABLE
20594 && (!MEM_P (operands[0])
20595 || !memory_displacement_operand (operands[0], QImode)))
20596 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20597 && peep2_regno_dead_p (0, FLAGS_REG)"
20598 [(parallel [(set (match_dup 0)
20599 (xor:QI (match_dup 1) (const_int -1)))
20600 (clobber (reg:CC FLAGS_REG))])]
20603 ;; Non pairable "test imm, reg" instructions can be translated to
20604 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20605 ;; byte opcode instead of two, have a short form for byte operands),
20606 ;; so do it for other CPUs as well. Given that the value was dead,
20607 ;; this should not create any new dependencies. Pass on the sub-word
20608 ;; versions if we're concerned about partial register stalls.
20611 [(set (match_operand 0 "flags_reg_operand" "")
20612 (match_operator 1 "compare_operator"
20613 [(and:SI (match_operand:SI 2 "register_operand" "")
20614 (match_operand:SI 3 "immediate_operand" ""))
20616 "ix86_match_ccmode (insn, CCNOmode)
20617 && (true_regnum (operands[2]) != AX_REG
20618 || satisfies_constraint_K (operands[3]))
20619 && peep2_reg_dead_p (1, operands[2])"
20621 [(set (match_dup 0)
20622 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20625 (and:SI (match_dup 2) (match_dup 3)))])]
20628 ;; We don't need to handle HImode case, because it will be promoted to SImode
20629 ;; on ! TARGET_PARTIAL_REG_STALL
20632 [(set (match_operand 0 "flags_reg_operand" "")
20633 (match_operator 1 "compare_operator"
20634 [(and:QI (match_operand:QI 2 "register_operand" "")
20635 (match_operand:QI 3 "immediate_operand" ""))
20637 "! TARGET_PARTIAL_REG_STALL
20638 && ix86_match_ccmode (insn, CCNOmode)
20639 && true_regnum (operands[2]) != AX_REG
20640 && peep2_reg_dead_p (1, operands[2])"
20642 [(set (match_dup 0)
20643 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20646 (and:QI (match_dup 2) (match_dup 3)))])]
20650 [(set (match_operand 0 "flags_reg_operand" "")
20651 (match_operator 1 "compare_operator"
20654 (match_operand 2 "ext_register_operand" "")
20657 (match_operand 3 "const_int_operand" ""))
20659 "! TARGET_PARTIAL_REG_STALL
20660 && ix86_match_ccmode (insn, CCNOmode)
20661 && true_regnum (operands[2]) != AX_REG
20662 && peep2_reg_dead_p (1, operands[2])"
20663 [(parallel [(set (match_dup 0)
20672 (set (zero_extract:SI (match_dup 2)
20683 ;; Don't do logical operations with memory inputs.
20685 [(match_scratch:SI 2 "r")
20686 (parallel [(set (match_operand:SI 0 "register_operand" "")
20687 (match_operator:SI 3 "arith_or_logical_operator"
20689 (match_operand:SI 1 "memory_operand" "")]))
20690 (clobber (reg:CC FLAGS_REG))])]
20691 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20692 [(set (match_dup 2) (match_dup 1))
20693 (parallel [(set (match_dup 0)
20694 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20695 (clobber (reg:CC FLAGS_REG))])]
20699 [(match_scratch:SI 2 "r")
20700 (parallel [(set (match_operand:SI 0 "register_operand" "")
20701 (match_operator:SI 3 "arith_or_logical_operator"
20702 [(match_operand:SI 1 "memory_operand" "")
20704 (clobber (reg:CC FLAGS_REG))])]
20705 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20706 [(set (match_dup 2) (match_dup 1))
20707 (parallel [(set (match_dup 0)
20708 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20709 (clobber (reg:CC FLAGS_REG))])]
20712 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20713 ;; refers to the destination of the load!
20716 [(set (match_operand:SI 0 "register_operand" "")
20717 (match_operand:SI 1 "register_operand" ""))
20718 (parallel [(set (match_dup 0)
20719 (match_operator:SI 3 "commutative_operator"
20721 (match_operand:SI 2 "memory_operand" "")]))
20722 (clobber (reg:CC FLAGS_REG))])]
20723 "REGNO (operands[0]) != REGNO (operands[1])
20724 && GENERAL_REGNO_P (REGNO (operands[0]))
20725 && GENERAL_REGNO_P (REGNO (operands[1]))"
20726 [(set (match_dup 0) (match_dup 4))
20727 (parallel [(set (match_dup 0)
20728 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20729 (clobber (reg:CC FLAGS_REG))])]
20730 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20733 [(set (match_operand 0 "register_operand" "")
20734 (match_operand 1 "register_operand" ""))
20736 (match_operator 3 "commutative_operator"
20738 (match_operand 2 "memory_operand" "")]))]
20739 "REGNO (operands[0]) != REGNO (operands[1])
20740 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20741 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20742 [(set (match_dup 0) (match_dup 2))
20744 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20747 ; Don't do logical operations with memory outputs
20749 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20750 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20751 ; the same decoder scheduling characteristics as the original.
20754 [(match_scratch:SI 2 "r")
20755 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20756 (match_operator:SI 3 "arith_or_logical_operator"
20758 (match_operand:SI 1 "nonmemory_operand" "")]))
20759 (clobber (reg:CC FLAGS_REG))])]
20760 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20761 [(set (match_dup 2) (match_dup 0))
20762 (parallel [(set (match_dup 2)
20763 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20764 (clobber (reg:CC FLAGS_REG))])
20765 (set (match_dup 0) (match_dup 2))]
20769 [(match_scratch:SI 2 "r")
20770 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20771 (match_operator:SI 3 "arith_or_logical_operator"
20772 [(match_operand:SI 1 "nonmemory_operand" "")
20774 (clobber (reg:CC FLAGS_REG))])]
20775 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20776 [(set (match_dup 2) (match_dup 0))
20777 (parallel [(set (match_dup 2)
20778 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20779 (clobber (reg:CC FLAGS_REG))])
20780 (set (match_dup 0) (match_dup 2))]
20783 ;; Attempt to always use XOR for zeroing registers.
20785 [(set (match_operand 0 "register_operand" "")
20786 (match_operand 1 "const0_operand" ""))]
20787 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20788 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20789 && GENERAL_REG_P (operands[0])
20790 && peep2_regno_dead_p (0, FLAGS_REG)"
20791 [(parallel [(set (match_dup 0) (const_int 0))
20792 (clobber (reg:CC FLAGS_REG))])]
20794 operands[0] = gen_lowpart (word_mode, operands[0]);
20798 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20800 "(GET_MODE (operands[0]) == QImode
20801 || GET_MODE (operands[0]) == HImode)
20802 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20803 && peep2_regno_dead_p (0, FLAGS_REG)"
20804 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20805 (clobber (reg:CC FLAGS_REG))])])
20807 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20809 [(set (match_operand 0 "register_operand" "")
20811 "(GET_MODE (operands[0]) == HImode
20812 || GET_MODE (operands[0]) == SImode
20813 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20814 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20815 && peep2_regno_dead_p (0, FLAGS_REG)"
20816 [(parallel [(set (match_dup 0) (const_int -1))
20817 (clobber (reg:CC FLAGS_REG))])]
20818 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20821 ;; Attempt to convert simple leas to adds. These can be created by
20824 [(set (match_operand:SI 0 "register_operand" "")
20825 (plus:SI (match_dup 0)
20826 (match_operand:SI 1 "nonmemory_operand" "")))]
20827 "peep2_regno_dead_p (0, FLAGS_REG)"
20828 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20829 (clobber (reg:CC FLAGS_REG))])]
20833 [(set (match_operand:SI 0 "register_operand" "")
20834 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20835 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20836 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20837 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20838 (clobber (reg:CC FLAGS_REG))])]
20839 "operands[2] = gen_lowpart (SImode, operands[2]);")
20842 [(set (match_operand:DI 0 "register_operand" "")
20843 (plus:DI (match_dup 0)
20844 (match_operand:DI 1 "x86_64_general_operand" "")))]
20845 "peep2_regno_dead_p (0, FLAGS_REG)"
20846 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20847 (clobber (reg:CC FLAGS_REG))])]
20851 [(set (match_operand:SI 0 "register_operand" "")
20852 (mult:SI (match_dup 0)
20853 (match_operand:SI 1 "const_int_operand" "")))]
20854 "exact_log2 (INTVAL (operands[1])) >= 0
20855 && peep2_regno_dead_p (0, FLAGS_REG)"
20856 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20857 (clobber (reg:CC FLAGS_REG))])]
20858 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20861 [(set (match_operand:DI 0 "register_operand" "")
20862 (mult:DI (match_dup 0)
20863 (match_operand:DI 1 "const_int_operand" "")))]
20864 "exact_log2 (INTVAL (operands[1])) >= 0
20865 && peep2_regno_dead_p (0, FLAGS_REG)"
20866 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20867 (clobber (reg:CC FLAGS_REG))])]
20868 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20871 [(set (match_operand:SI 0 "register_operand" "")
20872 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20873 (match_operand:DI 2 "const_int_operand" "")) 0))]
20874 "exact_log2 (INTVAL (operands[2])) >= 0
20875 && REGNO (operands[0]) == REGNO (operands[1])
20876 && peep2_regno_dead_p (0, FLAGS_REG)"
20877 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20878 (clobber (reg:CC FLAGS_REG))])]
20879 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20881 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20882 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20883 ;; many CPUs it is also faster, since special hardware to avoid esp
20884 ;; dependencies is present.
20886 ;; While some of these conversions may be done using splitters, we use peepholes
20887 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20889 ;; Convert prologue esp subtractions to push.
20890 ;; We need register to push. In order to keep verify_flow_info happy we have
20892 ;; - use scratch and clobber it in order to avoid dependencies
20893 ;; - use already live register
20894 ;; We can't use the second way right now, since there is no reliable way how to
20895 ;; verify that given register is live. First choice will also most likely in
20896 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20897 ;; call clobbered registers are dead. We may want to use base pointer as an
20898 ;; alternative when no register is available later.
20901 [(match_scratch:SI 0 "r")
20902 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20903 (clobber (reg:CC FLAGS_REG))
20904 (clobber (mem:BLK (scratch)))])]
20905 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20906 [(clobber (match_dup 0))
20907 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20908 (clobber (mem:BLK (scratch)))])])
20911 [(match_scratch:SI 0 "r")
20912 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20913 (clobber (reg:CC FLAGS_REG))
20914 (clobber (mem:BLK (scratch)))])]
20915 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20916 [(clobber (match_dup 0))
20917 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20918 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20919 (clobber (mem:BLK (scratch)))])])
20921 ;; Convert esp subtractions to push.
20923 [(match_scratch:SI 0 "r")
20924 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20925 (clobber (reg:CC FLAGS_REG))])]
20926 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20927 [(clobber (match_dup 0))
20928 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20931 [(match_scratch:SI 0 "r")
20932 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20933 (clobber (reg:CC FLAGS_REG))])]
20934 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20935 [(clobber (match_dup 0))
20936 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20937 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20939 ;; Convert epilogue deallocator to pop.
20941 [(match_scratch:SI 0 "r")
20942 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20943 (clobber (reg:CC FLAGS_REG))
20944 (clobber (mem:BLK (scratch)))])]
20945 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20946 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20947 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20948 (clobber (mem:BLK (scratch)))])]
20951 ;; Two pops case is tricky, since pop causes dependency on destination register.
20952 ;; We use two registers if available.
20954 [(match_scratch:SI 0 "r")
20955 (match_scratch:SI 1 "r")
20956 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957 (clobber (reg:CC FLAGS_REG))
20958 (clobber (mem:BLK (scratch)))])]
20959 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20960 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20961 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20962 (clobber (mem:BLK (scratch)))])
20963 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20964 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20968 [(match_scratch:SI 0 "r")
20969 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20970 (clobber (reg:CC FLAGS_REG))
20971 (clobber (mem:BLK (scratch)))])]
20972 "optimize_insn_for_size_p ()"
20973 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20974 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20975 (clobber (mem:BLK (scratch)))])
20976 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20977 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20980 ;; Convert esp additions to pop.
20982 [(match_scratch:SI 0 "r")
20983 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20984 (clobber (reg:CC FLAGS_REG))])]
20986 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20987 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20990 ;; Two pops case is tricky, since pop causes dependency on destination register.
20991 ;; We use two registers if available.
20993 [(match_scratch:SI 0 "r")
20994 (match_scratch:SI 1 "r")
20995 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20996 (clobber (reg:CC FLAGS_REG))])]
20998 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20999 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21000 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21001 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21005 [(match_scratch:SI 0 "r")
21006 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21007 (clobber (reg:CC FLAGS_REG))])]
21008 "optimize_insn_for_size_p ()"
21009 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21010 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21011 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21012 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21015 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21016 ;; required and register dies. Similarly for 128 to -128.
21018 [(set (match_operand 0 "flags_reg_operand" "")
21019 (match_operator 1 "compare_operator"
21020 [(match_operand 2 "register_operand" "")
21021 (match_operand 3 "const_int_operand" "")]))]
21022 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21023 && incdec_operand (operands[3], GET_MODE (operands[3])))
21024 || (!TARGET_FUSE_CMP_AND_BRANCH
21025 && INTVAL (operands[3]) == 128))
21026 && ix86_match_ccmode (insn, CCGCmode)
21027 && peep2_reg_dead_p (1, operands[2])"
21028 [(parallel [(set (match_dup 0)
21029 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21030 (clobber (match_dup 2))])]
21034 [(match_scratch:DI 0 "r")
21035 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21036 (clobber (reg:CC FLAGS_REG))
21037 (clobber (mem:BLK (scratch)))])]
21038 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21039 [(clobber (match_dup 0))
21040 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21041 (clobber (mem:BLK (scratch)))])])
21044 [(match_scratch:DI 0 "r")
21045 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21046 (clobber (reg:CC FLAGS_REG))
21047 (clobber (mem:BLK (scratch)))])]
21048 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21049 [(clobber (match_dup 0))
21050 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21051 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21052 (clobber (mem:BLK (scratch)))])])
21054 ;; Convert esp subtractions to push.
21056 [(match_scratch:DI 0 "r")
21057 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21058 (clobber (reg:CC FLAGS_REG))])]
21059 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21060 [(clobber (match_dup 0))
21061 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21064 [(match_scratch:DI 0 "r")
21065 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21066 (clobber (reg:CC FLAGS_REG))])]
21067 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21068 [(clobber (match_dup 0))
21069 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21070 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21072 ;; Convert epilogue deallocator to pop.
21074 [(match_scratch:DI 0 "r")
21075 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21076 (clobber (reg:CC FLAGS_REG))
21077 (clobber (mem:BLK (scratch)))])]
21078 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21079 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21080 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21081 (clobber (mem:BLK (scratch)))])]
21084 ;; Two pops case is tricky, since pop causes dependency on destination register.
21085 ;; We use two registers if available.
21087 [(match_scratch:DI 0 "r")
21088 (match_scratch:DI 1 "r")
21089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090 (clobber (reg:CC FLAGS_REG))
21091 (clobber (mem:BLK (scratch)))])]
21092 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21093 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21094 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21095 (clobber (mem:BLK (scratch)))])
21096 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21097 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21101 [(match_scratch:DI 0 "r")
21102 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21103 (clobber (reg:CC FLAGS_REG))
21104 (clobber (mem:BLK (scratch)))])]
21105 "optimize_insn_for_size_p ()"
21106 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21107 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21108 (clobber (mem:BLK (scratch)))])
21109 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21110 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21113 ;; Convert esp additions to pop.
21115 [(match_scratch:DI 0 "r")
21116 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21117 (clobber (reg:CC FLAGS_REG))])]
21119 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21120 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21123 ;; Two pops case is tricky, since pop causes dependency on destination register.
21124 ;; We use two registers if available.
21126 [(match_scratch:DI 0 "r")
21127 (match_scratch:DI 1 "r")
21128 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21129 (clobber (reg:CC FLAGS_REG))])]
21131 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21132 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21133 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21134 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21138 [(match_scratch:DI 0 "r")
21139 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21140 (clobber (reg:CC FLAGS_REG))])]
21141 "optimize_insn_for_size_p ()"
21142 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21143 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21144 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21145 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21148 ;; Convert imul by three, five and nine into lea
21151 [(set (match_operand:SI 0 "register_operand" "")
21152 (mult:SI (match_operand:SI 1 "register_operand" "")
21153 (match_operand:SI 2 "const_int_operand" "")))
21154 (clobber (reg:CC FLAGS_REG))])]
21155 "INTVAL (operands[2]) == 3
21156 || INTVAL (operands[2]) == 5
21157 || INTVAL (operands[2]) == 9"
21158 [(set (match_dup 0)
21159 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21161 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21165 [(set (match_operand:SI 0 "register_operand" "")
21166 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21167 (match_operand:SI 2 "const_int_operand" "")))
21168 (clobber (reg:CC FLAGS_REG))])]
21169 "optimize_insn_for_speed_p ()
21170 && (INTVAL (operands[2]) == 3
21171 || INTVAL (operands[2]) == 5
21172 || INTVAL (operands[2]) == 9)"
21173 [(set (match_dup 0) (match_dup 1))
21175 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21177 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21181 [(set (match_operand:DI 0 "register_operand" "")
21182 (mult:DI (match_operand:DI 1 "register_operand" "")
21183 (match_operand:DI 2 "const_int_operand" "")))
21184 (clobber (reg:CC FLAGS_REG))])]
21186 && (INTVAL (operands[2]) == 3
21187 || INTVAL (operands[2]) == 5
21188 || INTVAL (operands[2]) == 9)"
21189 [(set (match_dup 0)
21190 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21192 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21196 [(set (match_operand:DI 0 "register_operand" "")
21197 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21198 (match_operand:DI 2 "const_int_operand" "")))
21199 (clobber (reg:CC FLAGS_REG))])]
21201 && optimize_insn_for_speed_p ()
21202 && (INTVAL (operands[2]) == 3
21203 || INTVAL (operands[2]) == 5
21204 || INTVAL (operands[2]) == 9)"
21205 [(set (match_dup 0) (match_dup 1))
21207 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21209 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21211 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21212 ;; imul $32bit_imm, reg, reg is direct decoded.
21214 [(match_scratch:DI 3 "r")
21215 (parallel [(set (match_operand:DI 0 "register_operand" "")
21216 (mult:DI (match_operand:DI 1 "memory_operand" "")
21217 (match_operand:DI 2 "immediate_operand" "")))
21218 (clobber (reg:CC FLAGS_REG))])]
21219 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21220 && !satisfies_constraint_K (operands[2])"
21221 [(set (match_dup 3) (match_dup 1))
21222 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21223 (clobber (reg:CC FLAGS_REG))])]
21227 [(match_scratch:SI 3 "r")
21228 (parallel [(set (match_operand:SI 0 "register_operand" "")
21229 (mult:SI (match_operand:SI 1 "memory_operand" "")
21230 (match_operand:SI 2 "immediate_operand" "")))
21231 (clobber (reg:CC FLAGS_REG))])]
21232 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21233 && !satisfies_constraint_K (operands[2])"
21234 [(set (match_dup 3) (match_dup 1))
21235 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21236 (clobber (reg:CC FLAGS_REG))])]
21240 [(match_scratch:SI 3 "r")
21241 (parallel [(set (match_operand:DI 0 "register_operand" "")
21243 (mult:SI (match_operand:SI 1 "memory_operand" "")
21244 (match_operand:SI 2 "immediate_operand" ""))))
21245 (clobber (reg:CC FLAGS_REG))])]
21246 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21247 && !satisfies_constraint_K (operands[2])"
21248 [(set (match_dup 3) (match_dup 1))
21249 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21250 (clobber (reg:CC FLAGS_REG))])]
21253 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21254 ;; Convert it into imul reg, reg
21255 ;; It would be better to force assembler to encode instruction using long
21256 ;; immediate, but there is apparently no way to do so.
21258 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21259 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21260 (match_operand:DI 2 "const_int_operand" "")))
21261 (clobber (reg:CC FLAGS_REG))])
21262 (match_scratch:DI 3 "r")]
21263 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21264 && satisfies_constraint_K (operands[2])"
21265 [(set (match_dup 3) (match_dup 2))
21266 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21267 (clobber (reg:CC FLAGS_REG))])]
21269 if (!rtx_equal_p (operands[0], operands[1]))
21270 emit_move_insn (operands[0], operands[1]);
21274 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21275 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21276 (match_operand:SI 2 "const_int_operand" "")))
21277 (clobber (reg:CC FLAGS_REG))])
21278 (match_scratch:SI 3 "r")]
21279 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21280 && satisfies_constraint_K (operands[2])"
21281 [(set (match_dup 3) (match_dup 2))
21282 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21283 (clobber (reg:CC FLAGS_REG))])]
21285 if (!rtx_equal_p (operands[0], operands[1]))
21286 emit_move_insn (operands[0], operands[1]);
21290 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21291 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21292 (match_operand:HI 2 "immediate_operand" "")))
21293 (clobber (reg:CC FLAGS_REG))])
21294 (match_scratch:HI 3 "r")]
21295 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21296 [(set (match_dup 3) (match_dup 2))
21297 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21298 (clobber (reg:CC FLAGS_REG))])]
21300 if (!rtx_equal_p (operands[0], operands[1]))
21301 emit_move_insn (operands[0], operands[1]);
21304 ;; After splitting up read-modify operations, array accesses with memory
21305 ;; operands might end up in form:
21307 ;; movl 4(%esp), %edx
21309 ;; instead of pre-splitting:
21311 ;; addl 4(%esp), %eax
21313 ;; movl 4(%esp), %edx
21314 ;; leal (%edx,%eax,4), %eax
21317 [(parallel [(set (match_operand 0 "register_operand" "")
21318 (ashift (match_operand 1 "register_operand" "")
21319 (match_operand 2 "const_int_operand" "")))
21320 (clobber (reg:CC FLAGS_REG))])
21321 (set (match_operand 3 "register_operand")
21322 (match_operand 4 "x86_64_general_operand" ""))
21323 (parallel [(set (match_operand 5 "register_operand" "")
21324 (plus (match_operand 6 "register_operand" "")
21325 (match_operand 7 "register_operand" "")))
21326 (clobber (reg:CC FLAGS_REG))])]
21327 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21328 /* Validate MODE for lea. */
21329 && ((!TARGET_PARTIAL_REG_STALL
21330 && (GET_MODE (operands[0]) == QImode
21331 || GET_MODE (operands[0]) == HImode))
21332 || GET_MODE (operands[0]) == SImode
21333 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21334 /* We reorder load and the shift. */
21335 && !rtx_equal_p (operands[1], operands[3])
21336 && !reg_overlap_mentioned_p (operands[0], operands[4])
21337 /* Last PLUS must consist of operand 0 and 3. */
21338 && !rtx_equal_p (operands[0], operands[3])
21339 && (rtx_equal_p (operands[3], operands[6])
21340 || rtx_equal_p (operands[3], operands[7]))
21341 && (rtx_equal_p (operands[0], operands[6])
21342 || rtx_equal_p (operands[0], operands[7]))
21343 /* The intermediate operand 0 must die or be same as output. */
21344 && (rtx_equal_p (operands[0], operands[5])
21345 || peep2_reg_dead_p (3, operands[0]))"
21346 [(set (match_dup 3) (match_dup 4))
21347 (set (match_dup 0) (match_dup 1))]
21349 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21350 int scale = 1 << INTVAL (operands[2]);
21351 rtx index = gen_lowpart (Pmode, operands[1]);
21352 rtx base = gen_lowpart (Pmode, operands[3]);
21353 rtx dest = gen_lowpart (mode, operands[5]);
21355 operands[1] = gen_rtx_PLUS (Pmode, base,
21356 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21358 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21359 operands[0] = dest;
21362 ;; Call-value patterns last so that the wildcard operand does not
21363 ;; disrupt insn-recog's switch tables.
21365 (define_insn "*call_value_pop_0"
21366 [(set (match_operand 0 "" "")
21367 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21368 (match_operand:SI 2 "" "")))
21369 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21370 (match_operand:SI 3 "immediate_operand" "")))]
21373 if (SIBLING_CALL_P (insn))
21376 return "call\t%P1";
21378 [(set_attr "type" "callv")])
21380 (define_insn "*call_value_pop_1"
21381 [(set (match_operand 0 "" "")
21382 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21383 (match_operand:SI 2 "" "")))
21384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21385 (match_operand:SI 3 "immediate_operand" "i")))]
21386 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21388 if (constant_call_address_operand (operands[1], Pmode))
21389 return "call\t%P1";
21390 return "call\t%A1";
21392 [(set_attr "type" "callv")])
21394 (define_insn "*sibcall_value_pop_1"
21395 [(set (match_operand 0 "" "")
21396 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21397 (match_operand:SI 2 "" "")))
21398 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21399 (match_operand:SI 3 "immediate_operand" "i,i")))]
21400 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21404 [(set_attr "type" "callv")])
21406 (define_insn "*call_value_0"
21407 [(set (match_operand 0 "" "")
21408 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21409 (match_operand:SI 2 "" "")))]
21412 if (SIBLING_CALL_P (insn))
21415 return "call\t%P1";
21417 [(set_attr "type" "callv")])
21419 (define_insn "*call_value_0_rex64"
21420 [(set (match_operand 0 "" "")
21421 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21422 (match_operand:DI 2 "const_int_operand" "")))]
21425 if (SIBLING_CALL_P (insn))
21428 return "call\t%P1";
21430 [(set_attr "type" "callv")])
21432 (define_insn "*call_value_0_rex64_ms_sysv"
21433 [(set (match_operand 0 "" "")
21434 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21435 (match_operand:DI 2 "const_int_operand" "")))
21436 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21437 (clobber (reg:TI XMM6_REG))
21438 (clobber (reg:TI XMM7_REG))
21439 (clobber (reg:TI XMM8_REG))
21440 (clobber (reg:TI XMM9_REG))
21441 (clobber (reg:TI XMM10_REG))
21442 (clobber (reg:TI XMM11_REG))
21443 (clobber (reg:TI XMM12_REG))
21444 (clobber (reg:TI XMM13_REG))
21445 (clobber (reg:TI XMM14_REG))
21446 (clobber (reg:TI XMM15_REG))
21447 (clobber (reg:DI SI_REG))
21448 (clobber (reg:DI DI_REG))]
21449 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21451 if (SIBLING_CALL_P (insn))
21454 return "call\t%P1";
21456 [(set_attr "type" "callv")])
21458 (define_insn "*call_value_1"
21459 [(set (match_operand 0 "" "")
21460 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21461 (match_operand:SI 2 "" "")))]
21462 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21464 if (constant_call_address_operand (operands[1], Pmode))
21465 return "call\t%P1";
21466 return "call\t%A1";
21468 [(set_attr "type" "callv")])
21470 (define_insn "*sibcall_value_1"
21471 [(set (match_operand 0 "" "")
21472 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21473 (match_operand:SI 2 "" "")))]
21474 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21478 [(set_attr "type" "callv")])
21480 (define_insn "*call_value_1_rex64"
21481 [(set (match_operand 0 "" "")
21482 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21483 (match_operand:DI 2 "" "")))]
21484 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21485 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21487 if (constant_call_address_operand (operands[1], Pmode))
21488 return "call\t%P1";
21489 return "call\t%A1";
21491 [(set_attr "type" "callv")])
21493 (define_insn "*call_value_1_rex64_ms_sysv"
21494 [(set (match_operand 0 "" "")
21495 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21496 (match_operand:DI 2 "" "")))
21497 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21498 (clobber (reg:TI 27))
21499 (clobber (reg:TI 28))
21500 (clobber (reg:TI 45))
21501 (clobber (reg:TI 46))
21502 (clobber (reg:TI 47))
21503 (clobber (reg:TI 48))
21504 (clobber (reg:TI 49))
21505 (clobber (reg:TI 50))
21506 (clobber (reg:TI 51))
21507 (clobber (reg:TI 52))
21508 (clobber (reg:DI SI_REG))
21509 (clobber (reg:DI DI_REG))]
21510 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21512 if (constant_call_address_operand (operands[1], Pmode))
21513 return "call\t%P1";
21514 return "call\t%A1";
21516 [(set_attr "type" "callv")])
21518 (define_insn "*call_value_1_rex64_large"
21519 [(set (match_operand 0 "" "")
21520 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21521 (match_operand:DI 2 "" "")))]
21522 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21524 [(set_attr "type" "callv")])
21526 (define_insn "*sibcall_value_1_rex64"
21527 [(set (match_operand 0 "" "")
21528 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21529 (match_operand:DI 2 "" "")))]
21530 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21534 [(set_attr "type" "callv")])
21536 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21537 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21538 ;; caught for use by garbage collectors and the like. Using an insn that
21539 ;; maps to SIGILL makes it more likely the program will rightfully die.
21540 ;; Keeping with tradition, "6" is in honor of #UD.
21541 (define_insn "trap"
21542 [(trap_if (const_int 1) (const_int 6))]
21544 { return ASM_SHORT "0x0b0f"; }
21545 [(set_attr "length" "2")])
21547 (define_expand "sse_prologue_save"
21548 [(parallel [(set (match_operand:BLK 0 "" "")
21549 (unspec:BLK [(reg:DI 21)
21556 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21557 (use (match_operand:DI 1 "register_operand" ""))
21558 (use (match_operand:DI 2 "immediate_operand" ""))
21559 (use (label_ref:DI (match_operand 3 "" "")))])]
21563 (define_insn "*sse_prologue_save_insn"
21564 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21565 (match_operand:DI 4 "const_int_operand" "n")))
21566 (unspec:BLK [(reg:DI 21)
21573 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21574 (use (match_operand:DI 1 "register_operand" "r"))
21575 (use (match_operand:DI 2 "const_int_operand" "i"))
21576 (use (label_ref:DI (match_operand 3 "" "X")))]
21578 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21579 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21582 operands[0] = gen_rtx_MEM (Pmode,
21583 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21584 /* VEX instruction with a REX prefix will #UD. */
21585 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21586 gcc_unreachable ();
21588 output_asm_insn ("jmp\t%A1", operands);
21589 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21591 operands[4] = adjust_address (operands[0], DImode, i*16);
21592 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21593 PUT_MODE (operands[4], TImode);
21594 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21595 output_asm_insn ("rex", operands);
21596 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21598 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21599 CODE_LABEL_NUMBER (operands[3]));
21602 [(set_attr "type" "other")
21603 (set_attr "length_immediate" "0")
21604 (set_attr "length_address" "0")
21605 (set (attr "length")
21607 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21608 (const_string "34")
21609 (const_string "42")))
21610 (set_attr "memory" "store")
21611 (set_attr "modrm" "0")
21612 (set_attr "prefix" "maybe_vex")
21613 (set_attr "mode" "DI")])
21615 (define_expand "prefetch"
21616 [(prefetch (match_operand 0 "address_operand" "")
21617 (match_operand:SI 1 "const_int_operand" "")
21618 (match_operand:SI 2 "const_int_operand" ""))]
21619 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21621 int rw = INTVAL (operands[1]);
21622 int locality = INTVAL (operands[2]);
21624 gcc_assert (rw == 0 || rw == 1);
21625 gcc_assert (locality >= 0 && locality <= 3);
21626 gcc_assert (GET_MODE (operands[0]) == Pmode
21627 || GET_MODE (operands[0]) == VOIDmode);
21629 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21630 supported by SSE counterpart or the SSE prefetch is not available
21631 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21633 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21634 operands[2] = GEN_INT (3);
21636 operands[1] = const0_rtx;
21639 (define_insn "*prefetch_sse"
21640 [(prefetch (match_operand:SI 0 "address_operand" "p")
21642 (match_operand:SI 1 "const_int_operand" ""))]
21643 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21645 static const char * const patterns[4] = {
21646 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21649 int locality = INTVAL (operands[1]);
21650 gcc_assert (locality >= 0 && locality <= 3);
21652 return patterns[locality];
21654 [(set_attr "type" "sse")
21655 (set_attr "atom_sse_attr" "prefetch")
21656 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21657 (set_attr "memory" "none")])
21659 (define_insn "*prefetch_sse_rex"
21660 [(prefetch (match_operand:DI 0 "address_operand" "p")
21662 (match_operand:SI 1 "const_int_operand" ""))]
21663 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21665 static const char * const patterns[4] = {
21666 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21669 int locality = INTVAL (operands[1]);
21670 gcc_assert (locality >= 0 && locality <= 3);
21672 return patterns[locality];
21674 [(set_attr "type" "sse")
21675 (set_attr "atom_sse_attr" "prefetch")
21676 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21677 (set_attr "memory" "none")])
21679 (define_insn "*prefetch_3dnow"
21680 [(prefetch (match_operand:SI 0 "address_operand" "p")
21681 (match_operand:SI 1 "const_int_operand" "n")
21683 "TARGET_3DNOW && !TARGET_64BIT"
21685 if (INTVAL (operands[1]) == 0)
21686 return "prefetch\t%a0";
21688 return "prefetchw\t%a0";
21690 [(set_attr "type" "mmx")
21691 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21692 (set_attr "memory" "none")])
21694 (define_insn "*prefetch_3dnow_rex"
21695 [(prefetch (match_operand:DI 0 "address_operand" "p")
21696 (match_operand:SI 1 "const_int_operand" "n")
21698 "TARGET_3DNOW && TARGET_64BIT"
21700 if (INTVAL (operands[1]) == 0)
21701 return "prefetch\t%a0";
21703 return "prefetchw\t%a0";
21705 [(set_attr "type" "mmx")
21706 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21707 (set_attr "memory" "none")])
21709 (define_expand "stack_protect_set"
21710 [(match_operand 0 "memory_operand" "")
21711 (match_operand 1 "memory_operand" "")]
21714 #ifdef TARGET_THREAD_SSP_OFFSET
21716 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21717 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21719 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21720 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21723 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21725 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21730 (define_insn "stack_protect_set_si"
21731 [(set (match_operand:SI 0 "memory_operand" "=m")
21732 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21733 (set (match_scratch:SI 2 "=&r") (const_int 0))
21734 (clobber (reg:CC FLAGS_REG))]
21736 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21737 [(set_attr "type" "multi")])
21739 (define_insn "stack_protect_set_di"
21740 [(set (match_operand:DI 0 "memory_operand" "=m")
21741 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21742 (set (match_scratch:DI 2 "=&r") (const_int 0))
21743 (clobber (reg:CC FLAGS_REG))]
21745 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21746 [(set_attr "type" "multi")])
21748 (define_insn "stack_tls_protect_set_si"
21749 [(set (match_operand:SI 0 "memory_operand" "=m")
21750 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21751 (set (match_scratch:SI 2 "=&r") (const_int 0))
21752 (clobber (reg:CC FLAGS_REG))]
21754 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21755 [(set_attr "type" "multi")])
21757 (define_insn "stack_tls_protect_set_di"
21758 [(set (match_operand:DI 0 "memory_operand" "=m")
21759 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21760 (set (match_scratch:DI 2 "=&r") (const_int 0))
21761 (clobber (reg:CC FLAGS_REG))]
21764 /* The kernel uses a different segment register for performance reasons; a
21765 system call would not have to trash the userspace segment register,
21766 which would be expensive */
21767 if (ix86_cmodel != CM_KERNEL)
21768 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21770 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21772 [(set_attr "type" "multi")])
21774 (define_expand "stack_protect_test"
21775 [(match_operand 0 "memory_operand" "")
21776 (match_operand 1 "memory_operand" "")
21777 (match_operand 2 "" "")]
21780 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21782 #ifdef TARGET_THREAD_SSP_OFFSET
21784 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21785 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21787 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21788 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21791 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21793 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21796 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21797 flags, const0_rtx, operands[2]));
21801 (define_insn "stack_protect_test_si"
21802 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21803 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21804 (match_operand:SI 2 "memory_operand" "m")]
21806 (clobber (match_scratch:SI 3 "=&r"))]
21808 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21809 [(set_attr "type" "multi")])
21811 (define_insn "stack_protect_test_di"
21812 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21813 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21814 (match_operand:DI 2 "memory_operand" "m")]
21816 (clobber (match_scratch:DI 3 "=&r"))]
21818 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21819 [(set_attr "type" "multi")])
21821 (define_insn "stack_tls_protect_test_si"
21822 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21823 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21824 (match_operand:SI 2 "const_int_operand" "i")]
21825 UNSPEC_SP_TLS_TEST))
21826 (clobber (match_scratch:SI 3 "=r"))]
21828 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21829 [(set_attr "type" "multi")])
21831 (define_insn "stack_tls_protect_test_di"
21832 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21833 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21834 (match_operand:DI 2 "const_int_operand" "i")]
21835 UNSPEC_SP_TLS_TEST))
21836 (clobber (match_scratch:DI 3 "=r"))]
21839 /* The kernel uses a different segment register for performance reasons; a
21840 system call would not have to trash the userspace segment register,
21841 which would be expensive */
21842 if (ix86_cmodel != CM_KERNEL)
21843 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21845 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21847 [(set_attr "type" "multi")])
21849 (define_mode_iterator CRC32MODE [QI HI SI])
21850 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21851 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21853 (define_insn "sse4_2_crc32<mode>"
21854 [(set (match_operand:SI 0 "register_operand" "=r")
21856 [(match_operand:SI 1 "register_operand" "0")
21857 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21859 "TARGET_SSE4_2 || TARGET_CRC32"
21860 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21861 [(set_attr "type" "sselog1")
21862 (set_attr "prefix_rep" "1")
21863 (set_attr "prefix_extra" "1")
21864 (set (attr "prefix_data16")
21865 (if_then_else (match_operand:HI 2 "" "")
21867 (const_string "*")))
21868 (set (attr "prefix_rex")
21869 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21871 (const_string "*")))
21872 (set_attr "mode" "SI")])
21874 (define_insn "sse4_2_crc32di"
21875 [(set (match_operand:DI 0 "register_operand" "=r")
21877 [(match_operand:DI 1 "register_operand" "0")
21878 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21880 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21881 "crc32q\t{%2, %0|%0, %2}"
21882 [(set_attr "type" "sselog1")
21883 (set_attr "prefix_rep" "1")
21884 (set_attr "prefix_extra" "1")
21885 (set_attr "mode" "DI")])
21887 (define_expand "rdpmc"
21888 [(match_operand:DI 0 "register_operand" "")
21889 (match_operand:SI 1 "register_operand" "")]
21892 rtx reg = gen_reg_rtx (DImode);
21895 /* Force operand 1 into ECX. */
21896 rtx ecx = gen_rtx_REG (SImode, CX_REG);
21897 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21898 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21903 rtvec vec = rtvec_alloc (2);
21904 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21905 rtx upper = gen_reg_rtx (DImode);
21906 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21907 gen_rtvec (1, const0_rtx),
21909 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21910 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21912 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21913 NULL, 1, OPTAB_DIRECT);
21914 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21918 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21919 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21923 (define_insn "*rdpmc"
21924 [(set (match_operand:DI 0 "register_operand" "=A")
21925 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21929 [(set_attr "type" "other")
21930 (set_attr "length" "2")])
21932 (define_insn "*rdpmc_rex64"
21933 [(set (match_operand:DI 0 "register_operand" "=a")
21934 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21936 (set (match_operand:DI 1 "register_operand" "=d")
21937 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21940 [(set_attr "type" "other")
21941 (set_attr "length" "2")])
21943 (define_expand "rdtsc"
21944 [(set (match_operand:DI 0 "register_operand" "")
21945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21950 rtvec vec = rtvec_alloc (2);
21951 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21952 rtx upper = gen_reg_rtx (DImode);
21953 rtx lower = gen_reg_rtx (DImode);
21954 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21955 gen_rtvec (1, const0_rtx),
21957 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21958 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21960 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21961 NULL, 1, OPTAB_DIRECT);
21962 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21964 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21969 (define_insn "*rdtsc"
21970 [(set (match_operand:DI 0 "register_operand" "=A")
21971 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21974 [(set_attr "type" "other")
21975 (set_attr "length" "2")])
21977 (define_insn "*rdtsc_rex64"
21978 [(set (match_operand:DI 0 "register_operand" "=a")
21979 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21980 (set (match_operand:DI 1 "register_operand" "=d")
21981 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21984 [(set_attr "type" "other")
21985 (set_attr "length" "2")])
21987 (define_expand "rdtscp"
21988 [(match_operand:DI 0 "register_operand" "")
21989 (match_operand:SI 1 "memory_operand" "")]
21992 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21993 gen_rtvec (1, const0_rtx),
21995 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21996 gen_rtvec (1, const0_rtx),
21998 rtx reg = gen_reg_rtx (DImode);
21999 rtx tmp = gen_reg_rtx (SImode);
22003 rtvec vec = rtvec_alloc (3);
22004 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22005 rtx upper = gen_reg_rtx (DImode);
22006 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22007 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22008 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22010 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22011 NULL, 1, OPTAB_DIRECT);
22012 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22017 rtvec vec = rtvec_alloc (2);
22018 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22019 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22020 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22023 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22024 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22028 (define_insn "*rdtscp"
22029 [(set (match_operand:DI 0 "register_operand" "=A")
22030 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22031 (set (match_operand:SI 1 "register_operand" "=c")
22032 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22035 [(set_attr "type" "other")
22036 (set_attr "length" "3")])
22038 (define_insn "*rdtscp_rex64"
22039 [(set (match_operand:DI 0 "register_operand" "=a")
22040 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22041 (set (match_operand:DI 1 "register_operand" "=d")
22042 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22043 (set (match_operand:SI 2 "register_operand" "=c")
22044 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22047 [(set_attr "type" "other")
22048 (set_attr "length" "3")])
22052 (include "sync.md")