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 ;; Used in signed and unsigned widening multiplications.
706 (define_code_iterator any_extend [sign_extend zero_extend])
708 ;; Used in signed and unsigned divisions.
709 (define_code_iterator any_div [div udiv])
711 ;; Various insn prefixes for signed and unsigned operations.
712 (define_code_attr u [(sign_extend "") (zero_extend "u")
713 (div "") (udiv "u")])
714 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
716 ;; Instruction prefix for signed and unsigned operations.
717 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
718 (div "i") (udiv "")])
720 ;; All single word integer modes.
721 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
723 ;; Single word integer modes without QImode.
724 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
726 ;; Single word integer modes without QImode and HImode.
727 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
729 ;; All math-dependant single and double word integer modes.
730 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
731 (HI "TARGET_HIMODE_MATH")
732 SI DI (TI "TARGET_64BIT")])
734 ;; Math-dependant single word integer modes without QImode.
735 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
736 SI (DI "TARGET_64BIT")])
738 ;; Half mode for double word integer modes.
739 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
740 (DI "TARGET_64BIT")])
742 ;; Double word integer modes.
743 (define_mode_attr DWI [(SI "DI") (DI "TI")])
744 (define_mode_attr dwi [(SI "di") (DI "ti")])
746 ;; Instruction suffix for integer modes.
747 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
749 ;; Register class for integer modes.
750 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
752 ;; Immediate operand constraint for integer modes.
753 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
755 ;; General operand constraint for word modes.
756 (define_mode_attr g [(SI "g") (DI "rme")])
758 ;; Immediate operand constraint for double integer modes.
759 (define_mode_attr di [(SI "iF") (DI "e")])
761 ;; General operand predicate for integer modes.
762 (define_mode_attr general_operand
763 [(QI "general_operand")
764 (HI "general_operand")
765 (SI "general_operand")
766 (DI "x86_64_general_operand")
767 (TI "x86_64_general_operand")])
769 ;; SSE and x87 SFmode and DFmode floating point modes
770 (define_mode_iterator MODEF [SF DF])
772 ;; All x87 floating point modes
773 (define_mode_iterator X87MODEF [SF DF XF])
775 ;; All integer modes handled by x87 fisttp operator.
776 (define_mode_iterator X87MODEI [HI SI DI])
778 ;; All integer modes handled by integer x87 operators.
779 (define_mode_iterator X87MODEI12 [HI SI])
781 ;; All integer modes handled by SSE cvtts?2si* operators.
782 (define_mode_iterator SSEMODEI24 [SI DI])
784 ;; SSE asm suffix for floating point modes
785 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
787 ;; SSE vector mode corresponding to a scalar mode
788 (define_mode_attr ssevecmode
789 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
791 ;; Instruction suffix for REX 64bit operators.
792 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
794 ;; This mode iterator allows :P to be used for patterns that operate on
795 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
796 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
798 ;; Scheduling descriptions
800 (include "pentium.md")
803 (include "athlon.md")
808 ;; Operand and operator predicates and constraints
810 (include "predicates.md")
811 (include "constraints.md")
814 ;; Compare and branch/compare and store instructions.
816 (define_expand "cbranchti4"
817 [(set (reg:CC FLAGS_REG)
818 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
819 (match_operand:TI 2 "x86_64_general_operand" "")))
820 (set (pc) (if_then_else
821 (match_operator 0 "comparison_operator"
824 (label_ref (match_operand 3 "" ""))
828 if (MEM_P (operands[1]) && MEM_P (operands[2]))
829 operands[1] = force_reg (TImode, operands[1]);
830 ix86_compare_op0 = operands[1];
831 ix86_compare_op1 = operands[2];
832 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
836 (define_expand "cbranchdi4"
837 [(set (reg:CC FLAGS_REG)
838 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
839 (match_operand:DI 2 "x86_64_general_operand" "")))
840 (set (pc) (if_then_else
841 (match_operator 0 "comparison_operator"
844 (label_ref (match_operand 3 "" ""))
848 if (MEM_P (operands[1]) && MEM_P (operands[2]))
849 operands[1] = force_reg (DImode, operands[1]);
850 ix86_compare_op0 = operands[1];
851 ix86_compare_op1 = operands[2];
852 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
856 (define_expand "cstoredi4"
857 [(set (reg:CC FLAGS_REG)
858 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
859 (match_operand:DI 3 "x86_64_general_operand" "")))
860 (set (match_operand:QI 0 "register_operand" "")
861 (match_operator 1 "comparison_operator"
866 if (MEM_P (operands[2]) && MEM_P (operands[3]))
867 operands[2] = force_reg (DImode, operands[2]);
868 ix86_compare_op0 = operands[2];
869 ix86_compare_op1 = operands[3];
870 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
874 (define_expand "cbranchsi4"
875 [(set (reg:CC FLAGS_REG)
876 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
877 (match_operand:SI 2 "general_operand" "")))
878 (set (pc) (if_then_else
879 (match_operator 0 "comparison_operator"
882 (label_ref (match_operand 3 "" ""))
886 if (MEM_P (operands[1]) && MEM_P (operands[2]))
887 operands[1] = force_reg (SImode, operands[1]);
888 ix86_compare_op0 = operands[1];
889 ix86_compare_op1 = operands[2];
890 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
894 (define_expand "cstoresi4"
895 [(set (reg:CC FLAGS_REG)
896 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
897 (match_operand:SI 3 "general_operand" "")))
898 (set (match_operand:QI 0 "register_operand" "")
899 (match_operator 1 "comparison_operator"
904 if (MEM_P (operands[2]) && MEM_P (operands[3]))
905 operands[2] = force_reg (SImode, operands[2]);
906 ix86_compare_op0 = operands[2];
907 ix86_compare_op1 = operands[3];
908 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
912 (define_expand "cbranchhi4"
913 [(set (reg:CC FLAGS_REG)
914 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
915 (match_operand:HI 2 "general_operand" "")))
916 (set (pc) (if_then_else
917 (match_operator 0 "comparison_operator"
920 (label_ref (match_operand 3 "" ""))
924 if (MEM_P (operands[1]) && MEM_P (operands[2]))
925 operands[1] = force_reg (HImode, operands[1]);
926 ix86_compare_op0 = operands[1];
927 ix86_compare_op1 = operands[2];
928 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
932 (define_expand "cstorehi4"
933 [(set (reg:CC FLAGS_REG)
934 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
935 (match_operand:HI 3 "general_operand" "")))
936 (set (match_operand:QI 0 "register_operand" "")
937 (match_operator 1 "comparison_operator"
942 if (MEM_P (operands[2]) && MEM_P (operands[3]))
943 operands[2] = force_reg (HImode, operands[2]);
944 ix86_compare_op0 = operands[2];
945 ix86_compare_op1 = operands[3];
946 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
951 (define_expand "cbranchqi4"
952 [(set (reg:CC FLAGS_REG)
953 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
954 (match_operand:QI 2 "general_operand" "")))
955 (set (pc) (if_then_else
956 (match_operator 0 "comparison_operator"
959 (label_ref (match_operand 3 "" ""))
963 if (MEM_P (operands[1]) && MEM_P (operands[2]))
964 operands[1] = force_reg (QImode, operands[1]);
965 ix86_compare_op0 = operands[1];
966 ix86_compare_op1 = operands[2];
967 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
972 (define_expand "cstoreqi4"
973 [(set (reg:CC FLAGS_REG)
974 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
975 (match_operand:QI 3 "general_operand" "")))
976 (set (match_operand:QI 0 "register_operand" "")
977 (match_operator 1 "comparison_operator"
982 if (MEM_P (operands[2]) && MEM_P (operands[3]))
983 operands[2] = force_reg (QImode, operands[2]);
984 ix86_compare_op0 = operands[2];
985 ix86_compare_op1 = operands[3];
986 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
991 (define_insn "cmpdi_ccno_1_rex64"
992 [(set (reg FLAGS_REG)
993 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
994 (match_operand:DI 1 "const0_operand" "")))]
995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
998 cmp{q}\t{%1, %0|%0, %1}"
999 [(set_attr "type" "test,icmp")
1000 (set_attr "length_immediate" "0,1")
1001 (set_attr "mode" "DI")])
1003 (define_insn "*cmpdi_minus_1_rex64"
1004 [(set (reg FLAGS_REG)
1005 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1006 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1008 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1009 "cmp{q}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "icmp")
1011 (set_attr "mode" "DI")])
1013 (define_expand "cmpdi_1_rex64"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1016 (match_operand:DI 1 "general_operand" "")))]
1020 (define_insn "cmpdi_1_insn_rex64"
1021 [(set (reg FLAGS_REG)
1022 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1023 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1024 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{q}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "DI")])
1030 (define_insn "*cmpsi_ccno_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1033 (match_operand:SI 1 "const0_operand" "")))]
1034 "ix86_match_ccmode (insn, CCNOmode)"
1037 cmp{l}\t{%1, %0|%0, %1}"
1038 [(set_attr "type" "test,icmp")
1039 (set_attr "length_immediate" "0,1")
1040 (set_attr "mode" "SI")])
1042 (define_insn "*cmpsi_minus_1"
1043 [(set (reg FLAGS_REG)
1044 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1045 (match_operand:SI 1 "general_operand" "ri,mr"))
1047 "ix86_match_ccmode (insn, CCGOCmode)"
1048 "cmp{l}\t{%1, %0|%0, %1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "SI")])
1052 (define_expand "cmpsi_1"
1053 [(set (reg:CC FLAGS_REG)
1054 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1055 (match_operand:SI 1 "general_operand" "")))]
1059 (define_insn "*cmpsi_1_insn"
1060 [(set (reg FLAGS_REG)
1061 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1062 (match_operand:SI 1 "general_operand" "ri,mr")))]
1063 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1064 && ix86_match_ccmode (insn, CCmode)"
1065 "cmp{l}\t{%1, %0|%0, %1}"
1066 [(set_attr "type" "icmp")
1067 (set_attr "mode" "SI")])
1069 (define_insn "*cmphi_ccno_1"
1070 [(set (reg FLAGS_REG)
1071 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1072 (match_operand:HI 1 "const0_operand" "")))]
1073 "ix86_match_ccmode (insn, CCNOmode)"
1076 cmp{w}\t{%1, %0|%0, %1}"
1077 [(set_attr "type" "test,icmp")
1078 (set_attr "length_immediate" "0,1")
1079 (set_attr "mode" "HI")])
1081 (define_insn "*cmphi_minus_1"
1082 [(set (reg FLAGS_REG)
1083 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1084 (match_operand:HI 1 "general_operand" "rn,mr"))
1086 "ix86_match_ccmode (insn, CCGOCmode)"
1087 "cmp{w}\t{%1, %0|%0, %1}"
1088 [(set_attr "type" "icmp")
1089 (set_attr "mode" "HI")])
1091 (define_insn "*cmphi_1"
1092 [(set (reg FLAGS_REG)
1093 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1094 (match_operand:HI 1 "general_operand" "rn,mr")))]
1095 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1096 && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{w}\t{%1, %0|%0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "mode" "HI")])
1101 (define_insn "*cmpqi_ccno_1"
1102 [(set (reg FLAGS_REG)
1103 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1104 (match_operand:QI 1 "const0_operand" "")))]
1105 "ix86_match_ccmode (insn, CCNOmode)"
1108 cmp{b}\t{$0, %0|%0, 0}"
1109 [(set_attr "type" "test,icmp")
1110 (set_attr "length_immediate" "0,1")
1111 (set_attr "mode" "QI")])
1113 (define_insn "*cmpqi_1"
1114 [(set (reg FLAGS_REG)
1115 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1116 (match_operand:QI 1 "general_operand" "qn,mq")))]
1117 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1118 && ix86_match_ccmode (insn, CCmode)"
1119 "cmp{b}\t{%1, %0|%0, %1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1123 (define_insn "*cmpqi_minus_1"
1124 [(set (reg FLAGS_REG)
1125 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1126 (match_operand:QI 1 "general_operand" "qn,mq"))
1128 "ix86_match_ccmode (insn, CCGOCmode)"
1129 "cmp{b}\t{%1, %0|%0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_1"
1134 [(set (reg FLAGS_REG)
1136 (match_operand:QI 0 "general_operand" "Qm")
1139 (match_operand 1 "ext_register_operand" "Q")
1141 (const_int 8)) 0)))]
1142 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %0|%0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 (define_insn "*cmpqi_ext_1_rex64"
1148 [(set (reg FLAGS_REG)
1150 (match_operand:QI 0 "register_operand" "Q")
1153 (match_operand 1 "ext_register_operand" "Q")
1155 (const_int 8)) 0)))]
1156 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1157 "cmp{b}\t{%h1, %0|%0, %h1}"
1158 [(set_attr "type" "icmp")
1159 (set_attr "mode" "QI")])
1161 (define_insn "*cmpqi_ext_2"
1162 [(set (reg FLAGS_REG)
1166 (match_operand 0 "ext_register_operand" "Q")
1169 (match_operand:QI 1 "const0_operand" "")))]
1170 "ix86_match_ccmode (insn, CCNOmode)"
1172 [(set_attr "type" "test")
1173 (set_attr "length_immediate" "0")
1174 (set_attr "mode" "QI")])
1176 (define_expand "cmpqi_ext_3"
1177 [(set (reg:CC FLAGS_REG)
1181 (match_operand 0 "ext_register_operand" "")
1184 (match_operand:QI 1 "general_operand" "")))]
1188 (define_insn "cmpqi_ext_3_insn"
1189 [(set (reg FLAGS_REG)
1193 (match_operand 0 "ext_register_operand" "Q")
1196 (match_operand:QI 1 "general_operand" "Qmn")))]
1197 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1198 "cmp{b}\t{%1, %h0|%h0, %1}"
1199 [(set_attr "type" "icmp")
1200 (set_attr "modrm" "1")
1201 (set_attr "mode" "QI")])
1203 (define_insn "cmpqi_ext_3_insn_rex64"
1204 [(set (reg FLAGS_REG)
1208 (match_operand 0 "ext_register_operand" "Q")
1211 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1212 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1213 "cmp{b}\t{%1, %h0|%h0, %1}"
1214 [(set_attr "type" "icmp")
1215 (set_attr "modrm" "1")
1216 (set_attr "mode" "QI")])
1218 (define_insn "*cmpqi_ext_4"
1219 [(set (reg FLAGS_REG)
1223 (match_operand 0 "ext_register_operand" "Q")
1228 (match_operand 1 "ext_register_operand" "Q")
1230 (const_int 8)) 0)))]
1231 "ix86_match_ccmode (insn, CCmode)"
1232 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1233 [(set_attr "type" "icmp")
1234 (set_attr "mode" "QI")])
1236 ;; These implement float point compares.
1237 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1238 ;; which would allow mix and match FP modes on the compares. Which is what
1239 ;; the old patterns did, but with many more of them.
1241 (define_expand "cbranchxf4"
1242 [(set (reg:CC FLAGS_REG)
1243 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1244 (match_operand:XF 2 "nonmemory_operand" "")))
1245 (set (pc) (if_then_else
1246 (match_operator 0 "ix86_fp_comparison_operator"
1249 (label_ref (match_operand 3 "" ""))
1253 ix86_compare_op0 = operands[1];
1254 ix86_compare_op1 = operands[2];
1255 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1259 (define_expand "cstorexf4"
1260 [(set (reg:CC FLAGS_REG)
1261 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1262 (match_operand:XF 3 "nonmemory_operand" "")))
1263 (set (match_operand:QI 0 "register_operand" "")
1264 (match_operator 1 "ix86_fp_comparison_operator"
1269 ix86_compare_op0 = operands[2];
1270 ix86_compare_op1 = operands[3];
1271 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1275 (define_expand "cbranch<mode>4"
1276 [(set (reg:CC FLAGS_REG)
1277 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1278 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1279 (set (pc) (if_then_else
1280 (match_operator 0 "ix86_fp_comparison_operator"
1283 (label_ref (match_operand 3 "" ""))
1285 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1287 ix86_compare_op0 = operands[1];
1288 ix86_compare_op1 = operands[2];
1289 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1293 (define_expand "cstore<mode>4"
1294 [(set (reg:CC FLAGS_REG)
1295 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1296 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1297 (set (match_operand:QI 0 "register_operand" "")
1298 (match_operator 1 "ix86_fp_comparison_operator"
1301 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1303 ix86_compare_op0 = operands[2];
1304 ix86_compare_op1 = operands[3];
1305 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1309 (define_expand "cbranchcc4"
1310 [(set (pc) (if_then_else
1311 (match_operator 0 "comparison_operator"
1312 [(match_operand 1 "flags_reg_operand" "")
1313 (match_operand 2 "const0_operand" "")])
1314 (label_ref (match_operand 3 "" ""))
1318 ix86_compare_op0 = operands[1];
1319 ix86_compare_op1 = operands[2];
1320 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1324 (define_expand "cstorecc4"
1325 [(set (match_operand:QI 0 "register_operand" "")
1326 (match_operator 1 "comparison_operator"
1327 [(match_operand 2 "flags_reg_operand" "")
1328 (match_operand 3 "const0_operand" "")]))]
1331 ix86_compare_op0 = operands[2];
1332 ix86_compare_op1 = operands[3];
1333 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1338 ;; FP compares, step 1:
1339 ;; Set the FP condition codes.
1341 ;; CCFPmode compare with exceptions
1342 ;; CCFPUmode compare with no exceptions
1344 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1345 ;; used to manage the reg stack popping would not be preserved.
1347 (define_insn "*cmpfp_0"
1348 [(set (match_operand:HI 0 "register_operand" "=a")
1351 (match_operand 1 "register_operand" "f")
1352 (match_operand 2 "const0_operand" ""))]
1354 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1355 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1356 "* return output_fp_compare (insn, operands, 0, 0);"
1357 [(set_attr "type" "multi")
1358 (set_attr "unit" "i387")
1360 (cond [(match_operand:SF 1 "" "")
1362 (match_operand:DF 1 "" "")
1365 (const_string "XF")))])
1367 (define_insn_and_split "*cmpfp_0_cc"
1368 [(set (reg:CCFP FLAGS_REG)
1370 (match_operand 1 "register_operand" "f")
1371 (match_operand 2 "const0_operand" "")))
1372 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && TARGET_SAHF && !TARGET_CMOVE
1375 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "&& reload_completed"
1380 [(compare:CCFP (match_dup 1)(match_dup 2))]
1382 (set (reg:CC FLAGS_REG)
1383 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1385 [(set_attr "type" "multi")
1386 (set_attr "unit" "i387")
1388 (cond [(match_operand:SF 1 "" "")
1390 (match_operand:DF 1 "" "")
1393 (const_string "XF")))])
1395 (define_insn "*cmpfp_xf"
1396 [(set (match_operand:HI 0 "register_operand" "=a")
1399 (match_operand:XF 1 "register_operand" "f")
1400 (match_operand:XF 2 "register_operand" "f"))]
1403 "* return output_fp_compare (insn, operands, 0, 0);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "mode" "XF")])
1408 (define_insn_and_split "*cmpfp_xf_cc"
1409 [(set (reg:CCFP FLAGS_REG)
1411 (match_operand:XF 1 "register_operand" "f")
1412 (match_operand:XF 2 "register_operand" "f")))
1413 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1415 && TARGET_SAHF && !TARGET_CMOVE"
1417 "&& reload_completed"
1420 [(compare:CCFP (match_dup 1)(match_dup 2))]
1422 (set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "mode" "XF")])
1429 (define_insn "*cmpfp_<mode>"
1430 [(set (match_operand:HI 0 "register_operand" "=a")
1433 (match_operand:MODEF 1 "register_operand" "f")
1434 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1437 "* return output_fp_compare (insn, operands, 0, 0);"
1438 [(set_attr "type" "multi")
1439 (set_attr "unit" "i387")
1440 (set_attr "mode" "<MODE>")])
1442 (define_insn_and_split "*cmpfp_<mode>_cc"
1443 [(set (reg:CCFP FLAGS_REG)
1445 (match_operand:MODEF 1 "register_operand" "f")
1446 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1447 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1449 && TARGET_SAHF && !TARGET_CMOVE"
1451 "&& reload_completed"
1454 [(compare:CCFP (match_dup 1)(match_dup 2))]
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "mode" "<MODE>")])
1463 (define_insn "*cmpfp_u"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1467 (match_operand 1 "register_operand" "f")
1468 (match_operand 2 "register_operand" "f"))]
1470 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1471 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1472 "* return output_fp_compare (insn, operands, 0, 1);"
1473 [(set_attr "type" "multi")
1474 (set_attr "unit" "i387")
1476 (cond [(match_operand:SF 1 "" "")
1478 (match_operand:DF 1 "" "")
1481 (const_string "XF")))])
1483 (define_insn_and_split "*cmpfp_u_cc"
1484 [(set (reg:CCFPU FLAGS_REG)
1486 (match_operand 1 "register_operand" "f")
1487 (match_operand 2 "register_operand" "f")))
1488 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1489 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1490 && TARGET_SAHF && !TARGET_CMOVE
1491 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1493 "&& reload_completed"
1496 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1498 (set (reg:CC FLAGS_REG)
1499 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1501 [(set_attr "type" "multi")
1502 (set_attr "unit" "i387")
1504 (cond [(match_operand:SF 1 "" "")
1506 (match_operand:DF 1 "" "")
1509 (const_string "XF")))])
1511 (define_insn "*cmpfp_<mode>"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1515 (match_operand 1 "register_operand" "f")
1516 (match_operator 3 "float_operator"
1517 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1520 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1521 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1522 "* return output_fp_compare (insn, operands, 0, 0);"
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "fp_int_src" "true")
1526 (set_attr "mode" "<MODE>")])
1528 (define_insn_and_split "*cmpfp_<mode>_cc"
1529 [(set (reg:CCFP FLAGS_REG)
1531 (match_operand 1 "register_operand" "f")
1532 (match_operator 3 "float_operator"
1533 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1534 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1536 && TARGET_SAHF && !TARGET_CMOVE
1537 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1538 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1540 "&& reload_completed"
1545 (match_op_dup 3 [(match_dup 2)]))]
1547 (set (reg:CC FLAGS_REG)
1548 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "fp_int_src" "true")
1553 (set_attr "mode" "<MODE>")])
1555 ;; FP compares, step 2
1556 ;; Move the fpsw to ax.
1558 (define_insn "x86_fnstsw_1"
1559 [(set (match_operand:HI 0 "register_operand" "=a")
1560 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1563 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1564 (set_attr "mode" "SI")
1565 (set_attr "unit" "i387")])
1567 ;; FP compares, step 3
1568 ;; Get ax into flags, general case.
1570 (define_insn "x86_sahf_1"
1571 [(set (reg:CC FLAGS_REG)
1572 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1576 #ifdef HAVE_AS_IX86_SAHF
1579 return ASM_BYTE "0x9e";
1582 [(set_attr "length" "1")
1583 (set_attr "athlon_decode" "vector")
1584 (set_attr "amdfam10_decode" "direct")
1585 (set_attr "mode" "SI")])
1587 ;; Pentium Pro can do steps 1 through 3 in one go.
1588 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1589 (define_insn "*cmpfp_i_mixed"
1590 [(set (reg:CCFP FLAGS_REG)
1591 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1592 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1593 "TARGET_MIX_SSE_I387
1594 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, 1, 0);"
1597 [(set_attr "type" "fcmp,ssecomi")
1598 (set_attr "prefix" "orig,maybe_vex")
1600 (if_then_else (match_operand:SF 1 "" "")
1602 (const_string "DF")))
1603 (set (attr "prefix_rep")
1604 (if_then_else (eq_attr "type" "ssecomi")
1606 (const_string "*")))
1607 (set (attr "prefix_data16")
1608 (cond [(eq_attr "type" "fcmp")
1610 (eq_attr "mode" "DF")
1613 (const_string "0")))
1614 (set_attr "athlon_decode" "vector")
1615 (set_attr "amdfam10_decode" "direct")])
1617 (define_insn "*cmpfp_i_sse"
1618 [(set (reg:CCFP FLAGS_REG)
1619 (compare:CCFP (match_operand 0 "register_operand" "x")
1620 (match_operand 1 "nonimmediate_operand" "xm")))]
1622 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1623 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1624 "* return output_fp_compare (insn, operands, 1, 0);"
1625 [(set_attr "type" "ssecomi")
1626 (set_attr "prefix" "maybe_vex")
1628 (if_then_else (match_operand:SF 1 "" "")
1630 (const_string "DF")))
1631 (set_attr "prefix_rep" "0")
1632 (set (attr "prefix_data16")
1633 (if_then_else (eq_attr "mode" "DF")
1635 (const_string "0")))
1636 (set_attr "athlon_decode" "vector")
1637 (set_attr "amdfam10_decode" "direct")])
1639 (define_insn "*cmpfp_i_i387"
1640 [(set (reg:CCFP FLAGS_REG)
1641 (compare:CCFP (match_operand 0 "register_operand" "f")
1642 (match_operand 1 "register_operand" "f")))]
1643 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1645 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1646 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1647 "* return output_fp_compare (insn, operands, 1, 0);"
1648 [(set_attr "type" "fcmp")
1650 (cond [(match_operand:SF 1 "" "")
1652 (match_operand:DF 1 "" "")
1655 (const_string "XF")))
1656 (set_attr "athlon_decode" "vector")
1657 (set_attr "amdfam10_decode" "direct")])
1659 (define_insn "*cmpfp_iu_mixed"
1660 [(set (reg:CCFPU FLAGS_REG)
1661 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1662 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1663 "TARGET_MIX_SSE_I387
1664 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1665 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1666 "* return output_fp_compare (insn, operands, 1, 1);"
1667 [(set_attr "type" "fcmp,ssecomi")
1668 (set_attr "prefix" "orig,maybe_vex")
1670 (if_then_else (match_operand:SF 1 "" "")
1672 (const_string "DF")))
1673 (set (attr "prefix_rep")
1674 (if_then_else (eq_attr "type" "ssecomi")
1676 (const_string "*")))
1677 (set (attr "prefix_data16")
1678 (cond [(eq_attr "type" "fcmp")
1680 (eq_attr "mode" "DF")
1683 (const_string "0")))
1684 (set_attr "athlon_decode" "vector")
1685 (set_attr "amdfam10_decode" "direct")])
1687 (define_insn "*cmpfp_iu_sse"
1688 [(set (reg:CCFPU FLAGS_REG)
1689 (compare:CCFPU (match_operand 0 "register_operand" "x")
1690 (match_operand 1 "nonimmediate_operand" "xm")))]
1692 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1693 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1694 "* return output_fp_compare (insn, operands, 1, 1);"
1695 [(set_attr "type" "ssecomi")
1696 (set_attr "prefix" "maybe_vex")
1698 (if_then_else (match_operand:SF 1 "" "")
1700 (const_string "DF")))
1701 (set_attr "prefix_rep" "0")
1702 (set (attr "prefix_data16")
1703 (if_then_else (eq_attr "mode" "DF")
1705 (const_string "0")))
1706 (set_attr "athlon_decode" "vector")
1707 (set_attr "amdfam10_decode" "direct")])
1709 (define_insn "*cmpfp_iu_387"
1710 [(set (reg:CCFPU FLAGS_REG)
1711 (compare:CCFPU (match_operand 0 "register_operand" "f")
1712 (match_operand 1 "register_operand" "f")))]
1713 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1715 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1716 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1717 "* return output_fp_compare (insn, operands, 1, 1);"
1718 [(set_attr "type" "fcmp")
1720 (cond [(match_operand:SF 1 "" "")
1722 (match_operand:DF 1 "" "")
1725 (const_string "XF")))
1726 (set_attr "athlon_decode" "vector")
1727 (set_attr "amdfam10_decode" "direct")])
1729 ;; Move instructions.
1731 ;; General case of fullword move.
1733 (define_expand "movsi"
1734 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1735 (match_operand:SI 1 "general_operand" ""))]
1737 "ix86_expand_move (SImode, operands); DONE;")
1739 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1742 ;; %%% We don't use a post-inc memory reference because x86 is not a
1743 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1744 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1745 ;; targets without our curiosities, and it is just as easy to represent
1746 ;; this differently.
1748 (define_insn "*pushsi2"
1749 [(set (match_operand:SI 0 "push_operand" "=<")
1750 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1753 [(set_attr "type" "push")
1754 (set_attr "mode" "SI")])
1756 ;; For 64BIT abi we always round up to 8 bytes.
1757 (define_insn "*pushsi2_rex64"
1758 [(set (match_operand:SI 0 "push_operand" "=X")
1759 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1762 [(set_attr "type" "push")
1763 (set_attr "mode" "SI")])
1765 (define_insn "*pushsi2_prologue"
1766 [(set (match_operand:SI 0 "push_operand" "=<")
1767 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1768 (clobber (mem:BLK (scratch)))]
1771 [(set_attr "type" "push")
1772 (set_attr "mode" "SI")])
1774 (define_insn "*popsi1_epilogue"
1775 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1776 (mem:SI (reg:SI SP_REG)))
1777 (set (reg:SI SP_REG)
1778 (plus:SI (reg:SI SP_REG) (const_int 4)))
1779 (clobber (mem:BLK (scratch)))]
1782 [(set_attr "type" "pop")
1783 (set_attr "mode" "SI")])
1785 (define_insn "popsi1"
1786 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1787 (mem:SI (reg:SI SP_REG)))
1788 (set (reg:SI SP_REG)
1789 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1792 [(set_attr "type" "pop")
1793 (set_attr "mode" "SI")])
1795 (define_insn "*movsi_xor"
1796 [(set (match_operand:SI 0 "register_operand" "=r")
1797 (match_operand:SI 1 "const0_operand" ""))
1798 (clobber (reg:CC FLAGS_REG))]
1801 [(set_attr "type" "alu1")
1802 (set_attr "mode" "SI")
1803 (set_attr "length_immediate" "0")])
1805 (define_insn "*movsi_or"
1806 [(set (match_operand:SI 0 "register_operand" "=r")
1807 (match_operand:SI 1 "immediate_operand" "i"))
1808 (clobber (reg:CC FLAGS_REG))]
1810 && operands[1] == constm1_rtx"
1812 operands[1] = constm1_rtx;
1813 return "or{l}\t{%1, %0|%0, %1}";
1815 [(set_attr "type" "alu1")
1816 (set_attr "mode" "SI")
1817 (set_attr "length_immediate" "1")])
1819 (define_insn "*movsi_1"
1820 [(set (match_operand:SI 0 "nonimmediate_operand"
1821 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1822 (match_operand:SI 1 "general_operand"
1823 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1824 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 switch (get_attr_type (insn))
1829 if (get_attr_mode (insn) == MODE_TI)
1830 return "%vpxor\t%0, %d0";
1831 return "%vxorps\t%0, %d0";
1834 switch (get_attr_mode (insn))
1837 return "%vmovdqa\t{%1, %0|%0, %1}";
1839 return "%vmovaps\t{%1, %0|%0, %1}";
1841 return "%vmovd\t{%1, %0|%0, %1}";
1843 return "%vmovss\t{%1, %0|%0, %1}";
1849 return "pxor\t%0, %0";
1852 if (get_attr_mode (insn) == MODE_DI)
1853 return "movq\t{%1, %0|%0, %1}";
1854 return "movd\t{%1, %0|%0, %1}";
1857 return "lea{l}\t{%1, %0|%0, %1}";
1860 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1861 return "mov{l}\t{%1, %0|%0, %1}";
1865 (cond [(eq_attr "alternative" "2")
1866 (const_string "mmx")
1867 (eq_attr "alternative" "3,4,5")
1868 (const_string "mmxmov")
1869 (eq_attr "alternative" "6")
1870 (const_string "sselog1")
1871 (eq_attr "alternative" "7,8,9,10,11")
1872 (const_string "ssemov")
1873 (match_operand:DI 1 "pic_32bit_operand" "")
1874 (const_string "lea")
1876 (const_string "imov")))
1877 (set (attr "prefix")
1878 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1879 (const_string "orig")
1880 (const_string "maybe_vex")))
1881 (set (attr "prefix_data16")
1882 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1884 (const_string "*")))
1886 (cond [(eq_attr "alternative" "2,3")
1888 (eq_attr "alternative" "6,7")
1890 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1891 (const_string "V4SF")
1892 (const_string "TI"))
1893 (and (eq_attr "alternative" "8,9,10,11")
1894 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1897 (const_string "SI")))])
1899 ;; Stores and loads of ax to arbitrary constant address.
1900 ;; We fake an second form of instruction to force reload to load address
1901 ;; into register when rax is not available
1902 (define_insn "*movabssi_1_rex64"
1903 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1904 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1905 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1907 movabs{l}\t{%1, %P0|%P0, %1}
1908 mov{l}\t{%1, %a0|%a0, %1}"
1909 [(set_attr "type" "imov")
1910 (set_attr "modrm" "0,*")
1911 (set_attr "length_address" "8,0")
1912 (set_attr "length_immediate" "0,*")
1913 (set_attr "memory" "store")
1914 (set_attr "mode" "SI")])
1916 (define_insn "*movabssi_2_rex64"
1917 [(set (match_operand:SI 0 "register_operand" "=a,r")
1918 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1919 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1921 movabs{l}\t{%P1, %0|%0, %P1}
1922 mov{l}\t{%a1, %0|%0, %a1}"
1923 [(set_attr "type" "imov")
1924 (set_attr "modrm" "0,*")
1925 (set_attr "length_address" "8,0")
1926 (set_attr "length_immediate" "0")
1927 (set_attr "memory" "load")
1928 (set_attr "mode" "SI")])
1930 (define_insn "*swapsi"
1931 [(set (match_operand:SI 0 "register_operand" "+r")
1932 (match_operand:SI 1 "register_operand" "+r"))
1937 [(set_attr "type" "imov")
1938 (set_attr "mode" "SI")
1939 (set_attr "pent_pair" "np")
1940 (set_attr "athlon_decode" "vector")
1941 (set_attr "amdfam10_decode" "double")])
1943 (define_expand "movhi"
1944 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1945 (match_operand:HI 1 "general_operand" ""))]
1947 "ix86_expand_move (HImode, operands); DONE;")
1949 (define_insn "*pushhi2"
1950 [(set (match_operand:HI 0 "push_operand" "=X")
1951 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1954 [(set_attr "type" "push")
1955 (set_attr "mode" "SI")])
1957 ;; For 64BIT abi we always round up to 8 bytes.
1958 (define_insn "*pushhi2_rex64"
1959 [(set (match_operand:HI 0 "push_operand" "=X")
1960 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1963 [(set_attr "type" "push")
1964 (set_attr "mode" "DI")])
1966 (define_insn "*movhi_1"
1967 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1968 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1969 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 switch (get_attr_type (insn))
1974 /* movzwl is faster than movw on p2 due to partial word stalls,
1975 though not as fast as an aligned movl. */
1976 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1978 if (get_attr_mode (insn) == MODE_SI)
1979 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1981 return "mov{w}\t{%1, %0|%0, %1}";
1985 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1986 (const_string "imov")
1987 (and (eq_attr "alternative" "0")
1988 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1990 (eq (symbol_ref "TARGET_HIMODE_MATH")
1992 (const_string "imov")
1993 (and (eq_attr "alternative" "1,2")
1994 (match_operand:HI 1 "aligned_operand" ""))
1995 (const_string "imov")
1996 (and (ne (symbol_ref "TARGET_MOVX")
1998 (eq_attr "alternative" "0,2"))
1999 (const_string "imovx")
2001 (const_string "imov")))
2003 (cond [(eq_attr "type" "imovx")
2005 (and (eq_attr "alternative" "1,2")
2006 (match_operand:HI 1 "aligned_operand" ""))
2008 (and (eq_attr "alternative" "0")
2009 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2011 (eq (symbol_ref "TARGET_HIMODE_MATH")
2015 (const_string "HI")))])
2017 ;; Stores and loads of ax to arbitrary constant address.
2018 ;; We fake an second form of instruction to force reload to load address
2019 ;; into register when rax is not available
2020 (define_insn "*movabshi_1_rex64"
2021 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2022 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2023 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2025 movabs{w}\t{%1, %P0|%P0, %1}
2026 mov{w}\t{%1, %a0|%a0, %1}"
2027 [(set_attr "type" "imov")
2028 (set_attr "modrm" "0,*")
2029 (set_attr "length_address" "8,0")
2030 (set_attr "length_immediate" "0,*")
2031 (set_attr "memory" "store")
2032 (set_attr "mode" "HI")])
2034 (define_insn "*movabshi_2_rex64"
2035 [(set (match_operand:HI 0 "register_operand" "=a,r")
2036 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2037 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2039 movabs{w}\t{%P1, %0|%0, %P1}
2040 mov{w}\t{%a1, %0|%0, %a1}"
2041 [(set_attr "type" "imov")
2042 (set_attr "modrm" "0,*")
2043 (set_attr "length_address" "8,0")
2044 (set_attr "length_immediate" "0")
2045 (set_attr "memory" "load")
2046 (set_attr "mode" "HI")])
2048 (define_insn "*swaphi_1"
2049 [(set (match_operand:HI 0 "register_operand" "+r")
2050 (match_operand:HI 1 "register_operand" "+r"))
2053 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2055 [(set_attr "type" "imov")
2056 (set_attr "mode" "SI")
2057 (set_attr "pent_pair" "np")
2058 (set_attr "athlon_decode" "vector")
2059 (set_attr "amdfam10_decode" "double")])
2061 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2062 (define_insn "*swaphi_2"
2063 [(set (match_operand:HI 0 "register_operand" "+r")
2064 (match_operand:HI 1 "register_operand" "+r"))
2067 "TARGET_PARTIAL_REG_STALL"
2069 [(set_attr "type" "imov")
2070 (set_attr "mode" "HI")
2071 (set_attr "pent_pair" "np")
2072 (set_attr "athlon_decode" "vector")])
2074 (define_expand "movstricthi"
2075 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2076 (match_operand:HI 1 "general_operand" ""))]
2079 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2081 /* Don't generate memory->memory moves, go through a register */
2082 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2083 operands[1] = force_reg (HImode, operands[1]);
2086 (define_insn "*movstricthi_1"
2087 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2088 (match_operand:HI 1 "general_operand" "rn,m"))]
2089 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2090 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091 "mov{w}\t{%1, %0|%0, %1}"
2092 [(set_attr "type" "imov")
2093 (set_attr "mode" "HI")])
2095 (define_insn "*movstricthi_xor"
2096 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2097 (match_operand:HI 1 "const0_operand" ""))
2098 (clobber (reg:CC FLAGS_REG))]
2101 [(set_attr "type" "alu1")
2102 (set_attr "mode" "HI")
2103 (set_attr "length_immediate" "0")])
2105 (define_expand "movqi"
2106 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2107 (match_operand:QI 1 "general_operand" ""))]
2109 "ix86_expand_move (QImode, operands); DONE;")
2111 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2112 ;; "push a byte". But actually we use pushl, which has the effect
2113 ;; of rounding the amount pushed up to a word.
2115 (define_insn "*pushqi2"
2116 [(set (match_operand:QI 0 "push_operand" "=X")
2117 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2120 [(set_attr "type" "push")
2121 (set_attr "mode" "SI")])
2123 ;; For 64BIT abi we always round up to 8 bytes.
2124 (define_insn "*pushqi2_rex64"
2125 [(set (match_operand:QI 0 "push_operand" "=X")
2126 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2129 [(set_attr "type" "push")
2130 (set_attr "mode" "DI")])
2132 ;; Situation is quite tricky about when to choose full sized (SImode) move
2133 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2134 ;; partial register dependency machines (such as AMD Athlon), where QImode
2135 ;; moves issue extra dependency and for partial register stalls machines
2136 ;; that don't use QImode patterns (and QImode move cause stall on the next
2139 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2140 ;; register stall machines with, where we use QImode instructions, since
2141 ;; partial register stall can be caused there. Then we use movzx.
2142 (define_insn "*movqi_1"
2143 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2144 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2145 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2147 switch (get_attr_type (insn))
2150 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2151 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2153 if (get_attr_mode (insn) == MODE_SI)
2154 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2156 return "mov{b}\t{%1, %0|%0, %1}";
2160 (cond [(and (eq_attr "alternative" "5")
2161 (not (match_operand:QI 1 "aligned_operand" "")))
2162 (const_string "imovx")
2163 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2164 (const_string "imov")
2165 (and (eq_attr "alternative" "3")
2166 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2168 (eq (symbol_ref "TARGET_QIMODE_MATH")
2170 (const_string "imov")
2171 (eq_attr "alternative" "3,5")
2172 (const_string "imovx")
2173 (and (ne (symbol_ref "TARGET_MOVX")
2175 (eq_attr "alternative" "2"))
2176 (const_string "imovx")
2178 (const_string "imov")))
2180 (cond [(eq_attr "alternative" "3,4,5")
2182 (eq_attr "alternative" "6")
2184 (eq_attr "type" "imovx")
2186 (and (eq_attr "type" "imov")
2187 (and (eq_attr "alternative" "0,1")
2188 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2190 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2192 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2195 ;; Avoid partial register stalls when not using QImode arithmetic
2196 (and (eq_attr "type" "imov")
2197 (and (eq_attr "alternative" "0,1")
2198 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2200 (eq (symbol_ref "TARGET_QIMODE_MATH")
2204 (const_string "QI")))])
2206 (define_insn "*swapqi_1"
2207 [(set (match_operand:QI 0 "register_operand" "+r")
2208 (match_operand:QI 1 "register_operand" "+r"))
2211 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2213 [(set_attr "type" "imov")
2214 (set_attr "mode" "SI")
2215 (set_attr "pent_pair" "np")
2216 (set_attr "athlon_decode" "vector")
2217 (set_attr "amdfam10_decode" "vector")])
2219 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2220 (define_insn "*swapqi_2"
2221 [(set (match_operand:QI 0 "register_operand" "+q")
2222 (match_operand:QI 1 "register_operand" "+q"))
2225 "TARGET_PARTIAL_REG_STALL"
2227 [(set_attr "type" "imov")
2228 (set_attr "mode" "QI")
2229 (set_attr "pent_pair" "np")
2230 (set_attr "athlon_decode" "vector")])
2232 (define_expand "movstrictqi"
2233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2234 (match_operand:QI 1 "general_operand" ""))]
2237 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2239 /* Don't generate memory->memory moves, go through a register. */
2240 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2241 operands[1] = force_reg (QImode, operands[1]);
2244 (define_insn "*movstrictqi_1"
2245 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2246 (match_operand:QI 1 "general_operand" "*qn,m"))]
2247 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2249 "mov{b}\t{%1, %0|%0, %1}"
2250 [(set_attr "type" "imov")
2251 (set_attr "mode" "QI")])
2253 (define_insn "*movstrictqi_xor"
2254 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2255 (match_operand:QI 1 "const0_operand" ""))
2256 (clobber (reg:CC FLAGS_REG))]
2259 [(set_attr "type" "alu1")
2260 (set_attr "mode" "QI")
2261 (set_attr "length_immediate" "0")])
2263 (define_insn "*movsi_extv_1"
2264 [(set (match_operand:SI 0 "register_operand" "=R")
2265 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2269 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2270 [(set_attr "type" "imovx")
2271 (set_attr "mode" "SI")])
2273 (define_insn "*movhi_extv_1"
2274 [(set (match_operand:HI 0 "register_operand" "=R")
2275 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2279 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2280 [(set_attr "type" "imovx")
2281 (set_attr "mode" "SI")])
2283 (define_insn "*movqi_extv_1"
2284 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2285 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2290 switch (get_attr_type (insn))
2293 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2295 return "mov{b}\t{%h1, %0|%0, %h1}";
2299 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2300 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2301 (ne (symbol_ref "TARGET_MOVX")
2303 (const_string "imovx")
2304 (const_string "imov")))
2306 (if_then_else (eq_attr "type" "imovx")
2308 (const_string "QI")))])
2310 (define_insn "*movqi_extv_1_rex64"
2311 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2312 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2317 switch (get_attr_type (insn))
2320 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2322 return "mov{b}\t{%h1, %0|%0, %h1}";
2326 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2327 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2328 (ne (symbol_ref "TARGET_MOVX")
2330 (const_string "imovx")
2331 (const_string "imov")))
2333 (if_then_else (eq_attr "type" "imovx")
2335 (const_string "QI")))])
2337 ;; Stores and loads of ax to arbitrary constant address.
2338 ;; We fake an second form of instruction to force reload to load address
2339 ;; into register when rax is not available
2340 (define_insn "*movabsqi_1_rex64"
2341 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2342 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2343 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2345 movabs{b}\t{%1, %P0|%P0, %1}
2346 mov{b}\t{%1, %a0|%a0, %1}"
2347 [(set_attr "type" "imov")
2348 (set_attr "modrm" "0,*")
2349 (set_attr "length_address" "8,0")
2350 (set_attr "length_immediate" "0,*")
2351 (set_attr "memory" "store")
2352 (set_attr "mode" "QI")])
2354 (define_insn "*movabsqi_2_rex64"
2355 [(set (match_operand:QI 0 "register_operand" "=a,r")
2356 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2357 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2359 movabs{b}\t{%P1, %0|%0, %P1}
2360 mov{b}\t{%a1, %0|%0, %a1}"
2361 [(set_attr "type" "imov")
2362 (set_attr "modrm" "0,*")
2363 (set_attr "length_address" "8,0")
2364 (set_attr "length_immediate" "0")
2365 (set_attr "memory" "load")
2366 (set_attr "mode" "QI")])
2368 (define_insn "*movdi_extzv_1"
2369 [(set (match_operand:DI 0 "register_operand" "=R")
2370 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2374 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2375 [(set_attr "type" "imovx")
2376 (set_attr "mode" "SI")])
2378 (define_insn "*movsi_extzv_1"
2379 [(set (match_operand:SI 0 "register_operand" "=R")
2380 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2384 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2385 [(set_attr "type" "imovx")
2386 (set_attr "mode" "SI")])
2388 (define_insn "*movqi_extzv_2"
2389 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2390 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2395 switch (get_attr_type (insn))
2398 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2400 return "mov{b}\t{%h1, %0|%0, %h1}";
2404 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2405 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2406 (ne (symbol_ref "TARGET_MOVX")
2408 (const_string "imovx")
2409 (const_string "imov")))
2411 (if_then_else (eq_attr "type" "imovx")
2413 (const_string "QI")))])
2415 (define_insn "*movqi_extzv_2_rex64"
2416 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2417 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2422 switch (get_attr_type (insn))
2425 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2427 return "mov{b}\t{%h1, %0|%0, %h1}";
2431 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2432 (ne (symbol_ref "TARGET_MOVX")
2434 (const_string "imovx")
2435 (const_string "imov")))
2437 (if_then_else (eq_attr "type" "imovx")
2439 (const_string "QI")))])
2441 (define_insn "movsi_insv_1"
2442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2445 (match_operand:SI 1 "general_operand" "Qmn"))]
2447 "mov{b}\t{%b1, %h0|%h0, %b1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "mode" "QI")])
2451 (define_insn "*movsi_insv_1_rex64"
2452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2455 (match_operand:SI 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 "movdi_insv_1_rex64"
2462 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2465 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2467 "mov{b}\t{%b1, %h0|%h0, %b1}"
2468 [(set_attr "type" "imov")
2469 (set_attr "mode" "QI")])
2471 (define_insn "*movqi_insv_2"
2472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2475 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2478 "mov{b}\t{%h1, %h0|%h0, %h1}"
2479 [(set_attr "type" "imov")
2480 (set_attr "mode" "QI")])
2482 (define_expand "movdi"
2483 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2484 (match_operand:DI 1 "general_operand" ""))]
2486 "ix86_expand_move (DImode, operands); DONE;")
2488 (define_insn "*pushdi"
2489 [(set (match_operand:DI 0 "push_operand" "=<")
2490 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2494 (define_insn "*pushdi2_rex64"
2495 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2496 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2501 [(set_attr "type" "push,multi")
2502 (set_attr "mode" "DI")])
2504 ;; Convert impossible pushes of immediate to existing instructions.
2505 ;; First try to get scratch register and go through it. In case this
2506 ;; fails, push sign extended lower part first and then overwrite
2507 ;; upper part by 32bit move.
2509 [(match_scratch:DI 2 "r")
2510 (set (match_operand:DI 0 "push_operand" "")
2511 (match_operand:DI 1 "immediate_operand" ""))]
2512 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2513 && !x86_64_immediate_operand (operands[1], DImode)"
2514 [(set (match_dup 2) (match_dup 1))
2515 (set (match_dup 0) (match_dup 2))]
2518 ;; We need to define this as both peepholer and splitter for case
2519 ;; peephole2 pass is not run.
2520 ;; "&& 1" is needed to keep it from matching the previous pattern.
2522 [(set (match_operand:DI 0 "push_operand" "")
2523 (match_operand:DI 1 "immediate_operand" ""))]
2524 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2525 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2526 [(set (match_dup 0) (match_dup 1))
2527 (set (match_dup 2) (match_dup 3))]
2528 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2529 operands[1] = gen_lowpart (DImode, operands[2]);
2530 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2535 [(set (match_operand:DI 0 "push_operand" "")
2536 (match_operand:DI 1 "immediate_operand" ""))]
2537 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2538 ? epilogue_completed : reload_completed)
2539 && !symbolic_operand (operands[1], DImode)
2540 && !x86_64_immediate_operand (operands[1], DImode)"
2541 [(set (match_dup 0) (match_dup 1))
2542 (set (match_dup 2) (match_dup 3))]
2543 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2544 operands[1] = gen_lowpart (DImode, operands[2]);
2545 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2549 (define_insn "*pushdi2_prologue_rex64"
2550 [(set (match_operand:DI 0 "push_operand" "=<")
2551 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2552 (clobber (mem:BLK (scratch)))]
2555 [(set_attr "type" "push")
2556 (set_attr "mode" "DI")])
2558 (define_insn "*popdi1_epilogue_rex64"
2559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2560 (mem:DI (reg:DI SP_REG)))
2561 (set (reg:DI SP_REG)
2562 (plus:DI (reg:DI SP_REG) (const_int 8)))
2563 (clobber (mem:BLK (scratch)))]
2566 [(set_attr "type" "pop")
2567 (set_attr "mode" "DI")])
2569 (define_insn "popdi1"
2570 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2571 (mem:DI (reg:DI SP_REG)))
2572 (set (reg:DI SP_REG)
2573 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2576 [(set_attr "type" "pop")
2577 (set_attr "mode" "DI")])
2579 (define_insn "*movdi_xor_rex64"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (match_operand:DI 1 "const0_operand" ""))
2582 (clobber (reg:CC FLAGS_REG))]
2584 && reload_completed"
2586 [(set_attr "type" "alu1")
2587 (set_attr "mode" "SI")
2588 (set_attr "length_immediate" "0")])
2590 (define_insn "*movdi_or_rex64"
2591 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (match_operand:DI 1 "const_int_operand" "i"))
2593 (clobber (reg:CC FLAGS_REG))]
2596 && operands[1] == constm1_rtx"
2598 operands[1] = constm1_rtx;
2599 return "or{q}\t{%1, %0|%0, %1}";
2601 [(set_attr "type" "alu1")
2602 (set_attr "mode" "DI")
2603 (set_attr "length_immediate" "1")])
2605 (define_insn "*movdi_2"
2606 [(set (match_operand:DI 0 "nonimmediate_operand"
2607 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2608 (match_operand:DI 1 "general_operand"
2609 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2610 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2615 movq\t{%1, %0|%0, %1}
2616 movq\t{%1, %0|%0, %1}
2618 %vmovq\t{%1, %0|%0, %1}
2619 %vmovdqa\t{%1, %0|%0, %1}
2620 %vmovq\t{%1, %0|%0, %1}
2622 movlps\t{%1, %0|%0, %1}
2623 movaps\t{%1, %0|%0, %1}
2624 movlps\t{%1, %0|%0, %1}"
2625 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2626 (set (attr "prefix")
2627 (if_then_else (eq_attr "alternative" "5,6,7,8")
2628 (const_string "vex")
2629 (const_string "orig")))
2630 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2633 [(set (match_operand:DI 0 "push_operand" "")
2634 (match_operand:DI 1 "general_operand" ""))]
2635 "!TARGET_64BIT && reload_completed
2636 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2638 "ix86_split_long_move (operands); DONE;")
2640 ;; %%% This multiword shite has got to go.
2642 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2643 (match_operand:DI 1 "general_operand" ""))]
2644 "!TARGET_64BIT && reload_completed
2645 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2646 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2648 "ix86_split_long_move (operands); DONE;")
2650 (define_insn "*movdi_1_rex64"
2651 [(set (match_operand:DI 0 "nonimmediate_operand"
2652 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2653 (match_operand:DI 1 "general_operand"
2654 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2655 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2657 switch (get_attr_type (insn))
2660 if (SSE_REG_P (operands[0]))
2661 return "movq2dq\t{%1, %0|%0, %1}";
2663 return "movdq2q\t{%1, %0|%0, %1}";
2668 if (get_attr_mode (insn) == MODE_TI)
2669 return "vmovdqa\t{%1, %0|%0, %1}";
2671 return "vmovq\t{%1, %0|%0, %1}";
2674 if (get_attr_mode (insn) == MODE_TI)
2675 return "movdqa\t{%1, %0|%0, %1}";
2679 /* Moves from and into integer register is done using movd
2680 opcode with REX prefix. */
2681 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2682 return "movd\t{%1, %0|%0, %1}";
2683 return "movq\t{%1, %0|%0, %1}";
2686 return "%vpxor\t%0, %d0";
2689 return "pxor\t%0, %0";
2695 return "lea{q}\t{%a1, %0|%0, %a1}";
2698 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2699 if (get_attr_mode (insn) == MODE_SI)
2700 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2701 else if (which_alternative == 2)
2702 return "movabs{q}\t{%1, %0|%0, %1}";
2704 return "mov{q}\t{%1, %0|%0, %1}";
2708 (cond [(eq_attr "alternative" "5")
2709 (const_string "mmx")
2710 (eq_attr "alternative" "6,7,8,9,10")
2711 (const_string "mmxmov")
2712 (eq_attr "alternative" "11")
2713 (const_string "sselog1")
2714 (eq_attr "alternative" "12,13,14,15,16")
2715 (const_string "ssemov")
2716 (eq_attr "alternative" "17,18")
2717 (const_string "ssecvt")
2718 (eq_attr "alternative" "4")
2719 (const_string "multi")
2720 (match_operand:DI 1 "pic_32bit_operand" "")
2721 (const_string "lea")
2723 (const_string "imov")))
2726 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2728 (const_string "*")))
2729 (set (attr "length_immediate")
2731 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2733 (const_string "*")))
2734 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2735 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2736 (set (attr "prefix")
2737 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2738 (const_string "maybe_vex")
2739 (const_string "orig")))
2740 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2742 ;; Stores and loads of ax to arbitrary constant address.
2743 ;; We fake an second form of instruction to force reload to load address
2744 ;; into register when rax is not available
2745 (define_insn "*movabsdi_1_rex64"
2746 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2747 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2748 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2750 movabs{q}\t{%1, %P0|%P0, %1}
2751 mov{q}\t{%1, %a0|%a0, %1}"
2752 [(set_attr "type" "imov")
2753 (set_attr "modrm" "0,*")
2754 (set_attr "length_address" "8,0")
2755 (set_attr "length_immediate" "0,*")
2756 (set_attr "memory" "store")
2757 (set_attr "mode" "DI")])
2759 (define_insn "*movabsdi_2_rex64"
2760 [(set (match_operand:DI 0 "register_operand" "=a,r")
2761 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2762 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2764 movabs{q}\t{%P1, %0|%0, %P1}
2765 mov{q}\t{%a1, %0|%0, %a1}"
2766 [(set_attr "type" "imov")
2767 (set_attr "modrm" "0,*")
2768 (set_attr "length_address" "8,0")
2769 (set_attr "length_immediate" "0")
2770 (set_attr "memory" "load")
2771 (set_attr "mode" "DI")])
2773 ;; Convert impossible stores of immediate to existing instructions.
2774 ;; First try to get scratch register and go through it. In case this
2775 ;; fails, move by 32bit parts.
2777 [(match_scratch:DI 2 "r")
2778 (set (match_operand:DI 0 "memory_operand" "")
2779 (match_operand:DI 1 "immediate_operand" ""))]
2780 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2781 && !x86_64_immediate_operand (operands[1], DImode)"
2782 [(set (match_dup 2) (match_dup 1))
2783 (set (match_dup 0) (match_dup 2))]
2786 ;; We need to define this as both peepholer and splitter for case
2787 ;; peephole2 pass is not run.
2788 ;; "&& 1" is needed to keep it from matching the previous pattern.
2790 [(set (match_operand:DI 0 "memory_operand" "")
2791 (match_operand:DI 1 "immediate_operand" ""))]
2792 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2793 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2794 [(set (match_dup 2) (match_dup 3))
2795 (set (match_dup 4) (match_dup 5))]
2796 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2799 [(set (match_operand:DI 0 "memory_operand" "")
2800 (match_operand:DI 1 "immediate_operand" ""))]
2801 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2802 ? epilogue_completed : reload_completed)
2803 && !symbolic_operand (operands[1], DImode)
2804 && !x86_64_immediate_operand (operands[1], DImode)"
2805 [(set (match_dup 2) (match_dup 3))
2806 (set (match_dup 4) (match_dup 5))]
2807 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2809 (define_insn "*swapdi_rex64"
2810 [(set (match_operand:DI 0 "register_operand" "+r")
2811 (match_operand:DI 1 "register_operand" "+r"))
2816 [(set_attr "type" "imov")
2817 (set_attr "mode" "DI")
2818 (set_attr "pent_pair" "np")
2819 (set_attr "athlon_decode" "vector")
2820 (set_attr "amdfam10_decode" "double")])
2822 (define_expand "movoi"
2823 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2824 (match_operand:OI 1 "general_operand" ""))]
2826 "ix86_expand_move (OImode, operands); DONE;")
2828 (define_insn "*movoi_internal"
2829 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2830 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2834 switch (which_alternative)
2837 return "vxorps\t%0, %0, %0";
2840 if (misaligned_operand (operands[0], OImode)
2841 || misaligned_operand (operands[1], OImode))
2842 return "vmovdqu\t{%1, %0|%0, %1}";
2844 return "vmovdqa\t{%1, %0|%0, %1}";
2849 [(set_attr "type" "sselog1,ssemov,ssemov")
2850 (set_attr "prefix" "vex")
2851 (set_attr "mode" "OI")])
2853 (define_expand "movti"
2854 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2855 (match_operand:TI 1 "nonimmediate_operand" ""))]
2856 "TARGET_SSE || TARGET_64BIT"
2859 ix86_expand_move (TImode, operands);
2860 else if (push_operand (operands[0], TImode))
2861 ix86_expand_push (TImode, operands[1]);
2863 ix86_expand_vector_move (TImode, operands);
2867 (define_insn "*movti_internal"
2868 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2869 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2870 "TARGET_SSE && !TARGET_64BIT
2871 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2873 switch (which_alternative)
2876 if (get_attr_mode (insn) == MODE_V4SF)
2877 return "%vxorps\t%0, %d0";
2879 return "%vpxor\t%0, %d0";
2882 /* TDmode values are passed as TImode on the stack. Moving them
2883 to stack may result in unaligned memory access. */
2884 if (misaligned_operand (operands[0], TImode)
2885 || misaligned_operand (operands[1], TImode))
2887 if (get_attr_mode (insn) == MODE_V4SF)
2888 return "%vmovups\t{%1, %0|%0, %1}";
2890 return "%vmovdqu\t{%1, %0|%0, %1}";
2894 if (get_attr_mode (insn) == MODE_V4SF)
2895 return "%vmovaps\t{%1, %0|%0, %1}";
2897 return "%vmovdqa\t{%1, %0|%0, %1}";
2903 [(set_attr "type" "sselog1,ssemov,ssemov")
2904 (set_attr "prefix" "maybe_vex")
2906 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2907 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2908 (const_string "V4SF")
2909 (and (eq_attr "alternative" "2")
2910 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2912 (const_string "V4SF")]
2913 (const_string "TI")))])
2915 (define_insn "*movti_rex64"
2916 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2917 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2921 switch (which_alternative)
2927 if (get_attr_mode (insn) == MODE_V4SF)
2928 return "%vxorps\t%0, %d0";
2930 return "%vpxor\t%0, %d0";
2933 /* TDmode values are passed as TImode on the stack. Moving them
2934 to stack may result in unaligned memory access. */
2935 if (misaligned_operand (operands[0], TImode)
2936 || misaligned_operand (operands[1], TImode))
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "%vmovups\t{%1, %0|%0, %1}";
2941 return "%vmovdqu\t{%1, %0|%0, %1}";
2945 if (get_attr_mode (insn) == MODE_V4SF)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovdqa\t{%1, %0|%0, %1}";
2954 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2955 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2957 (cond [(eq_attr "alternative" "2,3")
2959 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2961 (const_string "V4SF")
2962 (const_string "TI"))
2963 (eq_attr "alternative" "4")
2965 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2969 (const_string "V4SF")
2970 (const_string "TI"))]
2971 (const_string "DI")))])
2974 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2975 (match_operand:TI 1 "general_operand" ""))]
2976 "reload_completed && !SSE_REG_P (operands[0])
2977 && !SSE_REG_P (operands[1])"
2979 "ix86_split_long_move (operands); DONE;")
2981 ;; This expands to what emit_move_complex would generate if we didn't
2982 ;; have a movti pattern. Having this avoids problems with reload on
2983 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2984 ;; to have around all the time.
2985 (define_expand "movcdi"
2986 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2987 (match_operand:CDI 1 "general_operand" ""))]
2990 if (push_operand (operands[0], CDImode))
2991 emit_move_complex_push (CDImode, operands[0], operands[1]);
2993 emit_move_complex_parts (operands[0], operands[1]);
2997 (define_expand "movsf"
2998 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2999 (match_operand:SF 1 "general_operand" ""))]
3001 "ix86_expand_move (SFmode, operands); DONE;")
3003 (define_insn "*pushsf"
3004 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3005 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
3008 /* Anything else should be already split before reg-stack. */
3009 gcc_assert (which_alternative == 1);
3010 return "push{l}\t%1";
3012 [(set_attr "type" "multi,push,multi")
3013 (set_attr "unit" "i387,*,*")
3014 (set_attr "mode" "SF,SI,SF")])
3016 (define_insn "*pushsf_rex64"
3017 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3018 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3021 /* Anything else should be already split before reg-stack. */
3022 gcc_assert (which_alternative == 1);
3023 return "push{q}\t%q1";
3025 [(set_attr "type" "multi,push,multi")
3026 (set_attr "unit" "i387,*,*")
3027 (set_attr "mode" "SF,DI,SF")])
3030 [(set (match_operand:SF 0 "push_operand" "")
3031 (match_operand:SF 1 "memory_operand" ""))]
3033 && MEM_P (operands[1])
3034 && (operands[2] = find_constant_src (insn))"
3038 ;; %%% Kill this when call knows how to work this out.
3040 [(set (match_operand:SF 0 "push_operand" "")
3041 (match_operand:SF 1 "any_fp_register_operand" ""))]
3043 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3044 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3047 [(set (match_operand:SF 0 "push_operand" "")
3048 (match_operand:SF 1 "any_fp_register_operand" ""))]
3050 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3051 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3053 (define_insn "*movsf_1"
3054 [(set (match_operand:SF 0 "nonimmediate_operand"
3055 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3056 (match_operand:SF 1 "general_operand"
3057 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3058 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3059 && (reload_in_progress || reload_completed
3060 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3061 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3062 && standard_80387_constant_p (operands[1]))
3063 || GET_CODE (operands[1]) != CONST_DOUBLE
3064 || memory_operand (operands[0], SFmode))"
3066 switch (which_alternative)
3070 return output_387_reg_move (insn, operands);
3073 return standard_80387_constant_opcode (operands[1]);
3077 return "mov{l}\t{%1, %0|%0, %1}";
3079 if (get_attr_mode (insn) == MODE_TI)
3080 return "%vpxor\t%0, %d0";
3082 return "%vxorps\t%0, %d0";
3084 if (get_attr_mode (insn) == MODE_V4SF)
3085 return "%vmovaps\t{%1, %0|%0, %1}";
3087 return "%vmovss\t{%1, %d0|%d0, %1}";
3090 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3091 : "vmovss\t{%1, %0|%0, %1}";
3093 return "movss\t{%1, %0|%0, %1}";
3095 return "%vmovss\t{%1, %0|%0, %1}";
3097 case 9: case 10: case 14: case 15:
3098 return "movd\t{%1, %0|%0, %1}";
3100 return "%vmovd\t{%1, %0|%0, %1}";
3103 return "movq\t{%1, %0|%0, %1}";
3109 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3110 (set (attr "prefix")
3111 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3112 (const_string "maybe_vex")
3113 (const_string "orig")))
3115 (cond [(eq_attr "alternative" "3,4,9,10")
3117 (eq_attr "alternative" "5")
3119 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3121 (ne (symbol_ref "TARGET_SSE2")
3123 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3126 (const_string "V4SF"))
3127 /* For architectures resolving dependencies on
3128 whole SSE registers use APS move to break dependency
3129 chains, otherwise use short move to avoid extra work.
3131 Do the same for architectures resolving dependencies on
3132 the parts. While in DF mode it is better to always handle
3133 just register parts, the SF mode is different due to lack
3134 of instructions to load just part of the register. It is
3135 better to maintain the whole registers in single format
3136 to avoid problems on using packed logical operations. */
3137 (eq_attr "alternative" "6")
3139 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3141 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3143 (const_string "V4SF")
3144 (const_string "SF"))
3145 (eq_attr "alternative" "11")
3146 (const_string "DI")]
3147 (const_string "SF")))])
3149 (define_insn "*swapsf"
3150 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3151 (match_operand:SF 1 "fp_register_operand" "+f"))
3154 "reload_completed || TARGET_80387"
3156 if (STACK_TOP_P (operands[0]))
3161 [(set_attr "type" "fxch")
3162 (set_attr "mode" "SF")])
3164 (define_expand "movdf"
3165 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3166 (match_operand:DF 1 "general_operand" ""))]
3168 "ix86_expand_move (DFmode, operands); DONE;")
3170 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3171 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3172 ;; On the average, pushdf using integers can be still shorter. Allow this
3173 ;; pattern for optimize_size too.
3175 (define_insn "*pushdf_nointeger"
3176 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3177 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3178 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3180 /* This insn should be already split before reg-stack. */
3183 [(set_attr "type" "multi")
3184 (set_attr "unit" "i387,*,*,*")
3185 (set_attr "mode" "DF,SI,SI,DF")])
3187 (define_insn "*pushdf_integer"
3188 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3189 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3190 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3192 /* This insn should be already split before reg-stack. */
3195 [(set_attr "type" "multi")
3196 (set_attr "unit" "i387,*,*")
3197 (set_attr "mode" "DF,SI,DF")])
3199 ;; %%% Kill this when call knows how to work this out.
3201 [(set (match_operand:DF 0 "push_operand" "")
3202 (match_operand:DF 1 "any_fp_register_operand" ""))]
3204 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3205 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3209 [(set (match_operand:DF 0 "push_operand" "")
3210 (match_operand:DF 1 "general_operand" ""))]
3213 "ix86_split_long_move (operands); DONE;")
3215 ;; Moving is usually shorter when only FP registers are used. This separate
3216 ;; movdf pattern avoids the use of integer registers for FP operations
3217 ;; when optimizing for size.
3219 (define_insn "*movdf_nointeger"
3220 [(set (match_operand:DF 0 "nonimmediate_operand"
3221 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3222 (match_operand:DF 1 "general_operand"
3223 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3224 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3225 && ((optimize_function_for_size_p (cfun)
3226 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3227 && (reload_in_progress || reload_completed
3228 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3229 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3230 && optimize_function_for_size_p (cfun)
3231 && !memory_operand (operands[0], DFmode)
3232 && standard_80387_constant_p (operands[1]))
3233 || GET_CODE (operands[1]) != CONST_DOUBLE
3234 || ((optimize_function_for_size_p (cfun)
3235 || !TARGET_MEMORY_MISMATCH_STALL
3236 || reload_in_progress || reload_completed)
3237 && memory_operand (operands[0], DFmode)))"
3239 switch (which_alternative)
3243 return output_387_reg_move (insn, operands);
3246 return standard_80387_constant_opcode (operands[1]);
3252 switch (get_attr_mode (insn))
3255 return "%vxorps\t%0, %d0";
3257 return "%vxorpd\t%0, %d0";
3259 return "%vpxor\t%0, %d0";
3266 switch (get_attr_mode (insn))
3269 return "%vmovaps\t{%1, %0|%0, %1}";
3271 return "%vmovapd\t{%1, %0|%0, %1}";
3273 return "%vmovdqa\t{%1, %0|%0, %1}";
3275 return "%vmovq\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]) && REG_P (operands[1]))
3280 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovsd\t{%1, %0|%0, %1}";
3285 return "movsd\t{%1, %0|%0, %1}";
3289 if (REG_P (operands[0]))
3290 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3292 return "vmovlpd\t{%1, %0|%0, %1}";
3295 return "movlpd\t{%1, %0|%0, %1}";
3299 if (REG_P (operands[0]))
3300 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3302 return "vmovlps\t{%1, %0|%0, %1}";
3305 return "movlps\t{%1, %0|%0, %1}";
3314 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3315 (set (attr "prefix")
3316 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3317 (const_string "orig")
3318 (const_string "maybe_vex")))
3319 (set (attr "prefix_data16")
3320 (if_then_else (eq_attr "mode" "V1DF")
3322 (const_string "*")))
3324 (cond [(eq_attr "alternative" "0,1,2")
3326 (eq_attr "alternative" "3,4")
3329 /* For SSE1, we have many fewer alternatives. */
3330 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3331 (cond [(eq_attr "alternative" "5,6")
3332 (const_string "V4SF")
3334 (const_string "V2SF"))
3336 /* xorps is one byte shorter. */
3337 (eq_attr "alternative" "5")
3338 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3340 (const_string "V4SF")
3341 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3345 (const_string "V2DF"))
3347 /* For architectures resolving dependencies on
3348 whole SSE registers use APD move to break dependency
3349 chains, otherwise use short move to avoid extra work.
3351 movaps encodes one byte shorter. */
3352 (eq_attr "alternative" "6")
3354 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3356 (const_string "V4SF")
3357 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (const_string "V2DF")
3361 (const_string "DF"))
3362 /* For architectures resolving dependencies on register
3363 parts we may avoid extra work to zero out upper part
3365 (eq_attr "alternative" "7")
3367 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3369 (const_string "V1DF")
3370 (const_string "DF"))
3372 (const_string "DF")))])
3374 (define_insn "*movdf_integer_rex64"
3375 [(set (match_operand:DF 0 "nonimmediate_operand"
3376 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3377 (match_operand:DF 1 "general_operand"
3378 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3379 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3380 && (reload_in_progress || reload_completed
3381 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3382 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3383 && optimize_function_for_size_p (cfun)
3384 && standard_80387_constant_p (operands[1]))
3385 || GET_CODE (operands[1]) != CONST_DOUBLE
3386 || memory_operand (operands[0], DFmode))"
3388 switch (which_alternative)
3392 return output_387_reg_move (insn, operands);
3395 return standard_80387_constant_opcode (operands[1]);
3402 switch (get_attr_mode (insn))
3405 return "%vxorps\t%0, %d0";
3407 return "%vxorpd\t%0, %d0";
3409 return "%vpxor\t%0, %d0";
3416 switch (get_attr_mode (insn))
3419 return "%vmovaps\t{%1, %0|%0, %1}";
3421 return "%vmovapd\t{%1, %0|%0, %1}";
3423 return "%vmovdqa\t{%1, %0|%0, %1}";
3425 return "%vmovq\t{%1, %0|%0, %1}";
3429 if (REG_P (operands[0]) && REG_P (operands[1]))
3430 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3432 return "vmovsd\t{%1, %0|%0, %1}";
3435 return "movsd\t{%1, %0|%0, %1}";
3437 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3439 return "%vmovlps\t{%1, %d0|%d0, %1}";
3446 return "%vmovd\t{%1, %0|%0, %1}";
3452 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3453 (set (attr "prefix")
3454 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3455 (const_string "orig")
3456 (const_string "maybe_vex")))
3457 (set (attr "prefix_data16")
3458 (if_then_else (eq_attr "mode" "V1DF")
3460 (const_string "*")))
3462 (cond [(eq_attr "alternative" "0,1,2")
3464 (eq_attr "alternative" "3,4,9,10")
3467 /* For SSE1, we have many fewer alternatives. */
3468 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3469 (cond [(eq_attr "alternative" "5,6")
3470 (const_string "V4SF")
3472 (const_string "V2SF"))
3474 /* xorps is one byte shorter. */
3475 (eq_attr "alternative" "5")
3476 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3478 (const_string "V4SF")
3479 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3483 (const_string "V2DF"))
3485 /* For architectures resolving dependencies on
3486 whole SSE registers use APD move to break dependency
3487 chains, otherwise use short move to avoid extra work.
3489 movaps encodes one byte shorter. */
3490 (eq_attr "alternative" "6")
3492 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3494 (const_string "V4SF")
3495 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3497 (const_string "V2DF")
3499 (const_string "DF"))
3500 /* For architectures resolving dependencies on register
3501 parts we may avoid extra work to zero out upper part
3503 (eq_attr "alternative" "7")
3505 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3507 (const_string "V1DF")
3508 (const_string "DF"))
3510 (const_string "DF")))])
3512 (define_insn "*movdf_integer"
3513 [(set (match_operand:DF 0 "nonimmediate_operand"
3514 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3515 (match_operand:DF 1 "general_operand"
3516 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3517 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3518 && optimize_function_for_speed_p (cfun)
3519 && TARGET_INTEGER_DFMODE_MOVES
3520 && (reload_in_progress || reload_completed
3521 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3522 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3523 && optimize_function_for_size_p (cfun)
3524 && standard_80387_constant_p (operands[1]))
3525 || GET_CODE (operands[1]) != CONST_DOUBLE
3526 || memory_operand (operands[0], DFmode))"
3528 switch (which_alternative)
3532 return output_387_reg_move (insn, operands);
3535 return standard_80387_constant_opcode (operands[1]);
3542 switch (get_attr_mode (insn))
3545 return "xorps\t%0, %0";
3547 return "xorpd\t%0, %0";
3549 return "pxor\t%0, %0";
3556 switch (get_attr_mode (insn))
3559 return "movaps\t{%1, %0|%0, %1}";
3561 return "movapd\t{%1, %0|%0, %1}";
3563 return "movdqa\t{%1, %0|%0, %1}";
3565 return "movq\t{%1, %0|%0, %1}";
3567 return "movsd\t{%1, %0|%0, %1}";
3569 return "movlpd\t{%1, %0|%0, %1}";
3571 return "movlps\t{%1, %0|%0, %1}";
3580 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3581 (set (attr "prefix_data16")
3582 (if_then_else (eq_attr "mode" "V1DF")
3584 (const_string "*")))
3586 (cond [(eq_attr "alternative" "0,1,2")
3588 (eq_attr "alternative" "3,4")
3591 /* For SSE1, we have many fewer alternatives. */
3592 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3593 (cond [(eq_attr "alternative" "5,6")
3594 (const_string "V4SF")
3596 (const_string "V2SF"))
3598 /* xorps is one byte shorter. */
3599 (eq_attr "alternative" "5")
3600 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3602 (const_string "V4SF")
3603 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3607 (const_string "V2DF"))
3609 /* For architectures resolving dependencies on
3610 whole SSE registers use APD move to break dependency
3611 chains, otherwise use short move to avoid extra work.
3613 movaps encodes one byte shorter. */
3614 (eq_attr "alternative" "6")
3616 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3618 (const_string "V4SF")
3619 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3621 (const_string "V2DF")
3623 (const_string "DF"))
3624 /* For architectures resolving dependencies on register
3625 parts we may avoid extra work to zero out upper part
3627 (eq_attr "alternative" "7")
3629 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3631 (const_string "V1DF")
3632 (const_string "DF"))
3634 (const_string "DF")))])
3637 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3638 (match_operand:DF 1 "general_operand" ""))]
3640 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3641 && ! (ANY_FP_REG_P (operands[0]) ||
3642 (GET_CODE (operands[0]) == SUBREG
3643 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3644 && ! (ANY_FP_REG_P (operands[1]) ||
3645 (GET_CODE (operands[1]) == SUBREG
3646 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3648 "ix86_split_long_move (operands); DONE;")
3650 (define_insn "*swapdf"
3651 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3652 (match_operand:DF 1 "fp_register_operand" "+f"))
3655 "reload_completed || TARGET_80387"
3657 if (STACK_TOP_P (operands[0]))
3662 [(set_attr "type" "fxch")
3663 (set_attr "mode" "DF")])
3665 (define_expand "movxf"
3666 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3667 (match_operand:XF 1 "general_operand" ""))]
3669 "ix86_expand_move (XFmode, operands); DONE;")
3671 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3672 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3673 ;; Pushing using integer instructions is longer except for constants
3674 ;; and direct memory references.
3675 ;; (assuming that any given constant is pushed only once, but this ought to be
3676 ;; handled elsewhere).
3678 (define_insn "*pushxf_nointeger"
3679 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3680 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3681 "optimize_function_for_size_p (cfun)"
3683 /* This insn should be already split before reg-stack. */
3686 [(set_attr "type" "multi")
3687 (set_attr "unit" "i387,*,*")
3688 (set_attr "mode" "XF,SI,SI")])
3690 (define_insn "*pushxf_integer"
3691 [(set (match_operand:XF 0 "push_operand" "=<,<")
3692 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3693 "optimize_function_for_speed_p (cfun)"
3695 /* This insn should be already split before reg-stack. */
3698 [(set_attr "type" "multi")
3699 (set_attr "unit" "i387,*")
3700 (set_attr "mode" "XF,SI")])
3703 [(set (match_operand 0 "push_operand" "")
3704 (match_operand 1 "general_operand" ""))]
3706 && (GET_MODE (operands[0]) == XFmode
3707 || GET_MODE (operands[0]) == DFmode)
3708 && !ANY_FP_REG_P (operands[1])"
3710 "ix86_split_long_move (operands); DONE;")
3713 [(set (match_operand:XF 0 "push_operand" "")
3714 (match_operand:XF 1 "any_fp_register_operand" ""))]
3716 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3717 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3718 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3720 ;; Do not use integer registers when optimizing for size
3721 (define_insn "*movxf_nointeger"
3722 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3723 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3724 "optimize_function_for_size_p (cfun)
3725 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3726 && (reload_in_progress || reload_completed
3727 || standard_80387_constant_p (operands[1])
3728 || GET_CODE (operands[1]) != CONST_DOUBLE
3729 || memory_operand (operands[0], XFmode))"
3731 switch (which_alternative)
3735 return output_387_reg_move (insn, operands);
3738 return standard_80387_constant_opcode (operands[1]);
3746 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3747 (set_attr "mode" "XF,XF,XF,SI,SI")])
3749 (define_insn "*movxf_integer"
3750 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3751 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3752 "optimize_function_for_speed_p (cfun)
3753 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3754 && (reload_in_progress || reload_completed
3755 || GET_CODE (operands[1]) != CONST_DOUBLE
3756 || memory_operand (operands[0], XFmode))"
3758 switch (which_alternative)
3762 return output_387_reg_move (insn, operands);
3765 return standard_80387_constant_opcode (operands[1]);
3774 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3775 (set_attr "mode" "XF,XF,XF,SI,SI")])
3777 (define_expand "movtf"
3778 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3779 (match_operand:TF 1 "nonimmediate_operand" ""))]
3782 ix86_expand_move (TFmode, operands);
3786 (define_insn "*movtf_internal"
3787 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3788 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3792 switch (which_alternative)
3796 if (get_attr_mode (insn) == MODE_V4SF)
3797 return "%vmovaps\t{%1, %0|%0, %1}";
3799 return "%vmovdqa\t{%1, %0|%0, %1}";
3801 if (get_attr_mode (insn) == MODE_V4SF)
3802 return "%vxorps\t%0, %d0";
3804 return "%vpxor\t%0, %d0";
3812 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3813 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3815 (cond [(eq_attr "alternative" "0,2")
3817 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3819 (const_string "V4SF")
3820 (const_string "TI"))
3821 (eq_attr "alternative" "1")
3823 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3825 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3827 (const_string "V4SF")
3828 (const_string "TI"))]
3829 (const_string "DI")))])
3831 (define_insn "*pushtf_sse"
3832 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3833 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3836 /* This insn should be already split before reg-stack. */
3839 [(set_attr "type" "multi")
3840 (set_attr "unit" "sse,*,*")
3841 (set_attr "mode" "TF,SI,SI")])
3844 [(set (match_operand:TF 0 "push_operand" "")
3845 (match_operand:TF 1 "general_operand" ""))]
3846 "TARGET_SSE2 && reload_completed
3847 && !SSE_REG_P (operands[1])"
3849 "ix86_split_long_move (operands); DONE;")
3852 [(set (match_operand:TF 0 "push_operand" "")
3853 (match_operand:TF 1 "any_fp_register_operand" ""))]
3855 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3856 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3860 [(set (match_operand 0 "nonimmediate_operand" "")
3861 (match_operand 1 "general_operand" ""))]
3863 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3864 && GET_MODE (operands[0]) == XFmode
3865 && ! (ANY_FP_REG_P (operands[0]) ||
3866 (GET_CODE (operands[0]) == SUBREG
3867 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3868 && ! (ANY_FP_REG_P (operands[1]) ||
3869 (GET_CODE (operands[1]) == SUBREG
3870 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3872 "ix86_split_long_move (operands); DONE;")
3875 [(set (match_operand 0 "register_operand" "")
3876 (match_operand 1 "memory_operand" ""))]
3878 && MEM_P (operands[1])
3879 && (GET_MODE (operands[0]) == TFmode
3880 || GET_MODE (operands[0]) == XFmode
3881 || GET_MODE (operands[0]) == SFmode
3882 || GET_MODE (operands[0]) == DFmode)
3883 && (operands[2] = find_constant_src (insn))"
3884 [(set (match_dup 0) (match_dup 2))]
3886 rtx c = operands[2];
3887 rtx r = operands[0];
3889 if (GET_CODE (r) == SUBREG)
3894 if (!standard_sse_constant_p (c))
3897 else if (FP_REG_P (r))
3899 if (!standard_80387_constant_p (c))
3902 else if (MMX_REG_P (r))
3907 [(set (match_operand 0 "register_operand" "")
3908 (float_extend (match_operand 1 "memory_operand" "")))]
3910 && MEM_P (operands[1])
3911 && (GET_MODE (operands[0]) == TFmode
3912 || GET_MODE (operands[0]) == XFmode
3913 || GET_MODE (operands[0]) == SFmode
3914 || GET_MODE (operands[0]) == DFmode)
3915 && (operands[2] = find_constant_src (insn))"
3916 [(set (match_dup 0) (match_dup 2))]
3918 rtx c = operands[2];
3919 rtx r = operands[0];
3921 if (GET_CODE (r) == SUBREG)
3926 if (!standard_sse_constant_p (c))
3929 else if (FP_REG_P (r))
3931 if (!standard_80387_constant_p (c))
3934 else if (MMX_REG_P (r))
3938 (define_insn "swapxf"
3939 [(set (match_operand:XF 0 "register_operand" "+f")
3940 (match_operand:XF 1 "register_operand" "+f"))
3945 if (STACK_TOP_P (operands[0]))
3950 [(set_attr "type" "fxch")
3951 (set_attr "mode" "XF")])
3953 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3955 [(set (match_operand:X87MODEF 0 "register_operand" "")
3956 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3957 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3958 && (standard_80387_constant_p (operands[1]) == 8
3959 || standard_80387_constant_p (operands[1]) == 9)"
3960 [(set (match_dup 0)(match_dup 1))
3962 (neg:X87MODEF (match_dup 0)))]
3966 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3967 if (real_isnegzero (&r))
3968 operands[1] = CONST0_RTX (<MODE>mode);
3970 operands[1] = CONST1_RTX (<MODE>mode);
3974 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3975 (match_operand:TF 1 "general_operand" ""))]
3977 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3979 "ix86_split_long_move (operands); DONE;")
3981 ;; Zero extension instructions
3983 (define_expand "zero_extendhisi2"
3984 [(set (match_operand:SI 0 "register_operand" "")
3985 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3988 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3990 operands[1] = force_reg (HImode, operands[1]);
3991 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3996 (define_insn "zero_extendhisi2_and"
3997 [(set (match_operand:SI 0 "register_operand" "=r")
3998 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3999 (clobber (reg:CC FLAGS_REG))]
4000 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4002 [(set_attr "type" "alu1")
4003 (set_attr "mode" "SI")])
4006 [(set (match_operand:SI 0 "register_operand" "")
4007 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
4008 (clobber (reg:CC FLAGS_REG))]
4009 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
4010 && optimize_function_for_speed_p (cfun)"
4011 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
4012 (clobber (reg:CC FLAGS_REG))])]
4015 (define_insn "*zero_extendhisi2_movzwl"
4016 [(set (match_operand:SI 0 "register_operand" "=r")
4017 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4018 "!TARGET_ZERO_EXTEND_WITH_AND
4019 || optimize_function_for_size_p (cfun)"
4020 "movz{wl|x}\t{%1, %0|%0, %1}"
4021 [(set_attr "type" "imovx")
4022 (set_attr "mode" "SI")])
4024 (define_expand "zero_extendqihi2"
4026 [(set (match_operand:HI 0 "register_operand" "")
4027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4028 (clobber (reg:CC FLAGS_REG))])]
4032 (define_insn "*zero_extendqihi2_and"
4033 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4034 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4035 (clobber (reg:CC FLAGS_REG))]
4036 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4038 [(set_attr "type" "alu1")
4039 (set_attr "mode" "HI")])
4041 (define_insn "*zero_extendqihi2_movzbw_and"
4042 [(set (match_operand:HI 0 "register_operand" "=r,r")
4043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4044 (clobber (reg:CC FLAGS_REG))]
4045 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4047 [(set_attr "type" "imovx,alu1")
4048 (set_attr "mode" "HI")])
4050 ; zero extend to SImode here to avoid partial register stalls
4051 (define_insn "*zero_extendqihi2_movzbl"
4052 [(set (match_operand:HI 0 "register_operand" "=r")
4053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4054 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4055 && reload_completed"
4056 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4057 [(set_attr "type" "imovx")
4058 (set_attr "mode" "SI")])
4060 ;; For the movzbw case strip only the clobber
4062 [(set (match_operand:HI 0 "register_operand" "")
4063 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4064 (clobber (reg:CC FLAGS_REG))]
4066 && (!TARGET_ZERO_EXTEND_WITH_AND
4067 || optimize_function_for_size_p (cfun))
4068 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4069 [(set (match_operand:HI 0 "register_operand" "")
4070 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4072 ;; When source and destination does not overlap, clear destination
4073 ;; first and then do the movb
4075 [(set (match_operand:HI 0 "register_operand" "")
4076 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4077 (clobber (reg:CC FLAGS_REG))]
4079 && ANY_QI_REG_P (operands[0])
4080 && (TARGET_ZERO_EXTEND_WITH_AND
4081 && optimize_function_for_speed_p (cfun))
4082 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4083 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4085 operands[2] = gen_lowpart (QImode, operands[0]);
4086 ix86_expand_clear (operands[0]);
4089 ;; Rest is handled by single and.
4091 [(set (match_operand:HI 0 "register_operand" "")
4092 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4093 (clobber (reg:CC FLAGS_REG))]
4095 && true_regnum (operands[0]) == true_regnum (operands[1])"
4096 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4097 (clobber (reg:CC FLAGS_REG))])]
4100 (define_expand "zero_extendqisi2"
4102 [(set (match_operand:SI 0 "register_operand" "")
4103 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4104 (clobber (reg:CC FLAGS_REG))])]
4108 (define_insn "*zero_extendqisi2_and"
4109 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4111 (clobber (reg:CC FLAGS_REG))]
4112 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4114 [(set_attr "type" "alu1")
4115 (set_attr "mode" "SI")])
4117 (define_insn "*zero_extendqisi2_movzbl_and"
4118 [(set (match_operand:SI 0 "register_operand" "=r,r")
4119 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4120 (clobber (reg:CC FLAGS_REG))]
4121 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4123 [(set_attr "type" "imovx,alu1")
4124 (set_attr "mode" "SI")])
4126 (define_insn "*zero_extendqisi2_movzbl"
4127 [(set (match_operand:SI 0 "register_operand" "=r")
4128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4129 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4130 && reload_completed"
4131 "movz{bl|x}\t{%1, %0|%0, %1}"
4132 [(set_attr "type" "imovx")
4133 (set_attr "mode" "SI")])
4135 ;; For the movzbl case strip only the clobber
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 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4142 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4144 (zero_extend:SI (match_dup 1)))])
4146 ;; When source and destination does not overlap, clear destination
4147 ;; first and then do the movb
4149 [(set (match_operand:SI 0 "register_operand" "")
4150 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4151 (clobber (reg:CC FLAGS_REG))]
4153 && ANY_QI_REG_P (operands[0])
4154 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4155 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4156 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4157 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4159 operands[2] = gen_lowpart (QImode, operands[0]);
4160 ix86_expand_clear (operands[0]);
4163 ;; Rest is handled by single and.
4165 [(set (match_operand:SI 0 "register_operand" "")
4166 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4167 (clobber (reg:CC FLAGS_REG))]
4169 && true_regnum (operands[0]) == true_regnum (operands[1])"
4170 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4171 (clobber (reg:CC FLAGS_REG))])]
4174 ;; %%% Kill me once multi-word ops are sane.
4175 (define_expand "zero_extendsidi2"
4176 [(set (match_operand:DI 0 "register_operand" "")
4177 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4182 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4187 (define_insn "zero_extendsidi2_32"
4188 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4190 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4191 (clobber (reg:CC FLAGS_REG))]
4197 movd\t{%1, %0|%0, %1}
4198 movd\t{%1, %0|%0, %1}
4199 %vmovd\t{%1, %0|%0, %1}
4200 %vmovd\t{%1, %0|%0, %1}"
4201 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4202 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4203 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4205 (define_insn "zero_extendsidi2_rex64"
4206 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4208 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4211 mov\t{%k1, %k0|%k0, %k1}
4213 movd\t{%1, %0|%0, %1}
4214 movd\t{%1, %0|%0, %1}
4215 %vmovd\t{%1, %0|%0, %1}
4216 %vmovd\t{%1, %0|%0, %1}"
4217 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4218 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4219 (set_attr "prefix_0f" "0,*,*,*,*,*")
4220 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4223 [(set (match_operand:DI 0 "memory_operand" "")
4224 (zero_extend:DI (match_dup 0)))]
4226 [(set (match_dup 4) (const_int 0))]
4227 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4230 [(set (match_operand:DI 0 "register_operand" "")
4231 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4232 (clobber (reg:CC FLAGS_REG))]
4233 "!TARGET_64BIT && reload_completed
4234 && true_regnum (operands[0]) == true_regnum (operands[1])"
4235 [(set (match_dup 4) (const_int 0))]
4236 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4239 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4240 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4241 (clobber (reg:CC FLAGS_REG))]
4242 "!TARGET_64BIT && reload_completed
4243 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4244 [(set (match_dup 3) (match_dup 1))
4245 (set (match_dup 4) (const_int 0))]
4246 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4248 (define_insn "zero_extendhidi2"
4249 [(set (match_operand:DI 0 "register_operand" "=r")
4250 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4252 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4253 [(set_attr "type" "imovx")
4254 (set_attr "mode" "SI")])
4256 (define_insn "zero_extendqidi2"
4257 [(set (match_operand:DI 0 "register_operand" "=r")
4258 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4260 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4261 [(set_attr "type" "imovx")
4262 (set_attr "mode" "SI")])
4264 ;; Sign extension instructions
4266 (define_expand "extendsidi2"
4267 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4268 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4269 (clobber (reg:CC FLAGS_REG))
4270 (clobber (match_scratch:SI 2 ""))])]
4275 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4280 (define_insn "*extendsidi2_1"
4281 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4282 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4283 (clobber (reg:CC FLAGS_REG))
4284 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4288 (define_insn "extendsidi2_rex64"
4289 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4290 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4294 movs{lq|x}\t{%1, %0|%0, %1}"
4295 [(set_attr "type" "imovx")
4296 (set_attr "mode" "DI")
4297 (set_attr "prefix_0f" "0")
4298 (set_attr "modrm" "0,1")])
4300 (define_insn "extendhidi2"
4301 [(set (match_operand:DI 0 "register_operand" "=r")
4302 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4304 "movs{wq|x}\t{%1, %0|%0, %1}"
4305 [(set_attr "type" "imovx")
4306 (set_attr "mode" "DI")])
4308 (define_insn "extendqidi2"
4309 [(set (match_operand:DI 0 "register_operand" "=r")
4310 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4312 "movs{bq|x}\t{%1, %0|%0, %1}"
4313 [(set_attr "type" "imovx")
4314 (set_attr "mode" "DI")])
4316 ;; Extend to memory case when source register does die.
4318 [(set (match_operand:DI 0 "memory_operand" "")
4319 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4320 (clobber (reg:CC FLAGS_REG))
4321 (clobber (match_operand:SI 2 "register_operand" ""))]
4323 && dead_or_set_p (insn, operands[1])
4324 && !reg_mentioned_p (operands[1], operands[0]))"
4325 [(set (match_dup 3) (match_dup 1))
4326 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4327 (clobber (reg:CC FLAGS_REG))])
4328 (set (match_dup 4) (match_dup 1))]
4329 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4331 ;; Extend to memory case when source register does not die.
4333 [(set (match_operand:DI 0 "memory_operand" "")
4334 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4335 (clobber (reg:CC FLAGS_REG))
4336 (clobber (match_operand:SI 2 "register_operand" ""))]
4340 split_di (&operands[0], 1, &operands[3], &operands[4]);
4342 emit_move_insn (operands[3], operands[1]);
4344 /* Generate a cltd if possible and doing so it profitable. */
4345 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4346 && true_regnum (operands[1]) == AX_REG
4347 && true_regnum (operands[2]) == DX_REG)
4349 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4353 emit_move_insn (operands[2], operands[1]);
4354 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4356 emit_move_insn (operands[4], operands[2]);
4360 ;; Extend to register case. Optimize case where source and destination
4361 ;; registers match and cases where we can use cltd.
4363 [(set (match_operand:DI 0 "register_operand" "")
4364 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4365 (clobber (reg:CC FLAGS_REG))
4366 (clobber (match_scratch:SI 2 ""))]
4370 split_di (&operands[0], 1, &operands[3], &operands[4]);
4372 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4373 emit_move_insn (operands[3], operands[1]);
4375 /* Generate a cltd if possible and doing so it profitable. */
4376 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4377 && true_regnum (operands[3]) == AX_REG)
4379 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4383 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4384 emit_move_insn (operands[4], operands[1]);
4386 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4390 (define_insn "extendhisi2"
4391 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4395 switch (get_attr_prefix_0f (insn))
4398 return "{cwtl|cwde}";
4400 return "movs{wl|x}\t{%1, %0|%0, %1}";
4403 [(set_attr "type" "imovx")
4404 (set_attr "mode" "SI")
4405 (set (attr "prefix_0f")
4406 ;; movsx is short decodable while cwtl is vector decoded.
4407 (if_then_else (and (eq_attr "cpu" "!k6")
4408 (eq_attr "alternative" "0"))
4410 (const_string "1")))
4412 (if_then_else (eq_attr "prefix_0f" "0")
4414 (const_string "1")))])
4416 (define_insn "*extendhisi2_zext"
4417 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4419 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4422 switch (get_attr_prefix_0f (insn))
4425 return "{cwtl|cwde}";
4427 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4430 [(set_attr "type" "imovx")
4431 (set_attr "mode" "SI")
4432 (set (attr "prefix_0f")
4433 ;; movsx is short decodable while cwtl is vector decoded.
4434 (if_then_else (and (eq_attr "cpu" "!k6")
4435 (eq_attr "alternative" "0"))
4437 (const_string "1")))
4439 (if_then_else (eq_attr "prefix_0f" "0")
4441 (const_string "1")))])
4443 (define_insn "extendqihi2"
4444 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4445 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4448 switch (get_attr_prefix_0f (insn))
4451 return "{cbtw|cbw}";
4453 return "movs{bw|x}\t{%1, %0|%0, %1}";
4456 [(set_attr "type" "imovx")
4457 (set_attr "mode" "HI")
4458 (set (attr "prefix_0f")
4459 ;; movsx is short decodable while cwtl is vector decoded.
4460 (if_then_else (and (eq_attr "cpu" "!k6")
4461 (eq_attr "alternative" "0"))
4463 (const_string "1")))
4465 (if_then_else (eq_attr "prefix_0f" "0")
4467 (const_string "1")))])
4469 (define_insn "extendqisi2"
4470 [(set (match_operand:SI 0 "register_operand" "=r")
4471 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4473 "movs{bl|x}\t{%1, %0|%0, %1}"
4474 [(set_attr "type" "imovx")
4475 (set_attr "mode" "SI")])
4477 (define_insn "*extendqisi2_zext"
4478 [(set (match_operand:DI 0 "register_operand" "=r")
4480 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4482 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4483 [(set_attr "type" "imovx")
4484 (set_attr "mode" "SI")])
4486 ;; Conversions between float and double.
4488 ;; These are all no-ops in the model used for the 80387. So just
4491 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4492 (define_insn "*dummy_extendsfdf2"
4493 [(set (match_operand:DF 0 "push_operand" "=<")
4494 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4499 [(set (match_operand:DF 0 "push_operand" "")
4500 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4502 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4503 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4505 (define_insn "*dummy_extendsfxf2"
4506 [(set (match_operand:XF 0 "push_operand" "=<")
4507 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4512 [(set (match_operand:XF 0 "push_operand" "")
4513 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4515 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4516 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4517 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4520 [(set (match_operand:XF 0 "push_operand" "")
4521 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4523 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4524 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4525 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4527 (define_expand "extendsfdf2"
4528 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4529 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4530 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4532 /* ??? Needed for compress_float_constant since all fp constants
4533 are LEGITIMATE_CONSTANT_P. */
4534 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4536 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4537 && standard_80387_constant_p (operands[1]) > 0)
4539 operands[1] = simplify_const_unary_operation
4540 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4541 emit_move_insn_1 (operands[0], operands[1]);
4544 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4548 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4550 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4552 We do the conversion post reload to avoid producing of 128bit spills
4553 that might lead to ICE on 32bit target. The sequence unlikely combine
4556 [(set (match_operand:DF 0 "register_operand" "")
4558 (match_operand:SF 1 "nonimmediate_operand" "")))]
4559 "TARGET_USE_VECTOR_FP_CONVERTS
4560 && optimize_insn_for_speed_p ()
4561 && reload_completed && SSE_REG_P (operands[0])"
4566 (parallel [(const_int 0) (const_int 1)]))))]
4568 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4569 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4570 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4571 Try to avoid move when unpacking can be done in source. */
4572 if (REG_P (operands[1]))
4574 /* If it is unsafe to overwrite upper half of source, we need
4575 to move to destination and unpack there. */
4576 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4577 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4578 && true_regnum (operands[0]) != true_regnum (operands[1]))
4580 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4581 emit_move_insn (tmp, operands[1]);
4584 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4585 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4588 emit_insn (gen_vec_setv4sf_0 (operands[3],
4589 CONST0_RTX (V4SFmode), operands[1]));
4592 (define_insn "*extendsfdf2_mixed"
4593 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4595 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4596 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598 switch (which_alternative)
4602 return output_387_reg_move (insn, operands);
4605 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4611 [(set_attr "type" "fmov,fmov,ssecvt")
4612 (set_attr "prefix" "orig,orig,maybe_vex")
4613 (set_attr "mode" "SF,XF,DF")])
4615 (define_insn "*extendsfdf2_sse"
4616 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4617 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4618 "TARGET_SSE2 && TARGET_SSE_MATH"
4619 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4620 [(set_attr "type" "ssecvt")
4621 (set_attr "prefix" "maybe_vex")
4622 (set_attr "mode" "DF")])
4624 (define_insn "*extendsfdf2_i387"
4625 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4626 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4628 "* return output_387_reg_move (insn, operands);"
4629 [(set_attr "type" "fmov")
4630 (set_attr "mode" "SF,XF")])
4632 (define_expand "extend<mode>xf2"
4633 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4634 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4637 /* ??? Needed for compress_float_constant since all fp constants
4638 are LEGITIMATE_CONSTANT_P. */
4639 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4641 if (standard_80387_constant_p (operands[1]) > 0)
4643 operands[1] = simplify_const_unary_operation
4644 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4645 emit_move_insn_1 (operands[0], operands[1]);
4648 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4652 (define_insn "*extend<mode>xf2_i387"
4653 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4655 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4657 "* return output_387_reg_move (insn, operands);"
4658 [(set_attr "type" "fmov")
4659 (set_attr "mode" "<MODE>,XF")])
4661 ;; %%% This seems bad bad news.
4662 ;; This cannot output into an f-reg because there is no way to be sure
4663 ;; of truncating in that case. Otherwise this is just like a simple move
4664 ;; insn. So we pretend we can output to a reg in order to get better
4665 ;; register preferencing, but we really use a stack slot.
4667 ;; Conversion from DFmode to SFmode.
4669 (define_expand "truncdfsf2"
4670 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4672 (match_operand:DF 1 "nonimmediate_operand" "")))]
4673 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4675 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4677 else if (flag_unsafe_math_optimizations)
4681 enum ix86_stack_slot slot = (virtuals_instantiated
4684 rtx temp = assign_386_stack_local (SFmode, slot);
4685 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4690 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4692 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4694 We do the conversion post reload to avoid producing of 128bit spills
4695 that might lead to ICE on 32bit target. The sequence unlikely combine
4698 [(set (match_operand:SF 0 "register_operand" "")
4700 (match_operand:DF 1 "nonimmediate_operand" "")))]
4701 "TARGET_USE_VECTOR_FP_CONVERTS
4702 && optimize_insn_for_speed_p ()
4703 && reload_completed && SSE_REG_P (operands[0])"
4706 (float_truncate:V2SF
4710 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4711 operands[3] = CONST0_RTX (V2SFmode);
4712 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4713 /* Use movsd for loading from memory, unpcklpd for registers.
4714 Try to avoid move when unpacking can be done in source, or SSE3
4715 movddup is available. */
4716 if (REG_P (operands[1]))
4719 && true_regnum (operands[0]) != true_regnum (operands[1])
4720 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4721 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4723 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4724 emit_move_insn (tmp, operands[1]);
4727 else if (!TARGET_SSE3)
4728 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4729 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4732 emit_insn (gen_sse2_loadlpd (operands[4],
4733 CONST0_RTX (V2DFmode), operands[1]));
4736 (define_expand "truncdfsf2_with_temp"
4737 [(parallel [(set (match_operand:SF 0 "" "")
4738 (float_truncate:SF (match_operand:DF 1 "" "")))
4739 (clobber (match_operand:SF 2 "" ""))])]
4742 (define_insn "*truncdfsf_fast_mixed"
4743 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4745 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4746 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4748 switch (which_alternative)
4751 return output_387_reg_move (insn, operands);
4753 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4758 [(set_attr "type" "fmov,ssecvt")
4759 (set_attr "prefix" "orig,maybe_vex")
4760 (set_attr "mode" "SF")])
4762 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4763 ;; because nothing we do here is unsafe.
4764 (define_insn "*truncdfsf_fast_sse"
4765 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4767 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4768 "TARGET_SSE2 && TARGET_SSE_MATH"
4769 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4770 [(set_attr "type" "ssecvt")
4771 (set_attr "prefix" "maybe_vex")
4772 (set_attr "mode" "SF")])
4774 (define_insn "*truncdfsf_fast_i387"
4775 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4777 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4778 "TARGET_80387 && flag_unsafe_math_optimizations"
4779 "* return output_387_reg_move (insn, operands);"
4780 [(set_attr "type" "fmov")
4781 (set_attr "mode" "SF")])
4783 (define_insn "*truncdfsf_mixed"
4784 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4786 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4787 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4788 "TARGET_MIX_SSE_I387"
4790 switch (which_alternative)
4793 return output_387_reg_move (insn, operands);
4795 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4801 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4802 (set_attr "unit" "*,*,i387,i387,i387")
4803 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4804 (set_attr "mode" "SF")])
4806 (define_insn "*truncdfsf_i387"
4807 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4809 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4810 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4813 switch (which_alternative)
4816 return output_387_reg_move (insn, operands);
4822 [(set_attr "type" "fmov,multi,multi,multi")
4823 (set_attr "unit" "*,i387,i387,i387")
4824 (set_attr "mode" "SF")])
4826 (define_insn "*truncdfsf2_i387_1"
4827 [(set (match_operand:SF 0 "memory_operand" "=m")
4829 (match_operand:DF 1 "register_operand" "f")))]
4831 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4832 && !TARGET_MIX_SSE_I387"
4833 "* return output_387_reg_move (insn, operands);"
4834 [(set_attr "type" "fmov")
4835 (set_attr "mode" "SF")])
4838 [(set (match_operand:SF 0 "register_operand" "")
4840 (match_operand:DF 1 "fp_register_operand" "")))
4841 (clobber (match_operand 2 "" ""))]
4843 [(set (match_dup 2) (match_dup 1))
4844 (set (match_dup 0) (match_dup 2))]
4846 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4849 ;; Conversion from XFmode to {SF,DF}mode
4851 (define_expand "truncxf<mode>2"
4852 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4853 (float_truncate:MODEF
4854 (match_operand:XF 1 "register_operand" "")))
4855 (clobber (match_dup 2))])]
4858 if (flag_unsafe_math_optimizations)
4860 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4861 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4862 if (reg != operands[0])
4863 emit_move_insn (operands[0], reg);
4868 enum ix86_stack_slot slot = (virtuals_instantiated
4871 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4875 (define_insn "*truncxfsf2_mixed"
4876 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4878 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4879 (clobber (match_operand:SF 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" "SF")])
4889 (define_insn "*truncxfdf2_mixed"
4890 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4892 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4893 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4896 gcc_assert (!which_alternative);
4897 return output_387_reg_move (insn, operands);
4899 [(set_attr "type" "fmov,multi,multi,multi")
4900 (set_attr "unit" "*,i387,i387,i387")
4901 (set_attr "mode" "DF")])
4903 (define_insn "truncxf<mode>2_i387_noop"
4904 [(set (match_operand:MODEF 0 "register_operand" "=f")
4905 (float_truncate:MODEF
4906 (match_operand:XF 1 "register_operand" "f")))]
4907 "TARGET_80387 && flag_unsafe_math_optimizations"
4908 "* return output_387_reg_move (insn, operands);"
4909 [(set_attr "type" "fmov")
4910 (set_attr "mode" "<MODE>")])
4912 (define_insn "*truncxf<mode>2_i387"
4913 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4914 (float_truncate:MODEF
4915 (match_operand:XF 1 "register_operand" "f")))]
4917 "* return output_387_reg_move (insn, operands);"
4918 [(set_attr "type" "fmov")
4919 (set_attr "mode" "<MODE>")])
4922 [(set (match_operand:MODEF 0 "register_operand" "")
4923 (float_truncate:MODEF
4924 (match_operand:XF 1 "register_operand" "")))
4925 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4926 "TARGET_80387 && reload_completed"
4927 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4928 (set (match_dup 0) (match_dup 2))]
4932 [(set (match_operand:MODEF 0 "memory_operand" "")
4933 (float_truncate:MODEF
4934 (match_operand:XF 1 "register_operand" "")))
4935 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4937 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4940 ;; Signed conversion to DImode.
4942 (define_expand "fix_truncxfdi2"
4943 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4944 (fix:DI (match_operand:XF 1 "register_operand" "")))
4945 (clobber (reg:CC FLAGS_REG))])]
4950 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4955 (define_expand "fix_trunc<mode>di2"
4956 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4957 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4958 (clobber (reg:CC FLAGS_REG))])]
4959 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4962 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4964 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4967 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4969 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4970 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4971 if (out != operands[0])
4972 emit_move_insn (operands[0], out);
4977 ;; Signed conversion to SImode.
4979 (define_expand "fix_truncxfsi2"
4980 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4981 (fix:SI (match_operand:XF 1 "register_operand" "")))
4982 (clobber (reg:CC FLAGS_REG))])]
4987 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4992 (define_expand "fix_trunc<mode>si2"
4993 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4994 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4995 (clobber (reg:CC FLAGS_REG))])]
4996 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4999 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5001 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
5004 if (SSE_FLOAT_MODE_P (<MODE>mode))
5006 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5007 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5008 if (out != operands[0])
5009 emit_move_insn (operands[0], out);
5014 ;; Signed conversion to HImode.
5016 (define_expand "fix_trunc<mode>hi2"
5017 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5018 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
5019 (clobber (reg:CC FLAGS_REG))])]
5021 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5025 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5030 ;; Unsigned conversion to SImode.
5032 (define_expand "fixuns_trunc<mode>si2"
5034 [(set (match_operand:SI 0 "register_operand" "")
5036 (match_operand:MODEF 1 "nonimmediate_operand" "")))
5038 (clobber (match_scratch:<ssevecmode> 3 ""))
5039 (clobber (match_scratch:<ssevecmode> 4 ""))])]
5040 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5042 enum machine_mode mode = <MODE>mode;
5043 enum machine_mode vecmode = <ssevecmode>mode;
5044 REAL_VALUE_TYPE TWO31r;
5047 if (optimize_insn_for_size_p ())
5050 real_ldexp (&TWO31r, &dconst1, 31);
5051 two31 = const_double_from_real_value (TWO31r, mode);
5052 two31 = ix86_build_const_vector (mode, true, two31);
5053 operands[2] = force_reg (vecmode, two31);
5056 (define_insn_and_split "*fixuns_trunc<mode>_1"
5057 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5059 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5060 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5061 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5062 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5063 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5064 && optimize_function_for_speed_p (cfun)"
5066 "&& reload_completed"
5069 ix86_split_convert_uns_si_sse (operands);
5073 ;; Unsigned conversion to HImode.
5074 ;; Without these patterns, we'll try the unsigned SI conversion which
5075 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5077 (define_expand "fixuns_trunc<mode>hi2"
5079 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5080 (set (match_operand:HI 0 "nonimmediate_operand" "")
5081 (subreg:HI (match_dup 2) 0))]
5082 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5083 "operands[2] = gen_reg_rtx (SImode);")
5085 ;; When SSE is available, it is always faster to use it!
5086 (define_insn "fix_trunc<mode>di_sse"
5087 [(set (match_operand:DI 0 "register_operand" "=r,r")
5088 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5089 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5090 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5091 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "prefix" "maybe_vex")
5094 (set_attr "prefix_rex" "1")
5095 (set_attr "mode" "<MODE>")
5096 (set_attr "athlon_decode" "double,vector")
5097 (set_attr "amdfam10_decode" "double,double")])
5099 (define_insn "fix_trunc<mode>si_sse"
5100 [(set (match_operand:SI 0 "register_operand" "=r,r")
5101 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5102 "SSE_FLOAT_MODE_P (<MODE>mode)
5103 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5104 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODE>")
5108 (set_attr "athlon_decode" "double,vector")
5109 (set_attr "amdfam10_decode" "double,double")])
5111 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5113 [(set (match_operand:MODEF 0 "register_operand" "")
5114 (match_operand:MODEF 1 "memory_operand" ""))
5115 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5116 (fix:SSEMODEI24 (match_dup 0)))]
5117 "TARGET_SHORTEN_X87_SSE
5118 && peep2_reg_dead_p (2, operands[0])"
5119 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5122 ;; Avoid vector decoded forms of the instruction.
5124 [(match_scratch:DF 2 "Y2")
5125 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5126 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5127 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5128 [(set (match_dup 2) (match_dup 1))
5129 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5133 [(match_scratch:SF 2 "x")
5134 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5135 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5136 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5137 [(set (match_dup 2) (match_dup 1))
5138 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5141 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5142 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5143 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5144 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5146 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5147 && (TARGET_64BIT || <MODE>mode != DImode))
5149 && can_create_pseudo_p ()"
5154 if (memory_operand (operands[0], VOIDmode))
5155 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5158 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5159 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5165 [(set_attr "type" "fisttp")
5166 (set_attr "mode" "<MODE>")])
5168 (define_insn "fix_trunc<mode>_i387_fisttp"
5169 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5170 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5171 (clobber (match_scratch:XF 2 "=&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)"
5177 "* return output_fix_trunc (insn, operands, 1);"
5178 [(set_attr "type" "fisttp")
5179 (set_attr "mode" "<MODE>")])
5181 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5182 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5183 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5184 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5185 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5186 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5188 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5189 && (TARGET_64BIT || <MODE>mode != DImode))
5190 && TARGET_SSE_MATH)"
5192 [(set_attr "type" "fisttp")
5193 (set_attr "mode" "<MODE>")])
5196 [(set (match_operand:X87MODEI 0 "register_operand" "")
5197 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5198 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5199 (clobber (match_scratch 3 ""))]
5201 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5202 (clobber (match_dup 3))])
5203 (set (match_dup 0) (match_dup 2))]
5207 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5208 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5209 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5210 (clobber (match_scratch 3 ""))]
5212 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5213 (clobber (match_dup 3))])]
5216 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5217 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5218 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5219 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5220 ;; function in i386.c.
5221 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5222 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5223 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5224 (clobber (reg:CC FLAGS_REG))]
5225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5227 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5228 && (TARGET_64BIT || <MODE>mode != DImode))
5229 && can_create_pseudo_p ()"
5234 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5236 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5237 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5238 if (memory_operand (operands[0], VOIDmode))
5239 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5240 operands[2], operands[3]));
5243 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5244 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5245 operands[2], operands[3],
5250 [(set_attr "type" "fistp")
5251 (set_attr "i387_cw" "trunc")
5252 (set_attr "mode" "<MODE>")])
5254 (define_insn "fix_truncdi_i387"
5255 [(set (match_operand:DI 0 "memory_operand" "=m")
5256 (fix:DI (match_operand 1 "register_operand" "f")))
5257 (use (match_operand:HI 2 "memory_operand" "m"))
5258 (use (match_operand:HI 3 "memory_operand" "m"))
5259 (clobber (match_scratch:XF 4 "=&1f"))]
5260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5262 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5263 "* return output_fix_trunc (insn, operands, 0);"
5264 [(set_attr "type" "fistp")
5265 (set_attr "i387_cw" "trunc")
5266 (set_attr "mode" "DI")])
5268 (define_insn "fix_truncdi_i387_with_temp"
5269 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5270 (fix:DI (match_operand 1 "register_operand" "f,f")))
5271 (use (match_operand:HI 2 "memory_operand" "m,m"))
5272 (use (match_operand:HI 3 "memory_operand" "m,m"))
5273 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5274 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5275 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5277 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5279 [(set_attr "type" "fistp")
5280 (set_attr "i387_cw" "trunc")
5281 (set_attr "mode" "DI")])
5284 [(set (match_operand:DI 0 "register_operand" "")
5285 (fix:DI (match_operand 1 "register_operand" "")))
5286 (use (match_operand:HI 2 "memory_operand" ""))
5287 (use (match_operand:HI 3 "memory_operand" ""))
5288 (clobber (match_operand:DI 4 "memory_operand" ""))
5289 (clobber (match_scratch 5 ""))]
5291 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5294 (clobber (match_dup 5))])
5295 (set (match_dup 0) (match_dup 4))]
5299 [(set (match_operand:DI 0 "memory_operand" "")
5300 (fix:DI (match_operand 1 "register_operand" "")))
5301 (use (match_operand:HI 2 "memory_operand" ""))
5302 (use (match_operand:HI 3 "memory_operand" ""))
5303 (clobber (match_operand:DI 4 "memory_operand" ""))
5304 (clobber (match_scratch 5 ""))]
5306 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5309 (clobber (match_dup 5))])]
5312 (define_insn "fix_trunc<mode>_i387"
5313 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5314 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5315 (use (match_operand:HI 2 "memory_operand" "m"))
5316 (use (match_operand:HI 3 "memory_operand" "m"))]
5317 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5319 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5320 "* return output_fix_trunc (insn, operands, 0);"
5321 [(set_attr "type" "fistp")
5322 (set_attr "i387_cw" "trunc")
5323 (set_attr "mode" "<MODE>")])
5325 (define_insn "fix_trunc<mode>_i387_with_temp"
5326 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5327 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5328 (use (match_operand:HI 2 "memory_operand" "m,m"))
5329 (use (match_operand:HI 3 "memory_operand" "m,m"))
5330 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5331 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5333 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5335 [(set_attr "type" "fistp")
5336 (set_attr "i387_cw" "trunc")
5337 (set_attr "mode" "<MODE>")])
5340 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5341 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5342 (use (match_operand:HI 2 "memory_operand" ""))
5343 (use (match_operand:HI 3 "memory_operand" ""))
5344 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5346 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5348 (use (match_dup 3))])
5349 (set (match_dup 0) (match_dup 4))]
5353 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5354 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5355 (use (match_operand:HI 2 "memory_operand" ""))
5356 (use (match_operand:HI 3 "memory_operand" ""))
5357 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5359 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5361 (use (match_dup 3))])]
5364 (define_insn "x86_fnstcw_1"
5365 [(set (match_operand:HI 0 "memory_operand" "=m")
5366 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5369 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5370 (set_attr "mode" "HI")
5371 (set_attr "unit" "i387")])
5373 (define_insn "x86_fldcw_1"
5374 [(set (reg:HI FPCR_REG)
5375 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5378 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5379 (set_attr "mode" "HI")
5380 (set_attr "unit" "i387")
5381 (set_attr "athlon_decode" "vector")
5382 (set_attr "amdfam10_decode" "vector")])
5384 ;; Conversion between fixed point and floating point.
5386 ;; Even though we only accept memory inputs, the backend _really_
5387 ;; wants to be able to do this between registers.
5389 (define_expand "floathi<mode>2"
5390 [(set (match_operand:X87MODEF 0 "register_operand" "")
5391 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5394 || TARGET_MIX_SSE_I387)"
5397 ;; Pre-reload splitter to add memory clobber to the pattern.
5398 (define_insn_and_split "*floathi<mode>2_1"
5399 [(set (match_operand:X87MODEF 0 "register_operand" "")
5400 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5403 || TARGET_MIX_SSE_I387)
5404 && can_create_pseudo_p ()"
5407 [(parallel [(set (match_dup 0)
5408 (float:X87MODEF (match_dup 1)))
5409 (clobber (match_dup 2))])]
5410 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5412 (define_insn "*floathi<mode>2_i387_with_temp"
5413 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5414 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5415 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5418 || TARGET_MIX_SSE_I387)"
5420 [(set_attr "type" "fmov,multi")
5421 (set_attr "mode" "<MODE>")
5422 (set_attr "unit" "*,i387")
5423 (set_attr "fp_int_src" "true")])
5425 (define_insn "*floathi<mode>2_i387"
5426 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5427 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5429 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5430 || TARGET_MIX_SSE_I387)"
5432 [(set_attr "type" "fmov")
5433 (set_attr "mode" "<MODE>")
5434 (set_attr "fp_int_src" "true")])
5437 [(set (match_operand:X87MODEF 0 "register_operand" "")
5438 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5439 (clobber (match_operand:HI 2 "memory_operand" ""))]
5441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5442 || TARGET_MIX_SSE_I387)
5443 && reload_completed"
5444 [(set (match_dup 2) (match_dup 1))
5445 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5449 [(set (match_operand:X87MODEF 0 "register_operand" "")
5450 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5451 (clobber (match_operand:HI 2 "memory_operand" ""))]
5453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5454 || TARGET_MIX_SSE_I387)
5455 && reload_completed"
5456 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5459 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5460 [(set (match_operand:X87MODEF 0 "register_operand" "")
5462 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5464 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5468 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5469 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5470 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5472 rtx reg = gen_reg_rtx (XFmode);
5475 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5477 if (<X87MODEF:MODE>mode == SFmode)
5478 insn = gen_truncxfsf2 (operands[0], reg);
5479 else if (<X87MODEF:MODE>mode == DFmode)
5480 insn = gen_truncxfdf2 (operands[0], reg);
5489 ;; Pre-reload splitter to add memory clobber to the pattern.
5490 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5491 [(set (match_operand:X87MODEF 0 "register_operand" "")
5492 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5494 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5495 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5496 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5497 || TARGET_MIX_SSE_I387))
5498 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && ((<SSEMODEI24:MODE>mode == SImode
5501 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5502 && optimize_function_for_speed_p (cfun)
5503 && flag_trapping_math)
5504 || !(TARGET_INTER_UNIT_CONVERSIONS
5505 || optimize_function_for_size_p (cfun)))))
5506 && can_create_pseudo_p ()"
5509 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5510 (clobber (match_dup 2))])]
5512 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5514 /* Avoid store forwarding (partial memory) stall penalty
5515 by passing DImode value through XMM registers. */
5516 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5517 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5518 && optimize_function_for_speed_p (cfun))
5520 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5527 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5528 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5530 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5531 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5532 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5533 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5535 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5536 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5537 (set_attr "unit" "*,i387,*,*,*")
5538 (set_attr "athlon_decode" "*,*,double,direct,double")
5539 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5540 (set_attr "fp_int_src" "true")])
5542 (define_insn "*floatsi<mode>2_vector_mixed"
5543 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5544 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5545 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5546 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5550 [(set_attr "type" "fmov,sseicvt")
5551 (set_attr "mode" "<MODE>,<ssevecmode>")
5552 (set_attr "unit" "i387,*")
5553 (set_attr "athlon_decode" "*,direct")
5554 (set_attr "amdfam10_decode" "*,double")
5555 (set_attr "fp_int_src" "true")])
5557 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5558 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5560 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5561 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5562 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5563 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5565 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5566 (set_attr "mode" "<MODEF:MODE>")
5567 (set_attr "unit" "*,i387,*,*")
5568 (set_attr "athlon_decode" "*,*,double,direct")
5569 (set_attr "amdfam10_decode" "*,*,vector,double")
5570 (set_attr "fp_int_src" "true")])
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
5580 && (SSE_REG_P (operands[0])
5581 || (GET_CODE (operands[0]) == SUBREG
5582 && SSE_REG_P (operands[0])))"
5583 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5587 [(set (match_operand:MODEF 0 "register_operand" "")
5588 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5589 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5590 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5591 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5592 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5594 && (SSE_REG_P (operands[0])
5595 || (GET_CODE (operands[0]) == SUBREG
5596 && SSE_REG_P (operands[0])))"
5597 [(set (match_dup 2) (match_dup 1))
5598 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5601 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5602 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5604 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5605 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5606 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5607 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5610 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5611 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5612 [(set_attr "type" "fmov,sseicvt,sseicvt")
5613 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5614 (set_attr "mode" "<MODEF:MODE>")
5615 (set (attr "prefix_rex")
5617 (and (eq_attr "prefix" "maybe_vex")
5618 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5620 (const_string "*")))
5621 (set_attr "unit" "i387,*,*")
5622 (set_attr "athlon_decode" "*,double,direct")
5623 (set_attr "amdfam10_decode" "*,vector,double")
5624 (set_attr "fp_int_src" "true")])
5626 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5627 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5629 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5630 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5631 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5632 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5635 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5636 [(set_attr "type" "fmov,sseicvt")
5637 (set_attr "prefix" "orig,maybe_vex")
5638 (set_attr "mode" "<MODEF:MODE>")
5639 (set (attr "prefix_rex")
5641 (and (eq_attr "prefix" "maybe_vex")
5642 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5644 (const_string "*")))
5645 (set_attr "athlon_decode" "*,direct")
5646 (set_attr "amdfam10_decode" "*,double")
5647 (set_attr "fp_int_src" "true")])
5649 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5650 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5652 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5653 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5654 "TARGET_SSE2 && TARGET_SSE_MATH
5655 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5657 [(set_attr "type" "sseicvt")
5658 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5659 (set_attr "athlon_decode" "double,direct,double")
5660 (set_attr "amdfam10_decode" "vector,double,double")
5661 (set_attr "fp_int_src" "true")])
5663 (define_insn "*floatsi<mode>2_vector_sse"
5664 [(set (match_operand:MODEF 0 "register_operand" "=x")
5665 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5666 "TARGET_SSE2 && TARGET_SSE_MATH
5667 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5669 [(set_attr "type" "sseicvt")
5670 (set_attr "mode" "<MODE>")
5671 (set_attr "athlon_decode" "direct")
5672 (set_attr "amdfam10_decode" "double")
5673 (set_attr "fp_int_src" "true")])
5676 [(set (match_operand:MODEF 0 "register_operand" "")
5677 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5678 (clobber (match_operand:SI 2 "memory_operand" ""))]
5679 "TARGET_SSE2 && TARGET_SSE_MATH
5680 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5682 && (SSE_REG_P (operands[0])
5683 || (GET_CODE (operands[0]) == SUBREG
5684 && SSE_REG_P (operands[0])))"
5687 rtx op1 = operands[1];
5689 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5691 if (GET_CODE (op1) == SUBREG)
5692 op1 = SUBREG_REG (op1);
5694 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5696 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5697 emit_insn (gen_sse2_loadld (operands[4],
5698 CONST0_RTX (V4SImode), operands[1]));
5700 /* We can ignore possible trapping value in the
5701 high part of SSE register for non-trapping math. */
5702 else if (SSE_REG_P (op1) && !flag_trapping_math)
5703 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5706 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5707 emit_move_insn (operands[2], operands[1]);
5708 emit_insn (gen_sse2_loadld (operands[4],
5709 CONST0_RTX (V4SImode), operands[2]));
5712 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5717 [(set (match_operand:MODEF 0 "register_operand" "")
5718 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5719 (clobber (match_operand:SI 2 "memory_operand" ""))]
5720 "TARGET_SSE2 && TARGET_SSE_MATH
5721 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5723 && (SSE_REG_P (operands[0])
5724 || (GET_CODE (operands[0]) == SUBREG
5725 && SSE_REG_P (operands[0])))"
5728 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5730 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5732 emit_insn (gen_sse2_loadld (operands[4],
5733 CONST0_RTX (V4SImode), operands[1]));
5735 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5740 [(set (match_operand:MODEF 0 "register_operand" "")
5741 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5742 "TARGET_SSE2 && TARGET_SSE_MATH
5743 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5745 && (SSE_REG_P (operands[0])
5746 || (GET_CODE (operands[0]) == SUBREG
5747 && SSE_REG_P (operands[0])))"
5750 rtx op1 = operands[1];
5752 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5754 if (GET_CODE (op1) == SUBREG)
5755 op1 = SUBREG_REG (op1);
5757 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5759 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5760 emit_insn (gen_sse2_loadld (operands[4],
5761 CONST0_RTX (V4SImode), operands[1]));
5763 /* We can ignore possible trapping value in the
5764 high part of SSE register for non-trapping math. */
5765 else if (SSE_REG_P (op1) && !flag_trapping_math)
5766 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5770 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5775 [(set (match_operand:MODEF 0 "register_operand" "")
5776 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5777 "TARGET_SSE2 && TARGET_SSE_MATH
5778 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5780 && (SSE_REG_P (operands[0])
5781 || (GET_CODE (operands[0]) == SUBREG
5782 && SSE_REG_P (operands[0])))"
5785 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5787 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5789 emit_insn (gen_sse2_loadld (operands[4],
5790 CONST0_RTX (V4SImode), operands[1]));
5792 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5796 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5797 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5799 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5800 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5801 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5802 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5804 [(set_attr "type" "sseicvt")
5805 (set_attr "mode" "<MODEF:MODE>")
5806 (set_attr "athlon_decode" "double,direct")
5807 (set_attr "amdfam10_decode" "vector,double")
5808 (set_attr "fp_int_src" "true")])
5810 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5811 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5813 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5814 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5815 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5816 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5817 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5818 [(set_attr "type" "sseicvt")
5819 (set_attr "prefix" "maybe_vex")
5820 (set_attr "mode" "<MODEF:MODE>")
5821 (set (attr "prefix_rex")
5823 (and (eq_attr "prefix" "maybe_vex")
5824 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5826 (const_string "*")))
5827 (set_attr "athlon_decode" "double,direct")
5828 (set_attr "amdfam10_decode" "vector,double")
5829 (set_attr "fp_int_src" "true")])
5832 [(set (match_operand:MODEF 0 "register_operand" "")
5833 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5834 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5839 && (SSE_REG_P (operands[0])
5840 || (GET_CODE (operands[0]) == SUBREG
5841 && SSE_REG_P (operands[0])))"
5842 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5845 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5846 [(set (match_operand:MODEF 0 "register_operand" "=x")
5848 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5849 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5850 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5851 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5852 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5853 [(set_attr "type" "sseicvt")
5854 (set_attr "prefix" "maybe_vex")
5855 (set_attr "mode" "<MODEF:MODE>")
5856 (set (attr "prefix_rex")
5858 (and (eq_attr "prefix" "maybe_vex")
5859 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5861 (const_string "*")))
5862 (set_attr "athlon_decode" "direct")
5863 (set_attr "amdfam10_decode" "double")
5864 (set_attr "fp_int_src" "true")])
5867 [(set (match_operand:MODEF 0 "register_operand" "")
5868 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5869 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5870 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5872 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5874 && (SSE_REG_P (operands[0])
5875 || (GET_CODE (operands[0]) == SUBREG
5876 && SSE_REG_P (operands[0])))"
5877 [(set (match_dup 2) (match_dup 1))
5878 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5882 [(set (match_operand:MODEF 0 "register_operand" "")
5883 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5884 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5885 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5886 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5888 && (SSE_REG_P (operands[0])
5889 || (GET_CODE (operands[0]) == SUBREG
5890 && SSE_REG_P (operands[0])))"
5891 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5894 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5895 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5897 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5898 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5900 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5904 [(set_attr "type" "fmov,multi")
5905 (set_attr "mode" "<X87MODEF:MODE>")
5906 (set_attr "unit" "*,i387")
5907 (set_attr "fp_int_src" "true")])
5909 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5910 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5912 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5914 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5916 [(set_attr "type" "fmov")
5917 (set_attr "mode" "<X87MODEF:MODE>")
5918 (set_attr "fp_int_src" "true")])
5921 [(set (match_operand:X87MODEF 0 "register_operand" "")
5922 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5923 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5925 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5927 && FP_REG_P (operands[0])"
5928 [(set (match_dup 2) (match_dup 1))
5929 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5933 [(set (match_operand:X87MODEF 0 "register_operand" "")
5934 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5935 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5937 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5939 && FP_REG_P (operands[0])"
5940 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5943 ;; Avoid store forwarding (partial memory) stall penalty
5944 ;; by passing DImode value through XMM registers. */
5946 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5947 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5949 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5950 (clobber (match_scratch:V4SI 3 "=X,x"))
5951 (clobber (match_scratch:V4SI 4 "=X,x"))
5952 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5953 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5954 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5955 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5957 [(set_attr "type" "multi")
5958 (set_attr "mode" "<X87MODEF:MODE>")
5959 (set_attr "unit" "i387")
5960 (set_attr "fp_int_src" "true")])
5963 [(set (match_operand:X87MODEF 0 "register_operand" "")
5964 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5965 (clobber (match_scratch:V4SI 3 ""))
5966 (clobber (match_scratch:V4SI 4 ""))
5967 (clobber (match_operand:DI 2 "memory_operand" ""))]
5968 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5969 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5970 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5972 && FP_REG_P (operands[0])"
5973 [(set (match_dup 2) (match_dup 3))
5974 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5976 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5977 Assemble the 64-bit DImode value in an xmm register. */
5978 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5979 gen_rtx_SUBREG (SImode, operands[1], 0)));
5980 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5981 gen_rtx_SUBREG (SImode, operands[1], 4)));
5982 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5984 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5988 [(set (match_operand:X87MODEF 0 "register_operand" "")
5989 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5990 (clobber (match_scratch:V4SI 3 ""))
5991 (clobber (match_scratch:V4SI 4 ""))
5992 (clobber (match_operand:DI 2 "memory_operand" ""))]
5993 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5994 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5995 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5997 && FP_REG_P (operands[0])"
5998 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
6001 ;; Avoid store forwarding (partial memory) stall penalty by extending
6002 ;; SImode value to DImode through XMM register instead of pushing two
6003 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
6004 ;; targets benefit from this optimization. Also note that fild
6005 ;; loads from memory only.
6007 (define_insn "*floatunssi<mode>2_1"
6008 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6009 (unsigned_float:X87MODEF
6010 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
6011 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6012 (clobber (match_scratch:SI 3 "=X,x"))]
6014 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6017 [(set_attr "type" "multi")
6018 (set_attr "mode" "<MODE>")])
6021 [(set (match_operand:X87MODEF 0 "register_operand" "")
6022 (unsigned_float:X87MODEF
6023 (match_operand:SI 1 "register_operand" "")))
6024 (clobber (match_operand:DI 2 "memory_operand" ""))
6025 (clobber (match_scratch:SI 3 ""))]
6027 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6029 && reload_completed"
6030 [(set (match_dup 2) (match_dup 1))
6032 (float:X87MODEF (match_dup 2)))]
6033 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6036 [(set (match_operand:X87MODEF 0 "register_operand" "")
6037 (unsigned_float:X87MODEF
6038 (match_operand:SI 1 "memory_operand" "")))
6039 (clobber (match_operand:DI 2 "memory_operand" ""))
6040 (clobber (match_scratch:SI 3 ""))]
6042 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6044 && reload_completed"
6045 [(set (match_dup 2) (match_dup 3))
6047 (float:X87MODEF (match_dup 2)))]
6049 emit_move_insn (operands[3], operands[1]);
6050 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6053 (define_expand "floatunssi<mode>2"
6055 [(set (match_operand:X87MODEF 0 "register_operand" "")
6056 (unsigned_float:X87MODEF
6057 (match_operand:SI 1 "nonimmediate_operand" "")))
6058 (clobber (match_dup 2))
6059 (clobber (match_scratch:SI 3 ""))])]
6061 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6063 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6065 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6067 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6072 enum ix86_stack_slot slot = (virtuals_instantiated
6075 operands[2] = assign_386_stack_local (DImode, slot);
6079 (define_expand "floatunsdisf2"
6080 [(use (match_operand:SF 0 "register_operand" ""))
6081 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6082 "TARGET_64BIT && TARGET_SSE_MATH"
6083 "x86_emit_floatuns (operands); DONE;")
6085 (define_expand "floatunsdidf2"
6086 [(use (match_operand:DF 0 "register_operand" ""))
6087 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6088 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6089 && TARGET_SSE2 && TARGET_SSE_MATH"
6092 x86_emit_floatuns (operands);
6094 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6100 (define_expand "add<mode>3"
6101 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6102 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6103 (match_operand:SDWIM 2 "<general_operand>" "")))]
6105 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6107 (define_insn_and_split "*add<dwi>3_doubleword"
6108 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6110 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6111 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6112 (clobber (reg:CC FLAGS_REG))]
6113 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6116 [(parallel [(set (reg:CC FLAGS_REG)
6117 (unspec:CC [(match_dup 1) (match_dup 2)]
6120 (plus:DWIH (match_dup 1) (match_dup 2)))])
6121 (parallel [(set (match_dup 3)
6124 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6127 (clobber (reg:CC FLAGS_REG))])]
6128 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6130 (define_insn "add<mode>3_carry"
6131 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6133 (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
6134 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6135 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6136 (clobber (reg:CC FLAGS_REG))]
6137 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6138 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6139 [(set_attr "type" "alu")
6140 (set_attr "use_carry" "1")
6141 (set_attr "pent_pair" "pu")
6142 (set_attr "mode" "<MODE>")])
6144 (define_insn "*addsi3_carry_zext"
6145 [(set (match_operand:DI 0 "register_operand" "=r")
6148 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6149 (match_operand:SI 1 "nonimmediate_operand" "%0"))
6150 (match_operand:SI 2 "general_operand" "g"))))
6151 (clobber (reg:CC FLAGS_REG))]
6152 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6153 "adc{l}\t{%2, %k0|%k0, %2}"
6154 [(set_attr "type" "alu")
6155 (set_attr "use_carry" "1")
6156 (set_attr "pent_pair" "pu")
6157 (set_attr "mode" "SI")])
6159 (define_insn "*add<mode>3_cc"
6160 [(set (reg:CC FLAGS_REG)
6162 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6163 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6165 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6166 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6167 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6168 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6169 [(set_attr "type" "alu")
6170 (set_attr "mode" "<MODE>")])
6172 (define_insn "addqi3_cc"
6173 [(set (reg:CC FLAGS_REG)
6175 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6176 (match_operand:QI 2 "general_operand" "qn,qm")]
6178 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6179 (plus:QI (match_dup 1) (match_dup 2)))]
6180 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6181 "add{b}\t{%2, %0|%0, %2}"
6182 [(set_attr "type" "alu")
6183 (set_attr "mode" "QI")])
6185 (define_insn "*add<mode>3_cconly_overflow"
6186 [(set (reg:CCC FLAGS_REG)
6189 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6190 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6192 (clobber (match_scratch:SWI 0 "=<r>"))]
6193 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6194 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6195 [(set_attr "type" "alu")
6196 (set_attr "mode" "<MODE>")])
6198 (define_insn "*lea_1"
6199 [(set (match_operand:DWIH 0 "register_operand" "=r")
6200 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6202 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6203 [(set_attr "type" "lea")
6204 (set_attr "mode" "<MODE>")])
6206 (define_insn "*lea_2"
6207 [(set (match_operand:SI 0 "register_operand" "=r")
6208 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6210 "lea{l}\t{%a1, %0|%0, %a1}"
6211 [(set_attr "type" "lea")
6212 (set_attr "mode" "SI")])
6214 (define_insn "*lea_2_zext"
6215 [(set (match_operand:DI 0 "register_operand" "=r")
6217 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6219 "lea{l}\t{%a1, %k0|%k0, %a1}"
6220 [(set_attr "type" "lea")
6221 (set_attr "mode" "SI")])
6223 (define_insn "*add<mode>_1"
6224 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6226 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6227 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6228 (clobber (reg:CC FLAGS_REG))]
6229 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6231 switch (get_attr_type (insn))
6234 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6235 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6238 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6239 if (operands[2] == const1_rtx)
6240 return "inc{<imodesuffix>}\t%0";
6243 gcc_assert (operands[2] == constm1_rtx);
6244 return "dec{<imodesuffix>}\t%0";
6248 /* Use add as much as possible to replace lea for AGU optimization. */
6249 if (which_alternative == 2 && TARGET_OPT_AGU)
6250 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6254 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6255 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6256 if (CONST_INT_P (operands[2])
6257 /* Avoid overflows. */
6258 && (<MODE>mode != DImode
6259 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6267 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6271 (cond [(and (eq_attr "alternative" "2")
6272 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6273 (const_string "lea")
6274 (eq_attr "alternative" "3")
6275 (const_string "lea")
6276 ; Current assemblers are broken and do not allow @GOTOFF in
6277 ; ought but a memory context.
6278 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6279 (const_string "lea")
6280 (match_operand:SWI48 2 "incdec_operand" "")
6281 (const_string "incdec")
6283 (const_string "alu")))
6284 (set (attr "length_immediate")
6286 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6288 (const_string "*")))
6289 (set_attr "mode" "<MODE>")])
6291 ;; It may seem that nonimmediate operand is proper one for operand 1.
6292 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6293 ;; we take care in ix86_binary_operator_ok to not allow two memory
6294 ;; operands so proper swapping will be done in reload. This allow
6295 ;; patterns constructed from addsi_1 to match.
6297 (define_insn "*addsi_1_zext"
6298 [(set (match_operand:DI 0 "register_operand" "=r,r")
6300 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6301 (match_operand:SI 2 "general_operand" "g,li"))))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6305 switch (get_attr_type (insn))
6308 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6309 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6312 if (operands[2] == const1_rtx)
6313 return "inc{l}\t%k0";
6316 gcc_assert (operands[2] == constm1_rtx);
6317 return "dec{l}\t%k0";
6321 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6322 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6323 if (CONST_INT_P (operands[2])
6324 && (INTVAL (operands[2]) == 128
6325 || (INTVAL (operands[2]) < 0
6326 && INTVAL (operands[2]) != -128)))
6328 operands[2] = GEN_INT (-INTVAL (operands[2]));
6329 return "sub{l}\t{%2, %k0|%k0, %2}";
6331 return "add{l}\t{%2, %k0|%k0, %2}";
6335 (cond [(eq_attr "alternative" "1")
6336 (const_string "lea")
6337 ; Current assemblers are broken and do not allow @GOTOFF in
6338 ; ought but a memory context.
6339 (match_operand:SI 2 "pic_symbolic_operand" "")
6340 (const_string "lea")
6341 (match_operand:SI 2 "incdec_operand" "")
6342 (const_string "incdec")
6344 (const_string "alu")))
6345 (set (attr "length_immediate")
6347 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6349 (const_string "*")))
6350 (set_attr "mode" "SI")])
6352 (define_insn "*addhi_1"
6353 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6354 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6355 (match_operand:HI 2 "general_operand" "rn,rm")))
6356 (clobber (reg:CC FLAGS_REG))]
6357 "TARGET_PARTIAL_REG_STALL
6358 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6360 switch (get_attr_type (insn))
6363 if (operands[2] == const1_rtx)
6364 return "inc{w}\t%0";
6367 gcc_assert (operands[2] == constm1_rtx);
6368 return "dec{w}\t%0";
6372 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6373 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6374 if (CONST_INT_P (operands[2])
6375 && (INTVAL (operands[2]) == 128
6376 || (INTVAL (operands[2]) < 0
6377 && INTVAL (operands[2]) != -128)))
6379 operands[2] = GEN_INT (-INTVAL (operands[2]));
6380 return "sub{w}\t{%2, %0|%0, %2}";
6382 return "add{w}\t{%2, %0|%0, %2}";
6386 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set (attr "length_immediate")
6391 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6393 (const_string "*")))
6394 (set_attr "mode" "HI")])
6396 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6397 ;; type optimizations enabled by define-splits. This is not important
6398 ;; for PII, and in fact harmful because of partial register stalls.
6400 (define_insn "*addhi_1_lea"
6401 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6402 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6403 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6404 (clobber (reg:CC FLAGS_REG))]
6405 "!TARGET_PARTIAL_REG_STALL
6406 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6408 switch (get_attr_type (insn))
6413 if (operands[2] == const1_rtx)
6414 return "inc{w}\t%0";
6417 gcc_assert (operands[2] == constm1_rtx);
6418 return "dec{w}\t%0";
6422 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6423 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6424 if (CONST_INT_P (operands[2])
6425 && (INTVAL (operands[2]) == 128
6426 || (INTVAL (operands[2]) < 0
6427 && INTVAL (operands[2]) != -128)))
6429 operands[2] = GEN_INT (-INTVAL (operands[2]));
6430 return "sub{w}\t{%2, %0|%0, %2}";
6432 return "add{w}\t{%2, %0|%0, %2}";
6436 (if_then_else (eq_attr "alternative" "2")
6437 (const_string "lea")
6438 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6439 (const_string "incdec")
6440 (const_string "alu"))))
6441 (set (attr "length_immediate")
6443 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6445 (const_string "*")))
6446 (set_attr "mode" "HI,HI,SI")])
6448 (define_insn "*addqi_1"
6449 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6450 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6451 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "TARGET_PARTIAL_REG_STALL
6454 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6456 int widen = (which_alternative == 2);
6457 switch (get_attr_type (insn))
6460 if (operands[2] == const1_rtx)
6461 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6464 gcc_assert (operands[2] == constm1_rtx);
6465 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6469 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6470 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6471 if (CONST_INT_P (operands[2])
6472 && (INTVAL (operands[2]) == 128
6473 || (INTVAL (operands[2]) < 0
6474 && INTVAL (operands[2]) != -128)))
6476 operands[2] = GEN_INT (-INTVAL (operands[2]));
6478 return "sub{l}\t{%2, %k0|%k0, %2}";
6480 return "sub{b}\t{%2, %0|%0, %2}";
6483 return "add{l}\t{%k2, %k0|%k0, %k2}";
6485 return "add{b}\t{%2, %0|%0, %2}";
6489 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6490 (const_string "incdec")
6491 (const_string "alu")))
6492 (set (attr "length_immediate")
6494 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6496 (const_string "*")))
6497 (set_attr "mode" "QI,QI,SI")])
6499 ;; %%% Potential partial reg stall on alternative 2. What to do?
6500 (define_insn "*addqi_1_lea"
6501 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6502 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6503 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6504 (clobber (reg:CC FLAGS_REG))]
6505 "!TARGET_PARTIAL_REG_STALL
6506 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6508 int widen = (which_alternative == 2);
6509 switch (get_attr_type (insn))
6514 if (operands[2] == const1_rtx)
6515 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6518 gcc_assert (operands[2] == constm1_rtx);
6519 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6523 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6524 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6525 if (CONST_INT_P (operands[2])
6526 && (INTVAL (operands[2]) == 128
6527 || (INTVAL (operands[2]) < 0
6528 && INTVAL (operands[2]) != -128)))
6530 operands[2] = GEN_INT (-INTVAL (operands[2]));
6532 return "sub{l}\t{%2, %k0|%k0, %2}";
6534 return "sub{b}\t{%2, %0|%0, %2}";
6537 return "add{l}\t{%k2, %k0|%k0, %k2}";
6539 return "add{b}\t{%2, %0|%0, %2}";
6543 (if_then_else (eq_attr "alternative" "3")
6544 (const_string "lea")
6545 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6546 (const_string "incdec")
6547 (const_string "alu"))))
6548 (set (attr "length_immediate")
6550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6552 (const_string "*")))
6553 (set_attr "mode" "QI,QI,SI,SI")])
6555 (define_insn "*addqi_1_slp"
6556 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6557 (plus:QI (match_dup 0)
6558 (match_operand:QI 1 "general_operand" "qn,qnm")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6561 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6563 switch (get_attr_type (insn))
6566 if (operands[1] == const1_rtx)
6567 return "inc{b}\t%0";
6570 gcc_assert (operands[1] == constm1_rtx);
6571 return "dec{b}\t%0";
6575 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6576 if (CONST_INT_P (operands[1])
6577 && INTVAL (operands[1]) < 0)
6579 operands[1] = GEN_INT (-INTVAL (operands[1]));
6580 return "sub{b}\t{%1, %0|%0, %1}";
6582 return "add{b}\t{%1, %0|%0, %1}";
6586 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6587 (const_string "incdec")
6588 (const_string "alu1")))
6589 (set (attr "memory")
6590 (if_then_else (match_operand 1 "memory_operand" "")
6591 (const_string "load")
6592 (const_string "none")))
6593 (set_attr "mode" "QI")])
6595 (define_insn "*add<mode>_2"
6596 [(set (reg FLAGS_REG)
6599 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6600 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6602 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6603 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6604 "ix86_match_ccmode (insn, CCGOCmode)
6605 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6606 /* Current assemblers are broken and do not allow @GOTOFF in
6607 ought but a memory context. */
6608 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6610 switch (get_attr_type (insn))
6613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614 if (operands[2] == const1_rtx)
6615 return "inc{<imodesuffix>}\t%0";
6618 gcc_assert (operands[2] == constm1_rtx);
6619 return "dec{<imodesuffix>}\t%0";
6623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6624 /* ???? In DImode, we ought to handle there the 32bit case too
6625 - do we need new constraint? */
6626 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6627 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6628 if (CONST_INT_P (operands[2])
6629 /* Avoid overflows. */
6630 && (<MODE>mode != DImode
6631 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6632 && (INTVAL (operands[2]) == 128
6633 || (INTVAL (operands[2]) < 0
6634 && INTVAL (operands[2]) != -128)))
6636 operands[2] = GEN_INT (-INTVAL (operands[2]));
6637 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6639 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6643 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6644 (const_string "incdec")
6645 (const_string "alu")))
6646 (set (attr "length_immediate")
6648 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6650 (const_string "*")))
6651 (set_attr "mode" "<MODE>")])
6653 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6654 (define_insn "*addsi_2_zext"
6655 [(set (reg FLAGS_REG)
6657 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6658 (match_operand:SI 2 "general_operand" "g"))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6661 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6662 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6663 && ix86_binary_operator_ok (PLUS, SImode, operands)
6664 /* Current assemblers are broken and do not allow @GOTOFF in
6665 ought but a memory context. */
6666 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6668 switch (get_attr_type (insn))
6671 if (operands[2] == const1_rtx)
6672 return "inc{l}\t%k0";
6675 gcc_assert (operands[2] == constm1_rtx);
6676 return "dec{l}\t%k0";
6680 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6681 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6682 if (CONST_INT_P (operands[2])
6683 && (INTVAL (operands[2]) == 128
6684 || (INTVAL (operands[2]) < 0
6685 && INTVAL (operands[2]) != -128)))
6687 operands[2] = GEN_INT (-INTVAL (operands[2]));
6688 return "sub{l}\t{%2, %k0|%k0, %2}";
6690 return "add{l}\t{%2, %k0|%k0, %2}";
6694 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6695 (const_string "incdec")
6696 (const_string "alu")))
6697 (set (attr "length_immediate")
6699 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6701 (const_string "*")))
6702 (set_attr "mode" "SI")])
6704 (define_insn "*addhi_2"
6705 [(set (reg FLAGS_REG)
6707 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6708 (match_operand:HI 2 "general_operand" "rmn,rn"))
6710 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6711 (plus:HI (match_dup 1) (match_dup 2)))]
6712 "ix86_match_ccmode (insn, CCGOCmode)
6713 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6715 switch (get_attr_type (insn))
6718 if (operands[2] == const1_rtx)
6719 return "inc{w}\t%0";
6722 gcc_assert (operands[2] == constm1_rtx);
6723 return "dec{w}\t%0";
6727 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6728 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6729 if (CONST_INT_P (operands[2])
6730 && (INTVAL (operands[2]) == 128
6731 || (INTVAL (operands[2]) < 0
6732 && INTVAL (operands[2]) != -128)))
6734 operands[2] = GEN_INT (-INTVAL (operands[2]));
6735 return "sub{w}\t{%2, %0|%0, %2}";
6737 return "add{w}\t{%2, %0|%0, %2}";
6741 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6742 (const_string "incdec")
6743 (const_string "alu")))
6744 (set (attr "length_immediate")
6746 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6748 (const_string "*")))
6749 (set_attr "mode" "HI")])
6751 (define_insn "*addqi_2"
6752 [(set (reg FLAGS_REG)
6754 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6755 (match_operand:QI 2 "general_operand" "qmn,qn"))
6757 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6758 (plus:QI (match_dup 1) (match_dup 2)))]
6759 "ix86_match_ccmode (insn, CCGOCmode)
6760 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6762 switch (get_attr_type (insn))
6765 if (operands[2] == const1_rtx)
6766 return "inc{b}\t%0";
6769 gcc_assert (operands[2] == constm1_rtx
6770 || (CONST_INT_P (operands[2])
6771 && INTVAL (operands[2]) == 255));
6772 return "dec{b}\t%0";
6776 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6777 if (CONST_INT_P (operands[2])
6778 && INTVAL (operands[2]) < 0)
6780 operands[2] = GEN_INT (-INTVAL (operands[2]));
6781 return "sub{b}\t{%2, %0|%0, %2}";
6783 return "add{b}\t{%2, %0|%0, %2}";
6787 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6788 (const_string "incdec")
6789 (const_string "alu")))
6790 (set_attr "mode" "QI")])
6792 (define_insn "*add<mode>_3"
6793 [(set (reg FLAGS_REG)
6795 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6796 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6797 (clobber (match_scratch:SWI48 0 "=r"))]
6798 "ix86_match_ccmode (insn, CCZmode)
6799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6800 /* Current assemblers are broken and do not allow @GOTOFF in
6801 ought but a memory context. */
6802 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6804 switch (get_attr_type (insn))
6807 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6808 if (operands[2] == const1_rtx)
6809 return "inc{<imodesuffix>}\t%0";
6812 gcc_assert (operands[2] == constm1_rtx);
6813 return "dec{<imodesuffix>}\t%0";
6817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6818 /* ???? In DImode, we ought to handle there the 32bit case too
6819 - do we need new constraint? */
6820 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6821 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6822 if (CONST_INT_P (operands[2])
6823 /* Avoid overflows. */
6824 && (<MODE>mode != DImode
6825 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6826 && (INTVAL (operands[2]) == 128
6827 || (INTVAL (operands[2]) < 0
6828 && INTVAL (operands[2]) != -128)))
6830 operands[2] = GEN_INT (-INTVAL (operands[2]));
6831 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6833 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6837 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6838 (const_string "incdec")
6839 (const_string "alu")))
6840 (set (attr "length_immediate")
6842 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844 (const_string "*")))
6845 (set_attr "mode" "<MODE>")])
6847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6848 (define_insn "*addsi_3_zext"
6849 [(set (reg FLAGS_REG)
6851 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6852 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6853 (set (match_operand:DI 0 "register_operand" "=r")
6854 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6855 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6856 && ix86_binary_operator_ok (PLUS, SImode, operands)
6857 /* Current assemblers are broken and do not allow @GOTOFF in
6858 ought but a memory context. */
6859 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6861 switch (get_attr_type (insn))
6864 if (operands[2] == const1_rtx)
6865 return "inc{l}\t%k0";
6868 gcc_assert (operands[2] == constm1_rtx);
6869 return "dec{l}\t%k0";
6873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6875 if (CONST_INT_P (operands[2])
6876 && (INTVAL (operands[2]) == 128
6877 || (INTVAL (operands[2]) < 0
6878 && INTVAL (operands[2]) != -128)))
6880 operands[2] = GEN_INT (-INTVAL (operands[2]));
6881 return "sub{l}\t{%2, %k0|%k0, %2}";
6883 return "add{l}\t{%2, %k0|%k0, %2}";
6887 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6888 (const_string "incdec")
6889 (const_string "alu")))
6890 (set (attr "length_immediate")
6892 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6894 (const_string "*")))
6895 (set_attr "mode" "SI")])
6897 (define_insn "*addhi_3"
6898 [(set (reg FLAGS_REG)
6900 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6901 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6902 (clobber (match_scratch:HI 0 "=r"))]
6903 "ix86_match_ccmode (insn, CCZmode)
6904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906 switch (get_attr_type (insn))
6909 if (operands[2] == const1_rtx)
6910 return "inc{w}\t%0";
6913 gcc_assert (operands[2] == constm1_rtx);
6914 return "dec{w}\t%0";
6918 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6919 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6920 if (CONST_INT_P (operands[2])
6921 && (INTVAL (operands[2]) == 128
6922 || (INTVAL (operands[2]) < 0
6923 && INTVAL (operands[2]) != -128)))
6925 operands[2] = GEN_INT (-INTVAL (operands[2]));
6926 return "sub{w}\t{%2, %0|%0, %2}";
6928 return "add{w}\t{%2, %0|%0, %2}";
6932 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6933 (const_string "incdec")
6934 (const_string "alu")))
6935 (set (attr "length_immediate")
6937 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6939 (const_string "*")))
6940 (set_attr "mode" "HI")])
6942 (define_insn "*addqi_3"
6943 [(set (reg FLAGS_REG)
6945 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6946 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6947 (clobber (match_scratch:QI 0 "=q"))]
6948 "ix86_match_ccmode (insn, CCZmode)
6949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 switch (get_attr_type (insn))
6954 if (operands[2] == const1_rtx)
6955 return "inc{b}\t%0";
6958 gcc_assert (operands[2] == constm1_rtx
6959 || (CONST_INT_P (operands[2])
6960 && INTVAL (operands[2]) == 255));
6961 return "dec{b}\t%0";
6965 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6966 if (CONST_INT_P (operands[2])
6967 && INTVAL (operands[2]) < 0)
6969 operands[2] = GEN_INT (-INTVAL (operands[2]));
6970 return "sub{b}\t{%2, %0|%0, %2}";
6972 return "add{b}\t{%2, %0|%0, %2}";
6976 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6977 (const_string "incdec")
6978 (const_string "alu")))
6979 (set_attr "mode" "QI")])
6981 ; For comparisons against 1, -1 and 128, we may generate better code
6982 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6983 ; is matched then. We can't accept general immediate, because for
6984 ; case of overflows, the result is messed up.
6985 ; This pattern also don't hold of 0x8000000000000000, since the value
6986 ; overflows when negated.
6987 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6988 ; only for comparisons not depending on it.
6990 (define_insn "*adddi_4"
6991 [(set (reg FLAGS_REG)
6993 (match_operand:DI 1 "nonimmediate_operand" "0")
6994 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6995 (clobber (match_scratch:DI 0 "=rm"))]
6997 && ix86_match_ccmode (insn, CCGCmode)"
6999 switch (get_attr_type (insn))
7002 if (operands[2] == constm1_rtx)
7003 return "inc{q}\t%0";
7006 gcc_assert (operands[2] == const1_rtx);
7007 return "dec{q}\t%0";
7011 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7012 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7013 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7014 if ((INTVAL (operands[2]) == -128
7015 || (INTVAL (operands[2]) > 0
7016 && INTVAL (operands[2]) != 128))
7017 /* Avoid overflows. */
7018 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7019 return "sub{q}\t{%2, %0|%0, %2}";
7020 operands[2] = GEN_INT (-INTVAL (operands[2]));
7021 return "add{q}\t{%2, %0|%0, %2}";
7025 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7026 (const_string "incdec")
7027 (const_string "alu")))
7028 (set (attr "length_immediate")
7030 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7032 (const_string "*")))
7033 (set_attr "mode" "DI")])
7035 ; For comparisons against 1, -1 and 128, we may generate better code
7036 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7037 ; is matched then. We can't accept general immediate, because for
7038 ; case of overflows, the result is messed up.
7039 ; This pattern also don't hold of 0x80000000, since the value overflows
7041 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7042 ; only for comparisons not depending on it.
7044 (define_insn "*addsi_4"
7045 [(set (reg FLAGS_REG)
7047 (match_operand:SI 1 "nonimmediate_operand" "0")
7048 (match_operand:SI 2 "const_int_operand" "n")))
7049 (clobber (match_scratch:SI 0 "=rm"))]
7050 "ix86_match_ccmode (insn, CCGCmode)
7051 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7053 switch (get_attr_type (insn))
7056 if (operands[2] == constm1_rtx)
7057 return "inc{l}\t%0";
7060 gcc_assert (operands[2] == const1_rtx);
7061 return "dec{l}\t%0";
7065 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7066 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7067 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7068 if ((INTVAL (operands[2]) == -128
7069 || (INTVAL (operands[2]) > 0
7070 && INTVAL (operands[2]) != 128)))
7071 return "sub{l}\t{%2, %0|%0, %2}";
7072 operands[2] = GEN_INT (-INTVAL (operands[2]));
7073 return "add{l}\t{%2, %0|%0, %2}";
7077 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7078 (const_string "incdec")
7079 (const_string "alu")))
7080 (set (attr "length_immediate")
7082 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7084 (const_string "*")))
7085 (set_attr "mode" "SI")])
7087 ; See comments above addsi_4 for details.
7089 (define_insn "*addhi_4"
7090 [(set (reg FLAGS_REG)
7092 (match_operand:HI 1 "nonimmediate_operand" "0")
7093 (match_operand:HI 2 "const_int_operand" "n")))
7094 (clobber (match_scratch:HI 0 "=rm"))]
7095 "ix86_match_ccmode (insn, CCGCmode)
7096 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7098 switch (get_attr_type (insn))
7101 if (operands[2] == constm1_rtx)
7102 return "inc{w}\t%0";
7105 gcc_assert (operands[2] == const1_rtx);
7106 return "dec{w}\t%0";
7110 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7111 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7112 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7113 if ((INTVAL (operands[2]) == -128
7114 || (INTVAL (operands[2]) > 0
7115 && INTVAL (operands[2]) != 128)))
7116 return "sub{w}\t{%2, %0|%0, %2}";
7117 operands[2] = GEN_INT (-INTVAL (operands[2]));
7118 return "add{w}\t{%2, %0|%0, %2}";
7122 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7123 (const_string "incdec")
7124 (const_string "alu")))
7125 (set (attr "length_immediate")
7127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7129 (const_string "*")))
7130 (set_attr "mode" "HI")])
7132 ; See comments above addsi_4 for details.
7134 (define_insn "*addqi_4"
7135 [(set (reg FLAGS_REG)
7137 (match_operand:QI 1 "nonimmediate_operand" "0")
7138 (match_operand:QI 2 "const_int_operand" "n")))
7139 (clobber (match_scratch:QI 0 "=qm"))]
7140 "ix86_match_ccmode (insn, CCGCmode)
7141 && (INTVAL (operands[2]) & 0xff) != 0x80"
7143 switch (get_attr_type (insn))
7146 if (operands[2] == constm1_rtx
7147 || (CONST_INT_P (operands[2])
7148 && INTVAL (operands[2]) == 255))
7149 return "inc{b}\t%0";
7152 gcc_assert (operands[2] == const1_rtx);
7153 return "dec{b}\t%0";
7157 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7158 if (INTVAL (operands[2]) < 0)
7160 operands[2] = GEN_INT (-INTVAL (operands[2]));
7161 return "add{b}\t{%2, %0|%0, %2}";
7163 return "sub{b}\t{%2, %0|%0, %2}";
7167 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7168 (const_string "incdec")
7169 (const_string "alu")))
7170 (set_attr "mode" "QI")])
7172 (define_insn "*add<mode>_5"
7173 [(set (reg FLAGS_REG)
7176 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
7177 (match_operand:SWI48 2 "<general_operand>" "<g>"))
7179 (clobber (match_scratch:SWI48 0 "=r"))]
7180 "ix86_match_ccmode (insn, CCGOCmode)
7181 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7182 /* Current assemblers are broken and do not allow @GOTOFF in
7183 ought but a memory context. */
7184 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7186 switch (get_attr_type (insn))
7189 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7190 if (operands[2] == const1_rtx)
7191 return "inc{<imodesuffix>}\t%0";
7194 gcc_assert (operands[2] == constm1_rtx);
7195 return "dec{<imodesuffix>}\t%0";
7199 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7200 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
7201 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7202 if (CONST_INT_P (operands[2])
7203 /* Avoid overflows. */
7204 && (<MODE>mode != DImode
7205 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
7206 && (INTVAL (operands[2]) == 128
7207 || (INTVAL (operands[2]) < 0
7208 && INTVAL (operands[2]) != -128)))
7210 operands[2] = GEN_INT (-INTVAL (operands[2]));
7211 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7213 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7217 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
7218 (const_string "incdec")
7219 (const_string "alu")))
7220 (set (attr "length_immediate")
7222 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7224 (const_string "*")))
7225 (set_attr "mode" "<MODE>")])
7227 (define_insn "*addhi_5"
7228 [(set (reg FLAGS_REG)
7230 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7231 (match_operand:HI 2 "general_operand" "rmn"))
7233 (clobber (match_scratch:HI 0 "=r"))]
7234 "ix86_match_ccmode (insn, CCGOCmode)
7235 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7237 switch (get_attr_type (insn))
7240 if (operands[2] == const1_rtx)
7241 return "inc{w}\t%0";
7244 gcc_assert (operands[2] == constm1_rtx);
7245 return "dec{w}\t%0";
7249 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7250 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7251 if (CONST_INT_P (operands[2])
7252 && (INTVAL (operands[2]) == 128
7253 || (INTVAL (operands[2]) < 0
7254 && INTVAL (operands[2]) != -128)))
7256 operands[2] = GEN_INT (-INTVAL (operands[2]));
7257 return "sub{w}\t{%2, %0|%0, %2}";
7259 return "add{w}\t{%2, %0|%0, %2}";
7263 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7264 (const_string "incdec")
7265 (const_string "alu")))
7266 (set (attr "length_immediate")
7268 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7270 (const_string "*")))
7271 (set_attr "mode" "HI")])
7273 (define_insn "*addqi_5"
7274 [(set (reg FLAGS_REG)
7276 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7277 (match_operand:QI 2 "general_operand" "qmn"))
7279 (clobber (match_scratch:QI 0 "=q"))]
7280 "ix86_match_ccmode (insn, CCGOCmode)
7281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283 switch (get_attr_type (insn))
7286 if (operands[2] == const1_rtx)
7287 return "inc{b}\t%0";
7290 gcc_assert (operands[2] == constm1_rtx
7291 || (CONST_INT_P (operands[2])
7292 && INTVAL (operands[2]) == 255));
7293 return "dec{b}\t%0";
7297 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7298 if (CONST_INT_P (operands[2])
7299 && INTVAL (operands[2]) < 0)
7301 operands[2] = GEN_INT (-INTVAL (operands[2]));
7302 return "sub{b}\t{%2, %0|%0, %2}";
7304 return "add{b}\t{%2, %0|%0, %2}";
7308 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7309 (const_string "incdec")
7310 (const_string "alu")))
7311 (set_attr "mode" "QI")])
7313 (define_insn "*addqi_ext_1_rex64"
7314 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7319 (match_operand 1 "ext_register_operand" "0")
7322 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7323 (clobber (reg:CC FLAGS_REG))]
7326 switch (get_attr_type (insn))
7329 if (operands[2] == const1_rtx)
7330 return "inc{b}\t%h0";
7333 gcc_assert (operands[2] == constm1_rtx
7334 || (CONST_INT_P (operands[2])
7335 && INTVAL (operands[2]) == 255));
7336 return "dec{b}\t%h0";
7340 return "add{b}\t{%2, %h0|%h0, %2}";
7344 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7345 (const_string "incdec")
7346 (const_string "alu")))
7347 (set_attr "modrm" "1")
7348 (set_attr "mode" "QI")])
7350 (define_insn "addqi_ext_1"
7351 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7356 (match_operand 1 "ext_register_operand" "0")
7359 (match_operand:QI 2 "general_operand" "Qmn")))
7360 (clobber (reg:CC FLAGS_REG))]
7363 switch (get_attr_type (insn))
7366 if (operands[2] == const1_rtx)
7367 return "inc{b}\t%h0";
7370 gcc_assert (operands[2] == constm1_rtx
7371 || (CONST_INT_P (operands[2])
7372 && INTVAL (operands[2]) == 255));
7373 return "dec{b}\t%h0";
7377 return "add{b}\t{%2, %h0|%h0, %2}";
7381 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7382 (const_string "incdec")
7383 (const_string "alu")))
7384 (set_attr "modrm" "1")
7385 (set_attr "mode" "QI")])
7387 (define_insn "*addqi_ext_2"
7388 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7393 (match_operand 1 "ext_register_operand" "%0")
7397 (match_operand 2 "ext_register_operand" "Q")
7400 (clobber (reg:CC FLAGS_REG))]
7402 "add{b}\t{%h2, %h0|%h0, %h2}"
7403 [(set_attr "type" "alu")
7404 (set_attr "mode" "QI")])
7406 ;; The lea patterns for non-Pmodes needs to be matched by
7407 ;; several insns converted to real lea by splitters.
7409 (define_insn_and_split "*lea_general_1"
7410 [(set (match_operand 0 "register_operand" "=r")
7411 (plus (plus (match_operand 1 "index_register_operand" "l")
7412 (match_operand 2 "register_operand" "r"))
7413 (match_operand 3 "immediate_operand" "i")))]
7414 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7415 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7416 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7417 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7418 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7419 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7420 || GET_MODE (operands[3]) == VOIDmode)"
7422 "&& reload_completed"
7426 operands[0] = gen_lowpart (SImode, operands[0]);
7427 operands[1] = gen_lowpart (Pmode, operands[1]);
7428 operands[2] = gen_lowpart (Pmode, operands[2]);
7429 operands[3] = gen_lowpart (Pmode, operands[3]);
7430 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7432 if (Pmode != SImode)
7433 pat = gen_rtx_SUBREG (SImode, pat, 0);
7434 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7437 [(set_attr "type" "lea")
7438 (set_attr "mode" "SI")])
7440 (define_insn_and_split "*lea_general_1_zext"
7441 [(set (match_operand:DI 0 "register_operand" "=r")
7444 (match_operand:SI 1 "index_register_operand" "l")
7445 (match_operand:SI 2 "register_operand" "r"))
7446 (match_operand:SI 3 "immediate_operand" "i"))))]
7449 "&& reload_completed"
7451 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7453 (match_dup 3)) 0)))]
7455 operands[1] = gen_lowpart (Pmode, operands[1]);
7456 operands[2] = gen_lowpart (Pmode, operands[2]);
7457 operands[3] = gen_lowpart (Pmode, operands[3]);
7459 [(set_attr "type" "lea")
7460 (set_attr "mode" "SI")])
7462 (define_insn_and_split "*lea_general_2"
7463 [(set (match_operand 0 "register_operand" "=r")
7464 (plus (mult (match_operand 1 "index_register_operand" "l")
7465 (match_operand 2 "const248_operand" "i"))
7466 (match_operand 3 "nonmemory_operand" "ri")))]
7467 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7468 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7469 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7470 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7471 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7472 || GET_MODE (operands[3]) == VOIDmode)"
7474 "&& reload_completed"
7478 operands[0] = gen_lowpart (SImode, operands[0]);
7479 operands[1] = gen_lowpart (Pmode, operands[1]);
7480 operands[3] = gen_lowpart (Pmode, operands[3]);
7481 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7483 if (Pmode != SImode)
7484 pat = gen_rtx_SUBREG (SImode, pat, 0);
7485 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7488 [(set_attr "type" "lea")
7489 (set_attr "mode" "SI")])
7491 (define_insn_and_split "*lea_general_2_zext"
7492 [(set (match_operand:DI 0 "register_operand" "=r")
7495 (match_operand:SI 1 "index_register_operand" "l")
7496 (match_operand:SI 2 "const248_operand" "n"))
7497 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7500 "&& reload_completed"
7502 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7504 (match_dup 3)) 0)))]
7506 operands[1] = gen_lowpart (Pmode, operands[1]);
7507 operands[3] = gen_lowpart (Pmode, operands[3]);
7509 [(set_attr "type" "lea")
7510 (set_attr "mode" "SI")])
7512 (define_insn_and_split "*lea_general_3"
7513 [(set (match_operand 0 "register_operand" "=r")
7514 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7515 (match_operand 2 "const248_operand" "i"))
7516 (match_operand 3 "register_operand" "r"))
7517 (match_operand 4 "immediate_operand" "i")))]
7518 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7519 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7520 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7521 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7522 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7524 "&& reload_completed"
7528 operands[0] = gen_lowpart (SImode, operands[0]);
7529 operands[1] = gen_lowpart (Pmode, operands[1]);
7530 operands[3] = gen_lowpart (Pmode, operands[3]);
7531 operands[4] = gen_lowpart (Pmode, operands[4]);
7532 pat = gen_rtx_PLUS (Pmode,
7533 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7537 if (Pmode != SImode)
7538 pat = gen_rtx_SUBREG (SImode, pat, 0);
7539 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7542 [(set_attr "type" "lea")
7543 (set_attr "mode" "SI")])
7545 (define_insn_and_split "*lea_general_3_zext"
7546 [(set (match_operand:DI 0 "register_operand" "=r")
7550 (match_operand:SI 1 "index_register_operand" "l")
7551 (match_operand:SI 2 "const248_operand" "n"))
7552 (match_operand:SI 3 "register_operand" "r"))
7553 (match_operand:SI 4 "immediate_operand" "i"))))]
7556 "&& reload_completed"
7558 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7561 (match_dup 4)) 0)))]
7563 operands[1] = gen_lowpart (Pmode, operands[1]);
7564 operands[3] = gen_lowpart (Pmode, operands[3]);
7565 operands[4] = gen_lowpart (Pmode, operands[4]);
7567 [(set_attr "type" "lea")
7568 (set_attr "mode" "SI")])
7570 ;; Convert lea to the lea pattern to avoid flags dependency.
7572 [(set (match_operand:DI 0 "register_operand" "")
7573 (plus:DI (match_operand:DI 1 "register_operand" "")
7574 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7575 (clobber (reg:CC FLAGS_REG))]
7576 "TARGET_64BIT && reload_completed
7577 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7579 (plus:DI (match_dup 1)
7583 ;; Convert lea to the lea pattern to avoid flags dependency.
7585 [(set (match_operand 0 "register_operand" "")
7586 (plus (match_operand 1 "register_operand" "")
7587 (match_operand 2 "nonmemory_operand" "")))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7593 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7594 may confuse gen_lowpart. */
7595 if (GET_MODE (operands[0]) != Pmode)
7597 operands[1] = gen_lowpart (Pmode, operands[1]);
7598 operands[2] = gen_lowpart (Pmode, operands[2]);
7600 operands[0] = gen_lowpart (SImode, operands[0]);
7601 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7602 if (Pmode != SImode)
7603 pat = gen_rtx_SUBREG (SImode, pat, 0);
7604 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7608 ;; Convert lea to the lea pattern to avoid flags dependency.
7610 [(set (match_operand:DI 0 "register_operand" "")
7612 (plus:SI (match_operand:SI 1 "register_operand" "")
7613 (match_operand:SI 2 "nonmemory_operand" ""))))
7614 (clobber (reg:CC FLAGS_REG))]
7615 "TARGET_64BIT && reload_completed
7616 && true_regnum (operands[0]) != true_regnum (operands[1])"
7618 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7620 operands[1] = gen_lowpart (Pmode, operands[1]);
7621 operands[2] = gen_lowpart (Pmode, operands[2]);
7624 ;; Subtract instructions
7626 (define_expand "sub<mode>3"
7627 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7628 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7629 (match_operand:SDWIM 2 "<general_operand>" "")))]
7631 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7633 (define_insn_and_split "*sub<dwi>3_doubleword"
7634 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7636 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7637 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7638 (clobber (reg:CC FLAGS_REG))]
7639 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7642 [(parallel [(set (reg:CC FLAGS_REG)
7643 (compare:CC (match_dup 1) (match_dup 2)))
7645 (minus:DWIH (match_dup 1) (match_dup 2)))])
7646 (parallel [(set (match_dup 3)
7650 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7652 (clobber (reg:CC FLAGS_REG))])]
7653 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7655 (define_insn "sub<mode>3_carry"
7656 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7658 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7660 (match_operand:SWI 3 "ix86_carry_flag_operator" "")
7661 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7662 (clobber (reg:CC FLAGS_REG))]
7663 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7664 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7665 [(set_attr "type" "alu")
7666 (set_attr "use_carry" "1")
7667 (set_attr "pent_pair" "pu")
7668 (set_attr "mode" "<MODE>")])
7670 (define_insn "*subsi3_carry_zext"
7671 [(set (match_operand:DI 0 "register_operand" "=r")
7673 (minus:SI (match_operand:SI 1 "register_operand" "0")
7674 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7675 (match_operand:SI 2 "general_operand" "g")))))
7676 (clobber (reg:CC FLAGS_REG))]
7677 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7678 "sbb{l}\t{%2, %k0|%k0, %2}"
7679 [(set_attr "type" "alu")
7680 (set_attr "pent_pair" "pu")
7681 (set_attr "mode" "SI")])
7683 (define_insn "*sub<mode>3_cconly_overflow"
7684 [(set (reg:CCC FLAGS_REG)
7687 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7688 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7691 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7692 [(set_attr "type" "icmp")
7693 (set_attr "mode" "<MODE>")])
7695 (define_insn "*sub<mode>_1"
7696 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7698 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7699 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7700 (clobber (reg:CC FLAGS_REG))]
7701 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "alu")
7704 (set_attr "mode" "<MODE>")])
7706 (define_insn "*subsi_1_zext"
7707 [(set (match_operand:DI 0 "register_operand" "=r")
7709 (minus:SI (match_operand:SI 1 "register_operand" "0")
7710 (match_operand:SI 2 "general_operand" "g"))))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7713 "sub{l}\t{%2, %k0|%k0, %2}"
7714 [(set_attr "type" "alu")
7715 (set_attr "mode" "SI")])
7717 (define_insn "*subqi_1_slp"
7718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7719 (minus:QI (match_dup 0)
7720 (match_operand:QI 1 "general_operand" "qn,qm")))
7721 (clobber (reg:CC FLAGS_REG))]
7722 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7723 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7724 "sub{b}\t{%1, %0|%0, %1}"
7725 [(set_attr "type" "alu1")
7726 (set_attr "mode" "QI")])
7728 (define_insn "*sub<mode>_2"
7729 [(set (reg FLAGS_REG)
7732 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7733 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7735 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7736 (minus:SWI (match_dup 1) (match_dup 2)))]
7737 "ix86_match_ccmode (insn, CCGOCmode)
7738 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7739 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7740 [(set_attr "type" "alu")
7741 (set_attr "mode" "<MODE>")])
7743 (define_insn "*subsi_2_zext"
7744 [(set (reg FLAGS_REG)
7746 (minus:SI (match_operand:SI 1 "register_operand" "0")
7747 (match_operand:SI 2 "general_operand" "g"))
7749 (set (match_operand:DI 0 "register_operand" "=r")
7751 (minus:SI (match_dup 1)
7753 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7754 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7755 "sub{l}\t{%2, %k0|%k0, %2}"
7756 [(set_attr "type" "alu")
7757 (set_attr "mode" "SI")])
7759 (define_insn "*sub<mode>_3"
7760 [(set (reg FLAGS_REG)
7761 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7762 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7763 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7764 (minus:SWI (match_dup 1) (match_dup 2)))]
7765 "ix86_match_ccmode (insn, CCmode)
7766 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7767 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7768 [(set_attr "type" "alu")
7769 (set_attr "mode" "<MODE>")])
7771 (define_insn "*subsi_3_zext"
7772 [(set (reg FLAGS_REG)
7773 (compare (match_operand:SI 1 "register_operand" "0")
7774 (match_operand:SI 2 "general_operand" "g")))
7775 (set (match_operand:DI 0 "register_operand" "=r")
7777 (minus:SI (match_dup 1)
7779 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7780 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7781 "sub{l}\t{%2, %1|%1, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "SI")])
7786 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7787 [(set (reg:CCC FLAGS_REG)
7790 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7791 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7793 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7794 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7795 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7796 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7797 [(set_attr "type" "alu")
7798 (set_attr "mode" "<MODE>")])
7800 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7801 [(set (reg:CCC FLAGS_REG)
7804 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7805 (match_operand:SI 2 "general_operand" "g"))
7807 (set (match_operand:DI 0 "register_operand" "=r")
7808 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7809 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7810 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7811 [(set_attr "type" "alu")
7812 (set_attr "mode" "SI")])
7814 ;; The patterns that match these are at the end of this file.
7816 (define_expand "<plusminus_insn>xf3"
7817 [(set (match_operand:XF 0 "register_operand" "")
7819 (match_operand:XF 1 "register_operand" "")
7820 (match_operand:XF 2 "register_operand" "")))]
7824 (define_expand "<plusminus_insn><mode>3"
7825 [(set (match_operand:MODEF 0 "register_operand" "")
7827 (match_operand:MODEF 1 "register_operand" "")
7828 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7829 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7830 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7833 ;; Multiply instructions
7835 (define_expand "mul<mode>3"
7836 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7838 (match_operand:SWIM248 1 "register_operand" "")
7839 (match_operand:SWIM248 2 "<general_operand>" "")))
7840 (clobber (reg:CC FLAGS_REG))])]
7844 (define_expand "mulqi3"
7845 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7847 (match_operand:QI 1 "register_operand" "")
7848 (match_operand:QI 2 "nonimmediate_operand" "")))
7849 (clobber (reg:CC FLAGS_REG))])]
7850 "TARGET_QIMODE_MATH"
7854 ;; IMUL reg32/64, reg32/64, imm8 Direct
7855 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7856 ;; IMUL reg32/64, reg32/64, imm32 Direct
7857 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7858 ;; IMUL reg32/64, reg32/64 Direct
7859 ;; IMUL reg32/64, mem32/64 Direct
7861 (define_insn "*mul<mode>3_1"
7862 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7864 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7865 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7869 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7870 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7871 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7872 [(set_attr "type" "imul")
7873 (set_attr "prefix_0f" "0,0,1")
7874 (set (attr "athlon_decode")
7875 (cond [(eq_attr "cpu" "athlon")
7876 (const_string "vector")
7877 (eq_attr "alternative" "1")
7878 (const_string "vector")
7879 (and (eq_attr "alternative" "2")
7880 (match_operand 1 "memory_operand" ""))
7881 (const_string "vector")]
7882 (const_string "direct")))
7883 (set (attr "amdfam10_decode")
7884 (cond [(and (eq_attr "alternative" "0,1")
7885 (match_operand 1 "memory_operand" ""))
7886 (const_string "vector")]
7887 (const_string "direct")))
7888 (set_attr "mode" "<MODE>")])
7890 (define_insn "*mulsi3_1_zext"
7891 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7893 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7894 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7895 (clobber (reg:CC FLAGS_REG))]
7897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7899 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7900 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7901 imul{l}\t{%2, %k0|%k0, %2}"
7902 [(set_attr "type" "imul")
7903 (set_attr "prefix_0f" "0,0,1")
7904 (set (attr "athlon_decode")
7905 (cond [(eq_attr "cpu" "athlon")
7906 (const_string "vector")
7907 (eq_attr "alternative" "1")
7908 (const_string "vector")
7909 (and (eq_attr "alternative" "2")
7910 (match_operand 1 "memory_operand" ""))
7911 (const_string "vector")]
7912 (const_string "direct")))
7913 (set (attr "amdfam10_decode")
7914 (cond [(and (eq_attr "alternative" "0,1")
7915 (match_operand 1 "memory_operand" ""))
7916 (const_string "vector")]
7917 (const_string "direct")))
7918 (set_attr "mode" "SI")])
7921 ;; IMUL reg16, reg16, imm8 VectorPath
7922 ;; IMUL reg16, mem16, imm8 VectorPath
7923 ;; IMUL reg16, reg16, imm16 VectorPath
7924 ;; IMUL reg16, mem16, imm16 VectorPath
7925 ;; IMUL reg16, reg16 Direct
7926 ;; IMUL reg16, mem16 Direct
7928 (define_insn "*mulhi3_1"
7929 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7930 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7931 (match_operand:HI 2 "general_operand" "K,n,mr")))
7932 (clobber (reg:CC FLAGS_REG))]
7934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7936 imul{w}\t{%2, %1, %0|%0, %1, %2}
7937 imul{w}\t{%2, %1, %0|%0, %1, %2}
7938 imul{w}\t{%2, %0|%0, %2}"
7939 [(set_attr "type" "imul")
7940 (set_attr "prefix_0f" "0,0,1")
7941 (set (attr "athlon_decode")
7942 (cond [(eq_attr "cpu" "athlon")
7943 (const_string "vector")
7944 (eq_attr "alternative" "1,2")
7945 (const_string "vector")]
7946 (const_string "direct")))
7947 (set (attr "amdfam10_decode")
7948 (cond [(eq_attr "alternative" "0,1")
7949 (const_string "vector")]
7950 (const_string "direct")))
7951 (set_attr "mode" "HI")])
7957 (define_insn "*mulqi3_1"
7958 [(set (match_operand:QI 0 "register_operand" "=a")
7959 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7960 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7961 (clobber (reg:CC FLAGS_REG))]
7963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7965 [(set_attr "type" "imul")
7966 (set_attr "length_immediate" "0")
7967 (set (attr "athlon_decode")
7968 (if_then_else (eq_attr "cpu" "athlon")
7969 (const_string "vector")
7970 (const_string "direct")))
7971 (set_attr "amdfam10_decode" "direct")
7972 (set_attr "mode" "QI")])
7974 (define_expand "<u>mul<mode><dwi>3"
7975 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7978 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7980 (match_operand:DWIH 2 "register_operand" ""))))
7981 (clobber (reg:CC FLAGS_REG))])]
7985 (define_expand "<u>mulqihi3"
7986 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7989 (match_operand:QI 1 "nonimmediate_operand" ""))
7991 (match_operand:QI 2 "register_operand" ""))))
7992 (clobber (reg:CC FLAGS_REG))])]
7993 "TARGET_QIMODE_MATH"
7996 (define_insn "*<u>mul<mode><dwi>3_1"
7997 [(set (match_operand:<DWI> 0 "register_operand" "=A")
8000 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
8002 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 "<sgnprefix>mul{<imodesuffix>}\t%2"
8006 [(set_attr "type" "imul")
8007 (set_attr "length_immediate" "0")
8008 (set (attr "athlon_decode")
8009 (if_then_else (eq_attr "cpu" "athlon")
8010 (const_string "vector")
8011 (const_string "double")))
8012 (set_attr "amdfam10_decode" "double")
8013 (set_attr "mode" "<MODE>")])
8015 (define_insn "*<u>mulqihi3_1"
8016 [(set (match_operand:HI 0 "register_operand" "=a")
8019 (match_operand:QI 1 "nonimmediate_operand" "%0"))
8021 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8022 (clobber (reg:CC FLAGS_REG))]
8024 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8025 "<sgnprefix>mul{b}\t%2"
8026 [(set_attr "type" "imul")
8027 (set_attr "length_immediate" "0")
8028 (set (attr "athlon_decode")
8029 (if_then_else (eq_attr "cpu" "athlon")
8030 (const_string "vector")
8031 (const_string "direct")))
8032 (set_attr "amdfam10_decode" "direct")
8033 (set_attr "mode" "QI")])
8035 (define_expand "<s>mul<mode>3_highpart"
8036 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
8041 (match_operand:SWI48 1 "nonimmediate_operand" ""))
8043 (match_operand:SWI48 2 "register_operand" "")))
8045 (clobber (match_scratch:SWI48 3 ""))
8046 (clobber (reg:CC FLAGS_REG))])]
8048 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8050 (define_insn "*<s>muldi3_highpart_1"
8051 [(set (match_operand:DI 0 "register_operand" "=d")
8056 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8058 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8060 (clobber (match_scratch:DI 3 "=1"))
8061 (clobber (reg:CC FLAGS_REG))]
8063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8064 "<sgnprefix>mul{q}\t%2"
8065 [(set_attr "type" "imul")
8066 (set_attr "length_immediate" "0")
8067 (set (attr "athlon_decode")
8068 (if_then_else (eq_attr "cpu" "athlon")
8069 (const_string "vector")
8070 (const_string "double")))
8071 (set_attr "amdfam10_decode" "double")
8072 (set_attr "mode" "DI")])
8074 (define_insn "*<s>mulsi3_highpart_1"
8075 [(set (match_operand:SI 0 "register_operand" "=d")
8080 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8082 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8084 (clobber (match_scratch:SI 3 "=1"))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8087 "<sgnprefix>mul{l}\t%2"
8088 [(set_attr "type" "imul")
8089 (set_attr "length_immediate" "0")
8090 (set (attr "athlon_decode")
8091 (if_then_else (eq_attr "cpu" "athlon")
8092 (const_string "vector")
8093 (const_string "double")))
8094 (set_attr "amdfam10_decode" "double")
8095 (set_attr "mode" "SI")])
8097 (define_insn "*<s>mulsi3_highpart_zext"
8098 [(set (match_operand:DI 0 "register_operand" "=d")
8099 (zero_extend:DI (truncate:SI
8101 (mult:DI (any_extend:DI
8102 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8104 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8106 (clobber (match_scratch:SI 3 "=1"))
8107 (clobber (reg:CC FLAGS_REG))]
8109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8110 "<sgnprefix>mul{l}\t%2"
8111 [(set_attr "type" "imul")
8112 (set_attr "length_immediate" "0")
8113 (set (attr "athlon_decode")
8114 (if_then_else (eq_attr "cpu" "athlon")
8115 (const_string "vector")
8116 (const_string "double")))
8117 (set_attr "amdfam10_decode" "double")
8118 (set_attr "mode" "SI")])
8120 ;; The patterns that match these are at the end of this file.
8122 (define_expand "mulxf3"
8123 [(set (match_operand:XF 0 "register_operand" "")
8124 (mult:XF (match_operand:XF 1 "register_operand" "")
8125 (match_operand:XF 2 "register_operand" "")))]
8129 (define_expand "mul<mode>3"
8130 [(set (match_operand:MODEF 0 "register_operand" "")
8131 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8132 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8133 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8134 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8137 ;; Divide instructions
8139 (define_insn "<u>divqi3"
8140 [(set (match_operand:QI 0 "register_operand" "=a")
8142 (match_operand:HI 1 "register_operand" "0")
8143 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8144 (clobber (reg:CC FLAGS_REG))]
8145 "TARGET_QIMODE_MATH"
8146 "<sgnprefix>div{b}\t%2"
8147 [(set_attr "type" "idiv")
8148 (set_attr "mode" "QI")])
8150 ;; The patterns that match these are at the end of this file.
8152 (define_expand "divxf3"
8153 [(set (match_operand:XF 0 "register_operand" "")
8154 (div:XF (match_operand:XF 1 "register_operand" "")
8155 (match_operand:XF 2 "register_operand" "")))]
8159 (define_expand "divdf3"
8160 [(set (match_operand:DF 0 "register_operand" "")
8161 (div:DF (match_operand:DF 1 "register_operand" "")
8162 (match_operand:DF 2 "nonimmediate_operand" "")))]
8163 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8164 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8167 (define_expand "divsf3"
8168 [(set (match_operand:SF 0 "register_operand" "")
8169 (div:SF (match_operand:SF 1 "register_operand" "")
8170 (match_operand:SF 2 "nonimmediate_operand" "")))]
8171 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8174 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8175 && flag_finite_math_only && !flag_trapping_math
8176 && flag_unsafe_math_optimizations)
8178 ix86_emit_swdivsf (operands[0], operands[1],
8179 operands[2], SFmode);
8184 ;; Divmod instructions.
8186 (define_expand "divmod<mode>4"
8187 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8189 (match_operand:SWIM248 1 "register_operand" "")
8190 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8191 (set (match_operand:SWIM248 3 "register_operand" "")
8192 (mod:SWIM248 (match_dup 1) (match_dup 2)))
8193 (clobber (reg:CC FLAGS_REG))])]
8197 (define_insn_and_split "*divmod<mode>4"
8198 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8199 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8200 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8201 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8202 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8203 (clobber (reg:CC FLAGS_REG))]
8206 "&& reload_completed"
8207 [(parallel [(set (match_dup 1)
8208 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8209 (clobber (reg:CC FLAGS_REG))])
8210 (parallel [(set (match_dup 0)
8211 (div:SWIM248 (match_dup 2) (match_dup 3)))
8213 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8215 (clobber (reg:CC FLAGS_REG))])]
8217 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8219 if (<MODE>mode != HImode
8220 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8221 operands[4] = operands[2];
8224 /* Avoid use of cltd in favor of a mov+shift. */
8225 emit_move_insn (operands[1], operands[2]);
8226 operands[4] = operands[1];
8229 [(set_attr "type" "multi")
8230 (set_attr "mode" "<MODE>")])
8232 (define_insn "*divmod<mode>4_noext"
8233 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8234 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8235 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8236 (set (match_operand:SWIM248 1 "register_operand" "=d")
8237 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8238 (use (match_operand:SWIM248 4 "register_operand" "1"))
8239 (clobber (reg:CC FLAGS_REG))]
8241 "idiv{<imodesuffix>}\t%3"
8242 [(set_attr "type" "idiv")
8243 (set_attr "mode" "<MODE>")])
8245 (define_expand "udivmod<mode>4"
8246 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8248 (match_operand:SWIM248 1 "register_operand" "")
8249 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8250 (set (match_operand:SWIM248 3 "register_operand" "")
8251 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8252 (clobber (reg:CC FLAGS_REG))])]
8256 (define_insn_and_split "*udivmod<mode>4"
8257 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8258 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8259 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8260 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8261 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8262 (clobber (reg:CC FLAGS_REG))]
8265 "&& reload_completed"
8266 [(set (match_dup 1) (const_int 0))
8267 (parallel [(set (match_dup 0)
8268 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8270 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8272 (clobber (reg:CC FLAGS_REG))])]
8274 [(set_attr "type" "multi")
8275 (set_attr "mode" "<MODE>")])
8277 (define_insn "*udivmod<mode>4_noext"
8278 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8279 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8280 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8281 (set (match_operand:SWIM248 1 "register_operand" "=d")
8282 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8283 (use (match_operand:SWIM248 4 "register_operand" "1"))
8284 (clobber (reg:CC FLAGS_REG))]
8286 "div{<imodesuffix>}\t%3"
8287 [(set_attr "type" "idiv")
8288 (set_attr "mode" "<MODE>")])
8290 ;; We cannot use div/idiv for double division, because it causes
8291 ;; "division by zero" on the overflow and that's not what we expect
8292 ;; from truncate. Because true (non truncating) double division is
8293 ;; never generated, we can't create this insn anyway.
8296 ; [(set (match_operand:SI 0 "register_operand" "=a")
8298 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8300 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8301 ; (set (match_operand:SI 3 "register_operand" "=d")
8303 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8304 ; (clobber (reg:CC FLAGS_REG))]
8306 ; "div{l}\t{%2, %0|%0, %2}"
8307 ; [(set_attr "type" "idiv")])
8309 ;;- Logical AND instructions
8311 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8312 ;; Note that this excludes ah.
8314 (define_insn "*testdi_1_rex64"
8315 [(set (reg FLAGS_REG)
8317 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8318 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8320 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8321 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8323 test{l}\t{%k1, %k0|%k0, %k1}
8324 test{l}\t{%k1, %k0|%k0, %k1}
8325 test{q}\t{%1, %0|%0, %1}
8326 test{q}\t{%1, %0|%0, %1}
8327 test{q}\t{%1, %0|%0, %1}"
8328 [(set_attr "type" "test")
8329 (set_attr "modrm" "0,1,0,1,1")
8330 (set_attr "mode" "SI,SI,DI,DI,DI")
8331 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8333 (define_insn "testsi_1"
8334 [(set (reg FLAGS_REG)
8336 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8337 (match_operand:SI 1 "general_operand" "i,i,ri"))
8339 "ix86_match_ccmode (insn, CCNOmode)
8340 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8341 "test{l}\t{%1, %0|%0, %1}"
8342 [(set_attr "type" "test")
8343 (set_attr "modrm" "0,1,1")
8344 (set_attr "mode" "SI")
8345 (set_attr "pent_pair" "uv,np,uv")])
8347 (define_expand "testsi_ccno_1"
8348 [(set (reg:CCNO FLAGS_REG)
8350 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8351 (match_operand:SI 1 "nonmemory_operand" ""))
8356 (define_insn "*testhi_1"
8357 [(set (reg FLAGS_REG)
8358 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8359 (match_operand:HI 1 "general_operand" "n,n,rn"))
8361 "ix86_match_ccmode (insn, CCNOmode)
8362 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8363 "test{w}\t{%1, %0|%0, %1}"
8364 [(set_attr "type" "test")
8365 (set_attr "modrm" "0,1,1")
8366 (set_attr "mode" "HI")
8367 (set_attr "pent_pair" "uv,np,uv")])
8369 (define_expand "testqi_ccz_1"
8370 [(set (reg:CCZ FLAGS_REG)
8371 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8372 (match_operand:QI 1 "nonmemory_operand" ""))
8377 (define_insn "*testqi_1_maybe_si"
8378 [(set (reg FLAGS_REG)
8381 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8382 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8384 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8385 && ix86_match_ccmode (insn,
8386 CONST_INT_P (operands[1])
8387 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8389 if (which_alternative == 3)
8391 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8392 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8393 return "test{l}\t{%1, %k0|%k0, %1}";
8395 return "test{b}\t{%1, %0|%0, %1}";
8397 [(set_attr "type" "test")
8398 (set_attr "modrm" "0,1,1,1")
8399 (set_attr "mode" "QI,QI,QI,SI")
8400 (set_attr "pent_pair" "uv,np,uv,np")])
8402 (define_insn "*testqi_1"
8403 [(set (reg FLAGS_REG)
8406 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8407 (match_operand:QI 1 "general_operand" "n,n,qn"))
8409 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8410 && ix86_match_ccmode (insn, CCNOmode)"
8411 "test{b}\t{%1, %0|%0, %1}"
8412 [(set_attr "type" "test")
8413 (set_attr "modrm" "0,1,1")
8414 (set_attr "mode" "QI")
8415 (set_attr "pent_pair" "uv,np,uv")])
8417 (define_expand "testqi_ext_ccno_0"
8418 [(set (reg:CCNO FLAGS_REG)
8422 (match_operand 0 "ext_register_operand" "")
8425 (match_operand 1 "const_int_operand" ""))
8430 (define_insn "*testqi_ext_0"
8431 [(set (reg FLAGS_REG)
8435 (match_operand 0 "ext_register_operand" "Q")
8438 (match_operand 1 "const_int_operand" "n"))
8440 "ix86_match_ccmode (insn, CCNOmode)"
8441 "test{b}\t{%1, %h0|%h0, %1}"
8442 [(set_attr "type" "test")
8443 (set_attr "mode" "QI")
8444 (set_attr "length_immediate" "1")
8445 (set_attr "modrm" "1")
8446 (set_attr "pent_pair" "np")])
8448 (define_insn "*testqi_ext_1"
8449 [(set (reg FLAGS_REG)
8453 (match_operand 0 "ext_register_operand" "Q")
8457 (match_operand:QI 1 "general_operand" "Qm")))
8459 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8461 "test{b}\t{%1, %h0|%h0, %1}"
8462 [(set_attr "type" "test")
8463 (set_attr "mode" "QI")])
8465 (define_insn "*testqi_ext_1_rex64"
8466 [(set (reg FLAGS_REG)
8470 (match_operand 0 "ext_register_operand" "Q")
8474 (match_operand:QI 1 "register_operand" "Q")))
8476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8477 "test{b}\t{%1, %h0|%h0, %1}"
8478 [(set_attr "type" "test")
8479 (set_attr "mode" "QI")])
8481 (define_insn "*testqi_ext_2"
8482 [(set (reg FLAGS_REG)
8486 (match_operand 0 "ext_register_operand" "Q")
8490 (match_operand 1 "ext_register_operand" "Q")
8494 "ix86_match_ccmode (insn, CCNOmode)"
8495 "test{b}\t{%h1, %h0|%h0, %h1}"
8496 [(set_attr "type" "test")
8497 (set_attr "mode" "QI")])
8499 ;; Combine likes to form bit extractions for some tests. Humor it.
8500 (define_insn "*testqi_ext_3"
8501 [(set (reg FLAGS_REG)
8502 (compare (zero_extract:SI
8503 (match_operand 0 "nonimmediate_operand" "rm")
8504 (match_operand:SI 1 "const_int_operand" "")
8505 (match_operand:SI 2 "const_int_operand" ""))
8507 "ix86_match_ccmode (insn, CCNOmode)
8508 && INTVAL (operands[1]) > 0
8509 && INTVAL (operands[2]) >= 0
8510 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8511 && (GET_MODE (operands[0]) == SImode
8512 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8513 || GET_MODE (operands[0]) == HImode
8514 || GET_MODE (operands[0]) == QImode)"
8517 (define_insn "*testqi_ext_3_rex64"
8518 [(set (reg FLAGS_REG)
8519 (compare (zero_extract:DI
8520 (match_operand 0 "nonimmediate_operand" "rm")
8521 (match_operand:DI 1 "const_int_operand" "")
8522 (match_operand:DI 2 "const_int_operand" ""))
8525 && ix86_match_ccmode (insn, CCNOmode)
8526 && INTVAL (operands[1]) > 0
8527 && INTVAL (operands[2]) >= 0
8528 /* Ensure that resulting mask is zero or sign extended operand. */
8529 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8530 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8531 && INTVAL (operands[1]) > 32))
8532 && (GET_MODE (operands[0]) == SImode
8533 || GET_MODE (operands[0]) == DImode
8534 || GET_MODE (operands[0]) == HImode
8535 || GET_MODE (operands[0]) == QImode)"
8539 [(set (match_operand 0 "flags_reg_operand" "")
8540 (match_operator 1 "compare_operator"
8542 (match_operand 2 "nonimmediate_operand" "")
8543 (match_operand 3 "const_int_operand" "")
8544 (match_operand 4 "const_int_operand" ""))
8546 "ix86_match_ccmode (insn, CCNOmode)"
8547 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8549 rtx val = operands[2];
8550 HOST_WIDE_INT len = INTVAL (operands[3]);
8551 HOST_WIDE_INT pos = INTVAL (operands[4]);
8553 enum machine_mode mode, submode;
8555 mode = GET_MODE (val);
8558 /* ??? Combine likes to put non-volatile mem extractions in QImode
8559 no matter the size of the test. So find a mode that works. */
8560 if (! MEM_VOLATILE_P (val))
8562 mode = smallest_mode_for_size (pos + len, MODE_INT);
8563 val = adjust_address (val, mode, 0);
8566 else if (GET_CODE (val) == SUBREG
8567 && (submode = GET_MODE (SUBREG_REG (val)),
8568 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8569 && pos + len <= GET_MODE_BITSIZE (submode))
8571 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8573 val = SUBREG_REG (val);
8575 else if (mode == HImode && pos + len <= 8)
8577 /* Small HImode tests can be converted to QImode. */
8579 val = gen_lowpart (QImode, val);
8582 if (len == HOST_BITS_PER_WIDE_INT)
8585 mask = ((HOST_WIDE_INT)1 << len) - 1;
8588 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8591 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8592 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8593 ;; this is relatively important trick.
8594 ;; Do the conversion only post-reload to avoid limiting of the register class
8597 [(set (match_operand 0 "flags_reg_operand" "")
8598 (match_operator 1 "compare_operator"
8599 [(and (match_operand 2 "register_operand" "")
8600 (match_operand 3 "const_int_operand" ""))
8603 && QI_REG_P (operands[2])
8604 && GET_MODE (operands[2]) != QImode
8605 && ((ix86_match_ccmode (insn, CCZmode)
8606 && !(INTVAL (operands[3]) & ~(255 << 8)))
8607 || (ix86_match_ccmode (insn, CCNOmode)
8608 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8611 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8614 "operands[2] = gen_lowpart (SImode, operands[2]);
8615 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8618 [(set (match_operand 0 "flags_reg_operand" "")
8619 (match_operator 1 "compare_operator"
8620 [(and (match_operand 2 "nonimmediate_operand" "")
8621 (match_operand 3 "const_int_operand" ""))
8624 && GET_MODE (operands[2]) != QImode
8625 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8626 && ((ix86_match_ccmode (insn, CCZmode)
8627 && !(INTVAL (operands[3]) & ~255))
8628 || (ix86_match_ccmode (insn, CCNOmode)
8629 && !(INTVAL (operands[3]) & ~127)))"
8631 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8633 "operands[2] = gen_lowpart (QImode, operands[2]);
8634 operands[3] = gen_lowpart (QImode, operands[3]);")
8637 ;; %%% This used to optimize known byte-wide and operations to memory,
8638 ;; and sometimes to QImode registers. If this is considered useful,
8639 ;; it should be done with splitters.
8641 (define_expand "anddi3"
8642 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8643 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8644 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8646 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8648 (define_insn "*anddi_1_rex64"
8649 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8650 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8651 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8652 (clobber (reg:CC FLAGS_REG))]
8653 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8655 switch (get_attr_type (insn))
8659 enum machine_mode mode;
8661 gcc_assert (CONST_INT_P (operands[2]));
8662 if (INTVAL (operands[2]) == 0xff)
8666 gcc_assert (INTVAL (operands[2]) == 0xffff);
8670 operands[1] = gen_lowpart (mode, operands[1]);
8672 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8674 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8679 if (get_attr_mode (insn) == MODE_SI)
8680 return "and{l}\t{%k2, %k0|%k0, %k2}";
8682 return "and{q}\t{%2, %0|%0, %2}";
8685 [(set_attr "type" "alu,alu,alu,imovx")
8686 (set_attr "length_immediate" "*,*,*,0")
8687 (set (attr "prefix_rex")
8689 (and (eq_attr "type" "imovx")
8690 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8691 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8693 (const_string "*")))
8694 (set_attr "mode" "SI,DI,DI,SI")])
8696 (define_insn "*anddi_2"
8697 [(set (reg FLAGS_REG)
8698 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8699 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8701 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8702 (and:DI (match_dup 1) (match_dup 2)))]
8703 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8704 && ix86_binary_operator_ok (AND, DImode, operands)"
8706 and{l}\t{%k2, %k0|%k0, %k2}
8707 and{q}\t{%2, %0|%0, %2}
8708 and{q}\t{%2, %0|%0, %2}"
8709 [(set_attr "type" "alu")
8710 (set_attr "mode" "SI,DI,DI")])
8712 (define_expand "andsi3"
8713 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8714 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8715 (match_operand:SI 2 "general_operand" "")))]
8717 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8719 (define_insn "*andsi_1"
8720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8721 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8722 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8723 (clobber (reg:CC FLAGS_REG))]
8724 "ix86_binary_operator_ok (AND, SImode, operands)"
8726 switch (get_attr_type (insn))
8730 enum machine_mode mode;
8732 gcc_assert (CONST_INT_P (operands[2]));
8733 if (INTVAL (operands[2]) == 0xff)
8737 gcc_assert (INTVAL (operands[2]) == 0xffff);
8741 operands[1] = gen_lowpart (mode, operands[1]);
8743 return "movz{bl|x}\t{%1, %0|%0, %1}";
8745 return "movz{wl|x}\t{%1, %0|%0, %1}";
8749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8750 return "and{l}\t{%2, %0|%0, %2}";
8753 [(set_attr "type" "alu,alu,imovx")
8754 (set (attr "prefix_rex")
8756 (and (eq_attr "type" "imovx")
8757 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8758 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8760 (const_string "*")))
8761 (set_attr "length_immediate" "*,*,0")
8762 (set_attr "mode" "SI")])
8765 [(set (match_operand 0 "register_operand" "")
8767 (const_int -65536)))
8768 (clobber (reg:CC FLAGS_REG))]
8769 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8770 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8771 "operands[1] = gen_lowpart (HImode, operands[0]);")
8774 [(set (match_operand 0 "ext_register_operand" "")
8777 (clobber (reg:CC FLAGS_REG))]
8778 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8779 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8780 "operands[1] = gen_lowpart (QImode, operands[0]);")
8783 [(set (match_operand 0 "ext_register_operand" "")
8785 (const_int -65281)))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8788 [(parallel [(set (zero_extract:SI (match_dup 0)
8792 (zero_extract:SI (match_dup 0)
8795 (zero_extract:SI (match_dup 0)
8798 (clobber (reg:CC FLAGS_REG))])]
8799 "operands[0] = gen_lowpart (SImode, operands[0]);")
8801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8802 (define_insn "*andsi_1_zext"
8803 [(set (match_operand:DI 0 "register_operand" "=r")
8805 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8806 (match_operand:SI 2 "general_operand" "g"))))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8809 "and{l}\t{%2, %k0|%k0, %2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "mode" "SI")])
8813 (define_insn "*andsi_2"
8814 [(set (reg FLAGS_REG)
8815 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8816 (match_operand:SI 2 "general_operand" "g,ri"))
8818 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8819 (and:SI (match_dup 1) (match_dup 2)))]
8820 "ix86_match_ccmode (insn, CCNOmode)
8821 && ix86_binary_operator_ok (AND, SImode, operands)"
8822 "and{l}\t{%2, %0|%0, %2}"
8823 [(set_attr "type" "alu")
8824 (set_attr "mode" "SI")])
8826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8827 (define_insn "*andsi_2_zext"
8828 [(set (reg FLAGS_REG)
8829 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8830 (match_operand:SI 2 "general_operand" "g"))
8832 (set (match_operand:DI 0 "register_operand" "=r")
8833 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8834 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8835 && ix86_binary_operator_ok (AND, SImode, operands)"
8836 "and{l}\t{%2, %k0|%k0, %2}"
8837 [(set_attr "type" "alu")
8838 (set_attr "mode" "SI")])
8840 (define_expand "andhi3"
8841 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8842 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8843 (match_operand:HI 2 "general_operand" "")))]
8844 "TARGET_HIMODE_MATH"
8845 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8847 (define_insn "*andhi_1"
8848 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8849 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8850 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8851 (clobber (reg:CC FLAGS_REG))]
8852 "ix86_binary_operator_ok (AND, HImode, operands)"
8854 switch (get_attr_type (insn))
8857 gcc_assert (CONST_INT_P (operands[2]));
8858 gcc_assert (INTVAL (operands[2]) == 0xff);
8859 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8864 return "and{w}\t{%2, %0|%0, %2}";
8867 [(set_attr "type" "alu,alu,imovx")
8868 (set_attr "length_immediate" "*,*,0")
8869 (set (attr "prefix_rex")
8871 (and (eq_attr "type" "imovx")
8872 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8874 (const_string "*")))
8875 (set_attr "mode" "HI,HI,SI")])
8877 (define_insn "*andhi_2"
8878 [(set (reg FLAGS_REG)
8879 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8880 (match_operand:HI 2 "general_operand" "rmn,rn"))
8882 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8883 (and:HI (match_dup 1) (match_dup 2)))]
8884 "ix86_match_ccmode (insn, CCNOmode)
8885 && ix86_binary_operator_ok (AND, HImode, operands)"
8886 "and{w}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "HI")])
8890 (define_expand "andqi3"
8891 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8892 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8893 (match_operand:QI 2 "general_operand" "")))]
8894 "TARGET_QIMODE_MATH"
8895 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8897 ;; %%% Potential partial reg stall on alternative 2. What to do?
8898 (define_insn "*andqi_1"
8899 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8900 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8901 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8902 (clobber (reg:CC FLAGS_REG))]
8903 "ix86_binary_operator_ok (AND, QImode, operands)"
8905 and{b}\t{%2, %0|%0, %2}
8906 and{b}\t{%2, %0|%0, %2}
8907 and{l}\t{%k2, %k0|%k0, %k2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "mode" "QI,QI,SI")])
8911 (define_insn "*andqi_1_slp"
8912 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8913 (and:QI (match_dup 0)
8914 (match_operand:QI 1 "general_operand" "qn,qmn")))
8915 (clobber (reg:CC FLAGS_REG))]
8916 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8917 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8918 "and{b}\t{%1, %0|%0, %1}"
8919 [(set_attr "type" "alu1")
8920 (set_attr "mode" "QI")])
8922 (define_insn "*andqi_2_maybe_si"
8923 [(set (reg FLAGS_REG)
8925 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8926 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8928 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8929 (and:QI (match_dup 1) (match_dup 2)))]
8930 "ix86_binary_operator_ok (AND, QImode, operands)
8931 && ix86_match_ccmode (insn,
8932 CONST_INT_P (operands[2])
8933 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8935 if (which_alternative == 2)
8937 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8938 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8939 return "and{l}\t{%2, %k0|%k0, %2}";
8941 return "and{b}\t{%2, %0|%0, %2}";
8943 [(set_attr "type" "alu")
8944 (set_attr "mode" "QI,QI,SI")])
8946 (define_insn "*andqi_2"
8947 [(set (reg FLAGS_REG)
8949 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8950 (match_operand:QI 2 "general_operand" "qmn,qn"))
8952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8953 (and:QI (match_dup 1) (match_dup 2)))]
8954 "ix86_match_ccmode (insn, CCNOmode)
8955 && ix86_binary_operator_ok (AND, QImode, operands)"
8956 "and{b}\t{%2, %0|%0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "QI")])
8960 (define_insn "*andqi_2_slp"
8961 [(set (reg FLAGS_REG)
8963 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8964 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8966 (set (strict_low_part (match_dup 0))
8967 (and:QI (match_dup 0) (match_dup 1)))]
8968 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8969 && ix86_match_ccmode (insn, CCNOmode)
8970 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8971 "and{b}\t{%1, %0|%0, %1}"
8972 [(set_attr "type" "alu1")
8973 (set_attr "mode" "QI")])
8975 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8976 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8977 ;; for a QImode operand, which of course failed.
8979 (define_insn "andqi_ext_0"
8980 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8985 (match_operand 1 "ext_register_operand" "0")
8988 (match_operand 2 "const_int_operand" "n")))
8989 (clobber (reg:CC FLAGS_REG))]
8991 "and{b}\t{%2, %h0|%h0, %2}"
8992 [(set_attr "type" "alu")
8993 (set_attr "length_immediate" "1")
8994 (set_attr "modrm" "1")
8995 (set_attr "mode" "QI")])
8997 ;; Generated by peephole translating test to and. This shows up
8998 ;; often in fp comparisons.
9000 (define_insn "*andqi_ext_0_cc"
9001 [(set (reg FLAGS_REG)
9005 (match_operand 1 "ext_register_operand" "0")
9008 (match_operand 2 "const_int_operand" "n"))
9010 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9019 "ix86_match_ccmode (insn, CCNOmode)"
9020 "and{b}\t{%2, %h0|%h0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "length_immediate" "1")
9023 (set_attr "modrm" "1")
9024 (set_attr "mode" "QI")])
9026 (define_insn "*andqi_ext_1"
9027 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9032 (match_operand 1 "ext_register_operand" "0")
9036 (match_operand:QI 2 "general_operand" "Qm"))))
9037 (clobber (reg:CC FLAGS_REG))]
9039 "and{b}\t{%2, %h0|%h0, %2}"
9040 [(set_attr "type" "alu")
9041 (set_attr "length_immediate" "0")
9042 (set_attr "mode" "QI")])
9044 (define_insn "*andqi_ext_1_rex64"
9045 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9050 (match_operand 1 "ext_register_operand" "0")
9054 (match_operand 2 "ext_register_operand" "Q"))))
9055 (clobber (reg:CC FLAGS_REG))]
9057 "and{b}\t{%2, %h0|%h0, %2}"
9058 [(set_attr "type" "alu")
9059 (set_attr "length_immediate" "0")
9060 (set_attr "mode" "QI")])
9062 (define_insn "*andqi_ext_2"
9063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9068 (match_operand 1 "ext_register_operand" "%0")
9072 (match_operand 2 "ext_register_operand" "Q")
9075 (clobber (reg:CC FLAGS_REG))]
9077 "and{b}\t{%h2, %h0|%h0, %h2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "length_immediate" "0")
9080 (set_attr "mode" "QI")])
9082 ;; Convert wide AND instructions with immediate operand to shorter QImode
9083 ;; equivalents when possible.
9084 ;; Don't do the splitting with memory operands, since it introduces risk
9085 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9086 ;; for size, but that can (should?) be handled by generic code instead.
9088 [(set (match_operand 0 "register_operand" "")
9089 (and (match_operand 1 "register_operand" "")
9090 (match_operand 2 "const_int_operand" "")))
9091 (clobber (reg:CC FLAGS_REG))]
9093 && QI_REG_P (operands[0])
9094 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9095 && !(~INTVAL (operands[2]) & ~(255 << 8))
9096 && GET_MODE (operands[0]) != QImode"
9097 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9098 (and:SI (zero_extract:SI (match_dup 1)
9099 (const_int 8) (const_int 8))
9101 (clobber (reg:CC FLAGS_REG))])]
9102 "operands[0] = gen_lowpart (SImode, operands[0]);
9103 operands[1] = gen_lowpart (SImode, operands[1]);
9104 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9106 ;; Since AND can be encoded with sign extended immediate, this is only
9107 ;; profitable when 7th bit is not set.
9109 [(set (match_operand 0 "register_operand" "")
9110 (and (match_operand 1 "general_operand" "")
9111 (match_operand 2 "const_int_operand" "")))
9112 (clobber (reg:CC FLAGS_REG))]
9114 && ANY_QI_REG_P (operands[0])
9115 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9116 && !(~INTVAL (operands[2]) & ~255)
9117 && !(INTVAL (operands[2]) & 128)
9118 && GET_MODE (operands[0]) != QImode"
9119 [(parallel [(set (strict_low_part (match_dup 0))
9120 (and:QI (match_dup 1)
9122 (clobber (reg:CC FLAGS_REG))])]
9123 "operands[0] = gen_lowpart (QImode, operands[0]);
9124 operands[1] = gen_lowpart (QImode, operands[1]);
9125 operands[2] = gen_lowpart (QImode, operands[2]);")
9127 ;; Logical inclusive OR instructions
9129 ;; %%% This used to optimize known byte-wide and operations to memory.
9130 ;; If this is considered useful, it should be done with splitters.
9132 (define_expand "iordi3"
9133 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9134 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9135 (match_operand:DI 2 "x86_64_general_operand" "")))]
9137 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9139 (define_insn "*iordi_1_rex64"
9140 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9141 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9142 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9143 (clobber (reg:CC FLAGS_REG))]
9145 && ix86_binary_operator_ok (IOR, DImode, operands)"
9146 "or{q}\t{%2, %0|%0, %2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "mode" "DI")])
9150 (define_insn "*iordi_2_rex64"
9151 [(set (reg FLAGS_REG)
9152 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9153 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9155 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9156 (ior:DI (match_dup 1) (match_dup 2)))]
9158 && ix86_match_ccmode (insn, CCNOmode)
9159 && ix86_binary_operator_ok (IOR, DImode, operands)"
9160 "or{q}\t{%2, %0|%0, %2}"
9161 [(set_attr "type" "alu")
9162 (set_attr "mode" "DI")])
9164 (define_insn "*iordi_3_rex64"
9165 [(set (reg FLAGS_REG)
9166 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9167 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9169 (clobber (match_scratch:DI 0 "=r"))]
9171 && ix86_match_ccmode (insn, CCNOmode)
9172 && ix86_binary_operator_ok (IOR, DImode, operands)"
9173 "or{q}\t{%2, %0|%0, %2}"
9174 [(set_attr "type" "alu")
9175 (set_attr "mode" "DI")])
9178 (define_expand "iorsi3"
9179 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9180 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9181 (match_operand:SI 2 "general_operand" "")))]
9183 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9185 (define_insn "*iorsi_1"
9186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9187 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9188 (match_operand:SI 2 "general_operand" "ri,g")))
9189 (clobber (reg:CC FLAGS_REG))]
9190 "ix86_binary_operator_ok (IOR, SImode, operands)"
9191 "or{l}\t{%2, %0|%0, %2}"
9192 [(set_attr "type" "alu")
9193 (set_attr "mode" "SI")])
9195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9196 (define_insn "*iorsi_1_zext"
9197 [(set (match_operand:DI 0 "register_operand" "=r")
9199 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9200 (match_operand:SI 2 "general_operand" "g"))))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9203 "or{l}\t{%2, %k0|%k0, %2}"
9204 [(set_attr "type" "alu")
9205 (set_attr "mode" "SI")])
9207 (define_insn "*iorsi_1_zext_imm"
9208 [(set (match_operand:DI 0 "register_operand" "=r")
9209 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9210 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9211 (clobber (reg:CC FLAGS_REG))]
9213 "or{l}\t{%2, %k0|%k0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "mode" "SI")])
9217 (define_insn "*iorsi_2"
9218 [(set (reg FLAGS_REG)
9219 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9220 (match_operand:SI 2 "general_operand" "g,ri"))
9222 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9223 (ior:SI (match_dup 1) (match_dup 2)))]
9224 "ix86_match_ccmode (insn, CCNOmode)
9225 && ix86_binary_operator_ok (IOR, SImode, operands)"
9226 "or{l}\t{%2, %0|%0, %2}"
9227 [(set_attr "type" "alu")
9228 (set_attr "mode" "SI")])
9230 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9231 ;; ??? Special case for immediate operand is missing - it is tricky.
9232 (define_insn "*iorsi_2_zext"
9233 [(set (reg FLAGS_REG)
9234 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9235 (match_operand:SI 2 "general_operand" "g"))
9237 (set (match_operand:DI 0 "register_operand" "=r")
9238 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9240 && ix86_binary_operator_ok (IOR, SImode, operands)"
9241 "or{l}\t{%2, %k0|%k0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "mode" "SI")])
9245 (define_insn "*iorsi_2_zext_imm"
9246 [(set (reg FLAGS_REG)
9247 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9248 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9250 (set (match_operand:DI 0 "register_operand" "=r")
9251 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9252 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9253 && ix86_binary_operator_ok (IOR, SImode, operands)"
9254 "or{l}\t{%2, %k0|%k0, %2}"
9255 [(set_attr "type" "alu")
9256 (set_attr "mode" "SI")])
9258 (define_insn "*iorsi_3"
9259 [(set (reg FLAGS_REG)
9260 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9261 (match_operand:SI 2 "general_operand" "g"))
9263 (clobber (match_scratch:SI 0 "=r"))]
9264 "ix86_match_ccmode (insn, CCNOmode)
9265 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9266 "or{l}\t{%2, %0|%0, %2}"
9267 [(set_attr "type" "alu")
9268 (set_attr "mode" "SI")])
9270 (define_expand "iorhi3"
9271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9272 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9273 (match_operand:HI 2 "general_operand" "")))]
9274 "TARGET_HIMODE_MATH"
9275 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9277 (define_insn "*iorhi_1"
9278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9279 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9280 (match_operand:HI 2 "general_operand" "rmn,rn")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "ix86_binary_operator_ok (IOR, HImode, operands)"
9283 "or{w}\t{%2, %0|%0, %2}"
9284 [(set_attr "type" "alu")
9285 (set_attr "mode" "HI")])
9287 (define_insn "*iorhi_2"
9288 [(set (reg FLAGS_REG)
9289 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9290 (match_operand:HI 2 "general_operand" "rmn,rn"))
9292 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9293 (ior:HI (match_dup 1) (match_dup 2)))]
9294 "ix86_match_ccmode (insn, CCNOmode)
9295 && ix86_binary_operator_ok (IOR, HImode, operands)"
9296 "or{w}\t{%2, %0|%0, %2}"
9297 [(set_attr "type" "alu")
9298 (set_attr "mode" "HI")])
9300 (define_insn "*iorhi_3"
9301 [(set (reg FLAGS_REG)
9302 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9303 (match_operand:HI 2 "general_operand" "rmn"))
9305 (clobber (match_scratch:HI 0 "=r"))]
9306 "ix86_match_ccmode (insn, CCNOmode)
9307 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9308 "or{w}\t{%2, %0|%0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "HI")])
9312 (define_expand "iorqi3"
9313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9314 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9315 (match_operand:QI 2 "general_operand" "")))]
9316 "TARGET_QIMODE_MATH"
9317 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9319 ;; %%% Potential partial reg stall on alternative 2. What to do?
9320 (define_insn "*iorqi_1"
9321 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9322 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9323 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "ix86_binary_operator_ok (IOR, QImode, operands)"
9327 or{b}\t{%2, %0|%0, %2}
9328 or{b}\t{%2, %0|%0, %2}
9329 or{l}\t{%k2, %k0|%k0, %k2}"
9330 [(set_attr "type" "alu")
9331 (set_attr "mode" "QI,QI,SI")])
9333 (define_insn "*iorqi_1_slp"
9334 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9335 (ior:QI (match_dup 0)
9336 (match_operand:QI 1 "general_operand" "qmn,qn")))
9337 (clobber (reg:CC FLAGS_REG))]
9338 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9339 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9340 "or{b}\t{%1, %0|%0, %1}"
9341 [(set_attr "type" "alu1")
9342 (set_attr "mode" "QI")])
9344 (define_insn "*iorqi_2"
9345 [(set (reg FLAGS_REG)
9346 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9347 (match_operand:QI 2 "general_operand" "qmn,qn"))
9349 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9350 (ior:QI (match_dup 1) (match_dup 2)))]
9351 "ix86_match_ccmode (insn, CCNOmode)
9352 && ix86_binary_operator_ok (IOR, QImode, operands)"
9353 "or{b}\t{%2, %0|%0, %2}"
9354 [(set_attr "type" "alu")
9355 (set_attr "mode" "QI")])
9357 (define_insn "*iorqi_2_slp"
9358 [(set (reg FLAGS_REG)
9359 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9360 (match_operand:QI 1 "general_operand" "qmn,qn"))
9362 (set (strict_low_part (match_dup 0))
9363 (ior:QI (match_dup 0) (match_dup 1)))]
9364 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9365 && ix86_match_ccmode (insn, CCNOmode)
9366 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9367 "or{b}\t{%1, %0|%0, %1}"
9368 [(set_attr "type" "alu1")
9369 (set_attr "mode" "QI")])
9371 (define_insn "*iorqi_3"
9372 [(set (reg FLAGS_REG)
9373 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9374 (match_operand:QI 2 "general_operand" "qmn"))
9376 (clobber (match_scratch:QI 0 "=q"))]
9377 "ix86_match_ccmode (insn, CCNOmode)
9378 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9379 "or{b}\t{%2, %0|%0, %2}"
9380 [(set_attr "type" "alu")
9381 (set_attr "mode" "QI")])
9383 (define_insn "*iorqi_ext_0"
9384 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9389 (match_operand 1 "ext_register_operand" "0")
9392 (match_operand 2 "const_int_operand" "n")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9395 "or{b}\t{%2, %h0|%h0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "length_immediate" "1")
9398 (set_attr "modrm" "1")
9399 (set_attr "mode" "QI")])
9401 (define_insn "*iorqi_ext_1"
9402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9407 (match_operand 1 "ext_register_operand" "0")
9411 (match_operand:QI 2 "general_operand" "Qm"))))
9412 (clobber (reg:CC FLAGS_REG))]
9414 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9415 "or{b}\t{%2, %h0|%h0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "length_immediate" "0")
9418 (set_attr "mode" "QI")])
9420 (define_insn "*iorqi_ext_1_rex64"
9421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9426 (match_operand 1 "ext_register_operand" "0")
9430 (match_operand 2 "ext_register_operand" "Q"))))
9431 (clobber (reg:CC FLAGS_REG))]
9433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9434 "or{b}\t{%2, %h0|%h0, %2}"
9435 [(set_attr "type" "alu")
9436 (set_attr "length_immediate" "0")
9437 (set_attr "mode" "QI")])
9439 (define_insn "*iorqi_ext_2"
9440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9444 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9447 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9450 (clobber (reg:CC FLAGS_REG))]
9451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9452 "ior{b}\t{%h2, %h0|%h0, %h2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "length_immediate" "0")
9455 (set_attr "mode" "QI")])
9458 [(set (match_operand 0 "register_operand" "")
9459 (ior (match_operand 1 "register_operand" "")
9460 (match_operand 2 "const_int_operand" "")))
9461 (clobber (reg:CC FLAGS_REG))]
9463 && QI_REG_P (operands[0])
9464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9465 && !(INTVAL (operands[2]) & ~(255 << 8))
9466 && GET_MODE (operands[0]) != QImode"
9467 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9468 (ior:SI (zero_extract:SI (match_dup 1)
9469 (const_int 8) (const_int 8))
9471 (clobber (reg:CC FLAGS_REG))])]
9472 "operands[0] = gen_lowpart (SImode, operands[0]);
9473 operands[1] = gen_lowpart (SImode, operands[1]);
9474 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9476 ;; Since OR can be encoded with sign extended immediate, this is only
9477 ;; profitable when 7th bit is set.
9479 [(set (match_operand 0 "register_operand" "")
9480 (ior (match_operand 1 "general_operand" "")
9481 (match_operand 2 "const_int_operand" "")))
9482 (clobber (reg:CC FLAGS_REG))]
9484 && ANY_QI_REG_P (operands[0])
9485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9486 && !(INTVAL (operands[2]) & ~255)
9487 && (INTVAL (operands[2]) & 128)
9488 && GET_MODE (operands[0]) != QImode"
9489 [(parallel [(set (strict_low_part (match_dup 0))
9490 (ior:QI (match_dup 1)
9492 (clobber (reg:CC FLAGS_REG))])]
9493 "operands[0] = gen_lowpart (QImode, operands[0]);
9494 operands[1] = gen_lowpart (QImode, operands[1]);
9495 operands[2] = gen_lowpart (QImode, operands[2]);")
9497 ;; Logical XOR instructions
9499 ;; %%% This used to optimize known byte-wide and operations to memory.
9500 ;; If this is considered useful, it should be done with splitters.
9502 (define_expand "xordi3"
9503 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9504 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9505 (match_operand:DI 2 "x86_64_general_operand" "")))]
9507 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9509 (define_insn "*xordi_1_rex64"
9510 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9511 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9512 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9513 (clobber (reg:CC FLAGS_REG))]
9515 && ix86_binary_operator_ok (XOR, DImode, operands)"
9516 "xor{q}\t{%2, %0|%0, %2}"
9517 [(set_attr "type" "alu")
9518 (set_attr "mode" "DI")])
9520 (define_insn "*xordi_2_rex64"
9521 [(set (reg FLAGS_REG)
9522 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9523 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9525 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9526 (xor:DI (match_dup 1) (match_dup 2)))]
9528 && ix86_match_ccmode (insn, CCNOmode)
9529 && ix86_binary_operator_ok (XOR, DImode, operands)"
9530 "xor{q}\t{%2, %0|%0, %2}"
9531 [(set_attr "type" "alu")
9532 (set_attr "mode" "DI")])
9534 (define_insn "*xordi_3_rex64"
9535 [(set (reg FLAGS_REG)
9536 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9537 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9539 (clobber (match_scratch:DI 0 "=r"))]
9541 && ix86_match_ccmode (insn, CCNOmode)
9542 && ix86_binary_operator_ok (XOR, DImode, operands)"
9543 "xor{q}\t{%2, %0|%0, %2}"
9544 [(set_attr "type" "alu")
9545 (set_attr "mode" "DI")])
9547 (define_expand "xorsi3"
9548 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9549 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9550 (match_operand:SI 2 "general_operand" "")))]
9552 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9554 (define_insn "*xorsi_1"
9555 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9556 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9557 (match_operand:SI 2 "general_operand" "ri,rm")))
9558 (clobber (reg:CC FLAGS_REG))]
9559 "ix86_binary_operator_ok (XOR, SImode, operands)"
9560 "xor{l}\t{%2, %0|%0, %2}"
9561 [(set_attr "type" "alu")
9562 (set_attr "mode" "SI")])
9564 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9565 ;; Add speccase for immediates
9566 (define_insn "*xorsi_1_zext"
9567 [(set (match_operand:DI 0 "register_operand" "=r")
9569 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9570 (match_operand:SI 2 "general_operand" "g"))))
9571 (clobber (reg:CC FLAGS_REG))]
9572 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9573 "xor{l}\t{%2, %k0|%k0, %2}"
9574 [(set_attr "type" "alu")
9575 (set_attr "mode" "SI")])
9577 (define_insn "*xorsi_1_zext_imm"
9578 [(set (match_operand:DI 0 "register_operand" "=r")
9579 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9580 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9581 (clobber (reg:CC FLAGS_REG))]
9582 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9583 "xor{l}\t{%2, %k0|%k0, %2}"
9584 [(set_attr "type" "alu")
9585 (set_attr "mode" "SI")])
9587 (define_insn "*xorsi_2"
9588 [(set (reg FLAGS_REG)
9589 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9590 (match_operand:SI 2 "general_operand" "g,ri"))
9592 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9593 (xor:SI (match_dup 1) (match_dup 2)))]
9594 "ix86_match_ccmode (insn, CCNOmode)
9595 && ix86_binary_operator_ok (XOR, SImode, operands)"
9596 "xor{l}\t{%2, %0|%0, %2}"
9597 [(set_attr "type" "alu")
9598 (set_attr "mode" "SI")])
9600 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9601 ;; ??? Special case for immediate operand is missing - it is tricky.
9602 (define_insn "*xorsi_2_zext"
9603 [(set (reg FLAGS_REG)
9604 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9605 (match_operand:SI 2 "general_operand" "g"))
9607 (set (match_operand:DI 0 "register_operand" "=r")
9608 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9609 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9610 && ix86_binary_operator_ok (XOR, SImode, operands)"
9611 "xor{l}\t{%2, %k0|%k0, %2}"
9612 [(set_attr "type" "alu")
9613 (set_attr "mode" "SI")])
9615 (define_insn "*xorsi_2_zext_imm"
9616 [(set (reg FLAGS_REG)
9617 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9618 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9620 (set (match_operand:DI 0 "register_operand" "=r")
9621 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9622 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9623 && ix86_binary_operator_ok (XOR, SImode, operands)"
9624 "xor{l}\t{%2, %k0|%k0, %2}"
9625 [(set_attr "type" "alu")
9626 (set_attr "mode" "SI")])
9628 (define_insn "*xorsi_3"
9629 [(set (reg FLAGS_REG)
9630 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9631 (match_operand:SI 2 "general_operand" "g"))
9633 (clobber (match_scratch:SI 0 "=r"))]
9634 "ix86_match_ccmode (insn, CCNOmode)
9635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9636 "xor{l}\t{%2, %0|%0, %2}"
9637 [(set_attr "type" "alu")
9638 (set_attr "mode" "SI")])
9640 (define_expand "xorhi3"
9641 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9642 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9643 (match_operand:HI 2 "general_operand" "")))]
9644 "TARGET_HIMODE_MATH"
9645 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9647 (define_insn "*xorhi_1"
9648 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9649 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9650 (match_operand:HI 2 "general_operand" "rmn,rn")))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "ix86_binary_operator_ok (XOR, HImode, operands)"
9653 "xor{w}\t{%2, %0|%0, %2}"
9654 [(set_attr "type" "alu")
9655 (set_attr "mode" "HI")])
9657 (define_insn "*xorhi_2"
9658 [(set (reg FLAGS_REG)
9659 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9660 (match_operand:HI 2 "general_operand" "rmn,rn"))
9662 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9663 (xor:HI (match_dup 1) (match_dup 2)))]
9664 "ix86_match_ccmode (insn, CCNOmode)
9665 && ix86_binary_operator_ok (XOR, HImode, operands)"
9666 "xor{w}\t{%2, %0|%0, %2}"
9667 [(set_attr "type" "alu")
9668 (set_attr "mode" "HI")])
9670 (define_insn "*xorhi_3"
9671 [(set (reg FLAGS_REG)
9672 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9673 (match_operand:HI 2 "general_operand" "rmn"))
9675 (clobber (match_scratch:HI 0 "=r"))]
9676 "ix86_match_ccmode (insn, CCNOmode)
9677 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9678 "xor{w}\t{%2, %0|%0, %2}"
9679 [(set_attr "type" "alu")
9680 (set_attr "mode" "HI")])
9682 (define_expand "xorqi3"
9683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9684 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9685 (match_operand:QI 2 "general_operand" "")))]
9686 "TARGET_QIMODE_MATH"
9687 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9689 ;; %%% Potential partial reg stall on alternative 2. What to do?
9690 (define_insn "*xorqi_1"
9691 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9692 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9693 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9694 (clobber (reg:CC FLAGS_REG))]
9695 "ix86_binary_operator_ok (XOR, QImode, operands)"
9697 xor{b}\t{%2, %0|%0, %2}
9698 xor{b}\t{%2, %0|%0, %2}
9699 xor{l}\t{%k2, %k0|%k0, %k2}"
9700 [(set_attr "type" "alu")
9701 (set_attr "mode" "QI,QI,SI")])
9703 (define_insn "*xorqi_1_slp"
9704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9705 (xor:QI (match_dup 0)
9706 (match_operand:QI 1 "general_operand" "qn,qmn")))
9707 (clobber (reg:CC FLAGS_REG))]
9708 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9709 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9710 "xor{b}\t{%1, %0|%0, %1}"
9711 [(set_attr "type" "alu1")
9712 (set_attr "mode" "QI")])
9714 (define_insn "*xorqi_ext_0"
9715 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9720 (match_operand 1 "ext_register_operand" "0")
9723 (match_operand 2 "const_int_operand" "n")))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9726 "xor{b}\t{%2, %h0|%h0, %2}"
9727 [(set_attr "type" "alu")
9728 (set_attr "length_immediate" "1")
9729 (set_attr "modrm" "1")
9730 (set_attr "mode" "QI")])
9732 (define_insn "*xorqi_ext_1"
9733 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9738 (match_operand 1 "ext_register_operand" "0")
9742 (match_operand:QI 2 "general_operand" "Qm"))))
9743 (clobber (reg:CC FLAGS_REG))]
9745 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9746 "xor{b}\t{%2, %h0|%h0, %2}"
9747 [(set_attr "type" "alu")
9748 (set_attr "length_immediate" "0")
9749 (set_attr "mode" "QI")])
9751 (define_insn "*xorqi_ext_1_rex64"
9752 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9757 (match_operand 1 "ext_register_operand" "0")
9761 (match_operand 2 "ext_register_operand" "Q"))))
9762 (clobber (reg:CC FLAGS_REG))]
9764 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9765 "xor{b}\t{%2, %h0|%h0, %2}"
9766 [(set_attr "type" "alu")
9767 (set_attr "length_immediate" "0")
9768 (set_attr "mode" "QI")])
9770 (define_insn "*xorqi_ext_2"
9771 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9775 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9778 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9781 (clobber (reg:CC FLAGS_REG))]
9782 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9783 "xor{b}\t{%h2, %h0|%h0, %h2}"
9784 [(set_attr "type" "alu")
9785 (set_attr "length_immediate" "0")
9786 (set_attr "mode" "QI")])
9788 (define_insn "*xorqi_cc_1"
9789 [(set (reg FLAGS_REG)
9791 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9792 (match_operand:QI 2 "general_operand" "qmn,qn"))
9794 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9795 (xor:QI (match_dup 1) (match_dup 2)))]
9796 "ix86_match_ccmode (insn, CCNOmode)
9797 && ix86_binary_operator_ok (XOR, QImode, operands)"
9798 "xor{b}\t{%2, %0|%0, %2}"
9799 [(set_attr "type" "alu")
9800 (set_attr "mode" "QI")])
9802 (define_insn "*xorqi_2_slp"
9803 [(set (reg FLAGS_REG)
9804 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9805 (match_operand:QI 1 "general_operand" "qmn,qn"))
9807 (set (strict_low_part (match_dup 0))
9808 (xor:QI (match_dup 0) (match_dup 1)))]
9809 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9810 && ix86_match_ccmode (insn, CCNOmode)
9811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9812 "xor{b}\t{%1, %0|%0, %1}"
9813 [(set_attr "type" "alu1")
9814 (set_attr "mode" "QI")])
9816 (define_insn "*xorqi_cc_2"
9817 [(set (reg FLAGS_REG)
9819 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9820 (match_operand:QI 2 "general_operand" "qmn"))
9822 (clobber (match_scratch:QI 0 "=q"))]
9823 "ix86_match_ccmode (insn, CCNOmode)
9824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9825 "xor{b}\t{%2, %0|%0, %2}"
9826 [(set_attr "type" "alu")
9827 (set_attr "mode" "QI")])
9829 (define_insn "*xorqi_cc_ext_1"
9830 [(set (reg FLAGS_REG)
9834 (match_operand 1 "ext_register_operand" "0")
9837 (match_operand:QI 2 "general_operand" "qmn"))
9839 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9843 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9845 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9846 "xor{b}\t{%2, %h0|%h0, %2}"
9847 [(set_attr "type" "alu")
9848 (set_attr "modrm" "1")
9849 (set_attr "mode" "QI")])
9851 (define_insn "*xorqi_cc_ext_1_rex64"
9852 [(set (reg FLAGS_REG)
9856 (match_operand 1 "ext_register_operand" "0")
9859 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9861 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9865 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9867 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9868 "xor{b}\t{%2, %h0|%h0, %2}"
9869 [(set_attr "type" "alu")
9870 (set_attr "modrm" "1")
9871 (set_attr "mode" "QI")])
9873 (define_expand "xorqi_cc_ext_1"
9875 (set (reg:CCNO FLAGS_REG)
9879 (match_operand 1 "ext_register_operand" "")
9882 (match_operand:QI 2 "general_operand" ""))
9884 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9888 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9894 [(set (match_operand 0 "register_operand" "")
9895 (xor (match_operand 1 "register_operand" "")
9896 (match_operand 2 "const_int_operand" "")))
9897 (clobber (reg:CC FLAGS_REG))]
9899 && QI_REG_P (operands[0])
9900 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9901 && !(INTVAL (operands[2]) & ~(255 << 8))
9902 && GET_MODE (operands[0]) != QImode"
9903 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9904 (xor:SI (zero_extract:SI (match_dup 1)
9905 (const_int 8) (const_int 8))
9907 (clobber (reg:CC FLAGS_REG))])]
9908 "operands[0] = gen_lowpart (SImode, operands[0]);
9909 operands[1] = gen_lowpart (SImode, operands[1]);
9910 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9912 ;; Since XOR can be encoded with sign extended immediate, this is only
9913 ;; profitable when 7th bit is set.
9915 [(set (match_operand 0 "register_operand" "")
9916 (xor (match_operand 1 "general_operand" "")
9917 (match_operand 2 "const_int_operand" "")))
9918 (clobber (reg:CC FLAGS_REG))]
9920 && ANY_QI_REG_P (operands[0])
9921 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9922 && !(INTVAL (operands[2]) & ~255)
9923 && (INTVAL (operands[2]) & 128)
9924 && GET_MODE (operands[0]) != QImode"
9925 [(parallel [(set (strict_low_part (match_dup 0))
9926 (xor:QI (match_dup 1)
9928 (clobber (reg:CC FLAGS_REG))])]
9929 "operands[0] = gen_lowpart (QImode, operands[0]);
9930 operands[1] = gen_lowpart (QImode, operands[1]);
9931 operands[2] = gen_lowpart (QImode, operands[2]);")
9933 ;; Negation instructions
9935 (define_expand "negti2"
9936 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9937 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
9939 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9941 (define_insn "*negti2_1"
9942 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9943 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9944 (clobber (reg:CC FLAGS_REG))]
9946 && ix86_unary_operator_ok (NEG, TImode, operands)"
9950 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9951 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9952 (clobber (reg:CC FLAGS_REG))]
9953 "TARGET_64BIT && reload_completed"
9955 [(set (reg:CCZ FLAGS_REG)
9956 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
9957 (set (match_dup 0) (neg:DI (match_dup 1)))])
9960 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9963 (clobber (reg:CC FLAGS_REG))])
9966 (neg:DI (match_dup 2)))
9967 (clobber (reg:CC FLAGS_REG))])]
9968 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
9970 (define_expand "negdi2"
9971 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9972 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9974 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9976 (define_insn "*negdi2_1"
9977 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9978 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9979 (clobber (reg:CC FLAGS_REG))]
9981 && ix86_unary_operator_ok (NEG, DImode, operands)"
9985 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9986 (neg:DI (match_operand:DI 1 "general_operand" "")))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "!TARGET_64BIT && reload_completed"
9990 [(set (reg:CCZ FLAGS_REG)
9991 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
9992 (set (match_dup 0) (neg:SI (match_dup 1)))])
9995 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9998 (clobber (reg:CC FLAGS_REG))])
10000 [(set (match_dup 2)
10001 (neg:SI (match_dup 2)))
10002 (clobber (reg:CC FLAGS_REG))])]
10003 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10005 (define_insn "*negdi2_1_rex64"
10006 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10007 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10008 (clobber (reg:CC FLAGS_REG))]
10009 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10011 [(set_attr "type" "negnot")
10012 (set_attr "mode" "DI")])
10014 ;; The problem with neg is that it does not perform (compare x 0),
10015 ;; it really performs (compare 0 x), which leaves us with the zero
10016 ;; flag being the only useful item.
10018 (define_insn "*negdi2_cmpz_rex64"
10019 [(set (reg:CCZ FLAGS_REG)
10020 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10022 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10023 (neg:DI (match_dup 1)))]
10024 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10026 [(set_attr "type" "negnot")
10027 (set_attr "mode" "DI")])
10030 (define_expand "negsi2"
10031 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10032 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10034 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10036 (define_insn "*negsi2_1"
10037 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10038 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10039 (clobber (reg:CC FLAGS_REG))]
10040 "ix86_unary_operator_ok (NEG, SImode, operands)"
10042 [(set_attr "type" "negnot")
10043 (set_attr "mode" "SI")])
10045 ;; Combine is quite creative about this pattern.
10046 (define_insn "*negsi2_1_zext"
10047 [(set (match_operand:DI 0 "register_operand" "=r")
10048 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10051 (clobber (reg:CC FLAGS_REG))]
10052 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10054 [(set_attr "type" "negnot")
10055 (set_attr "mode" "SI")])
10057 ;; The problem with neg is that it does not perform (compare x 0),
10058 ;; it really performs (compare 0 x), which leaves us with the zero
10059 ;; flag being the only useful item.
10061 (define_insn "*negsi2_cmpz"
10062 [(set (reg:CCZ FLAGS_REG)
10063 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10065 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10066 (neg:SI (match_dup 1)))]
10067 "ix86_unary_operator_ok (NEG, SImode, operands)"
10069 [(set_attr "type" "negnot")
10070 (set_attr "mode" "SI")])
10072 (define_insn "*negsi2_cmpz_zext"
10073 [(set (reg:CCZ FLAGS_REG)
10074 (compare:CCZ (lshiftrt:DI
10076 (match_operand:DI 1 "register_operand" "0")
10080 (set (match_operand:DI 0 "register_operand" "=r")
10081 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10084 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10086 [(set_attr "type" "negnot")
10087 (set_attr "mode" "SI")])
10089 (define_expand "neghi2"
10090 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10091 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10092 "TARGET_HIMODE_MATH"
10093 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10095 (define_insn "*neghi2_1"
10096 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10097 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10098 (clobber (reg:CC FLAGS_REG))]
10099 "ix86_unary_operator_ok (NEG, HImode, operands)"
10101 [(set_attr "type" "negnot")
10102 (set_attr "mode" "HI")])
10104 (define_insn "*neghi2_cmpz"
10105 [(set (reg:CCZ FLAGS_REG)
10106 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10108 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10109 (neg:HI (match_dup 1)))]
10110 "ix86_unary_operator_ok (NEG, HImode, operands)"
10112 [(set_attr "type" "negnot")
10113 (set_attr "mode" "HI")])
10115 (define_expand "negqi2"
10116 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10117 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10118 "TARGET_QIMODE_MATH"
10119 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10121 (define_insn "*negqi2_1"
10122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10123 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "ix86_unary_operator_ok (NEG, QImode, operands)"
10127 [(set_attr "type" "negnot")
10128 (set_attr "mode" "QI")])
10130 (define_insn "*negqi2_cmpz"
10131 [(set (reg:CCZ FLAGS_REG)
10132 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10134 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10135 (neg:QI (match_dup 1)))]
10136 "ix86_unary_operator_ok (NEG, QImode, operands)"
10138 [(set_attr "type" "negnot")
10139 (set_attr "mode" "QI")])
10141 ;; Changing of sign for FP values is doable using integer unit too.
10143 (define_expand "<code><mode>2"
10144 [(set (match_operand:X87MODEF 0 "register_operand" "")
10145 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10146 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10147 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10149 (define_insn "*absneg<mode>2_mixed"
10150 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10151 (match_operator:MODEF 3 "absneg_operator"
10152 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10153 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10154 (clobber (reg:CC FLAGS_REG))]
10155 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10158 (define_insn "*absneg<mode>2_sse"
10159 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10160 (match_operator:MODEF 3 "absneg_operator"
10161 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10162 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10163 (clobber (reg:CC FLAGS_REG))]
10164 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10167 (define_insn "*absneg<mode>2_i387"
10168 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10169 (match_operator:X87MODEF 3 "absneg_operator"
10170 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10171 (use (match_operand 2 "" ""))
10172 (clobber (reg:CC FLAGS_REG))]
10173 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10176 (define_expand "<code>tf2"
10177 [(set (match_operand:TF 0 "register_operand" "")
10178 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10180 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10182 (define_insn "*absnegtf2_sse"
10183 [(set (match_operand:TF 0 "register_operand" "=x,x")
10184 (match_operator:TF 3 "absneg_operator"
10185 [(match_operand:TF 1 "register_operand" "0,x")]))
10186 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10187 (clobber (reg:CC FLAGS_REG))]
10191 ;; Splitters for fp abs and neg.
10194 [(set (match_operand 0 "fp_register_operand" "")
10195 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10196 (use (match_operand 2 "" ""))
10197 (clobber (reg:CC FLAGS_REG))]
10199 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10202 [(set (match_operand 0 "register_operand" "")
10203 (match_operator 3 "absneg_operator"
10204 [(match_operand 1 "register_operand" "")]))
10205 (use (match_operand 2 "nonimmediate_operand" ""))
10206 (clobber (reg:CC FLAGS_REG))]
10207 "reload_completed && SSE_REG_P (operands[0])"
10208 [(set (match_dup 0) (match_dup 3))]
10210 enum machine_mode mode = GET_MODE (operands[0]);
10211 enum machine_mode vmode = GET_MODE (operands[2]);
10214 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10215 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10216 if (operands_match_p (operands[0], operands[2]))
10219 operands[1] = operands[2];
10222 if (GET_CODE (operands[3]) == ABS)
10223 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10225 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10230 [(set (match_operand:SF 0 "register_operand" "")
10231 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10232 (use (match_operand:V4SF 2 "" ""))
10233 (clobber (reg:CC FLAGS_REG))]
10235 [(parallel [(set (match_dup 0) (match_dup 1))
10236 (clobber (reg:CC FLAGS_REG))])]
10239 operands[0] = gen_lowpart (SImode, operands[0]);
10240 if (GET_CODE (operands[1]) == ABS)
10242 tmp = gen_int_mode (0x7fffffff, SImode);
10243 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10247 tmp = gen_int_mode (0x80000000, SImode);
10248 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10254 [(set (match_operand:DF 0 "register_operand" "")
10255 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10256 (use (match_operand 2 "" ""))
10257 (clobber (reg:CC FLAGS_REG))]
10259 [(parallel [(set (match_dup 0) (match_dup 1))
10260 (clobber (reg:CC FLAGS_REG))])]
10265 tmp = gen_lowpart (DImode, operands[0]);
10266 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10269 if (GET_CODE (operands[1]) == ABS)
10272 tmp = gen_rtx_NOT (DImode, tmp);
10276 operands[0] = gen_highpart (SImode, operands[0]);
10277 if (GET_CODE (operands[1]) == ABS)
10279 tmp = gen_int_mode (0x7fffffff, SImode);
10280 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10284 tmp = gen_int_mode (0x80000000, SImode);
10285 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10292 [(set (match_operand:XF 0 "register_operand" "")
10293 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10294 (use (match_operand 2 "" ""))
10295 (clobber (reg:CC FLAGS_REG))]
10297 [(parallel [(set (match_dup 0) (match_dup 1))
10298 (clobber (reg:CC FLAGS_REG))])]
10301 operands[0] = gen_rtx_REG (SImode,
10302 true_regnum (operands[0])
10303 + (TARGET_64BIT ? 1 : 2));
10304 if (GET_CODE (operands[1]) == ABS)
10306 tmp = GEN_INT (0x7fff);
10307 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10311 tmp = GEN_INT (0x8000);
10312 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10317 ;; Conditionalize these after reload. If they match before reload, we
10318 ;; lose the clobber and ability to use integer instructions.
10320 (define_insn "*<code><mode>2_1"
10321 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10322 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10324 && (reload_completed
10325 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10327 [(set_attr "type" "fsgn")
10328 (set_attr "mode" "<MODE>")])
10330 (define_insn "*<code>extendsfdf2"
10331 [(set (match_operand:DF 0 "register_operand" "=f")
10332 (absneg:DF (float_extend:DF
10333 (match_operand:SF 1 "register_operand" "0"))))]
10334 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10336 [(set_attr "type" "fsgn")
10337 (set_attr "mode" "DF")])
10339 (define_insn "*<code>extendsfxf2"
10340 [(set (match_operand:XF 0 "register_operand" "=f")
10341 (absneg:XF (float_extend:XF
10342 (match_operand:SF 1 "register_operand" "0"))))]
10345 [(set_attr "type" "fsgn")
10346 (set_attr "mode" "XF")])
10348 (define_insn "*<code>extenddfxf2"
10349 [(set (match_operand:XF 0 "register_operand" "=f")
10350 (absneg:XF (float_extend:XF
10351 (match_operand:DF 1 "register_operand" "0"))))]
10354 [(set_attr "type" "fsgn")
10355 (set_attr "mode" "XF")])
10357 ;; Copysign instructions
10359 (define_mode_iterator CSGNMODE [SF DF TF])
10360 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10362 (define_expand "copysign<mode>3"
10363 [(match_operand:CSGNMODE 0 "register_operand" "")
10364 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10365 (match_operand:CSGNMODE 2 "register_operand" "")]
10366 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10367 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10369 ix86_expand_copysign (operands);
10373 (define_insn_and_split "copysign<mode>3_const"
10374 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10376 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10377 (match_operand:CSGNMODE 2 "register_operand" "0")
10378 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10380 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10381 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10383 "&& reload_completed"
10386 ix86_split_copysign_const (operands);
10390 (define_insn "copysign<mode>3_var"
10391 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10393 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10394 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10395 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10396 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10398 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10399 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10400 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10404 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10406 [(match_operand:CSGNMODE 2 "register_operand" "")
10407 (match_operand:CSGNMODE 3 "register_operand" "")
10408 (match_operand:<CSGNVMODE> 4 "" "")
10409 (match_operand:<CSGNVMODE> 5 "" "")]
10411 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10412 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10413 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10414 && reload_completed"
10417 ix86_split_copysign_var (operands);
10421 ;; One complement instructions
10423 (define_expand "one_cmpldi2"
10424 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10425 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10427 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10429 (define_insn "*one_cmpldi2_1_rex64"
10430 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10431 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10432 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10434 [(set_attr "type" "negnot")
10435 (set_attr "mode" "DI")])
10437 (define_insn "*one_cmpldi2_2_rex64"
10438 [(set (reg FLAGS_REG)
10439 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10441 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10442 (not:DI (match_dup 1)))]
10443 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10444 && ix86_unary_operator_ok (NOT, DImode, operands)"
10446 [(set_attr "type" "alu1")
10447 (set_attr "mode" "DI")])
10450 [(set (match_operand 0 "flags_reg_operand" "")
10451 (match_operator 2 "compare_operator"
10452 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10454 (set (match_operand:DI 1 "nonimmediate_operand" "")
10455 (not:DI (match_dup 3)))]
10456 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10457 [(parallel [(set (match_dup 0)
10459 [(xor:DI (match_dup 3) (const_int -1))
10462 (xor:DI (match_dup 3) (const_int -1)))])]
10465 (define_expand "one_cmplsi2"
10466 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10467 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10469 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10471 (define_insn "*one_cmplsi2_1"
10472 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10473 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10474 "ix86_unary_operator_ok (NOT, SImode, operands)"
10476 [(set_attr "type" "negnot")
10477 (set_attr "mode" "SI")])
10479 ;; ??? Currently never generated - xor is used instead.
10480 (define_insn "*one_cmplsi2_1_zext"
10481 [(set (match_operand:DI 0 "register_operand" "=r")
10482 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10483 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "SI")])
10488 (define_insn "*one_cmplsi2_2"
10489 [(set (reg FLAGS_REG)
10490 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10492 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10493 (not:SI (match_dup 1)))]
10494 "ix86_match_ccmode (insn, CCNOmode)
10495 && ix86_unary_operator_ok (NOT, SImode, operands)"
10497 [(set_attr "type" "alu1")
10498 (set_attr "mode" "SI")])
10501 [(set (match_operand 0 "flags_reg_operand" "")
10502 (match_operator 2 "compare_operator"
10503 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10505 (set (match_operand:SI 1 "nonimmediate_operand" "")
10506 (not:SI (match_dup 3)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (match_dup 0)
10509 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10512 (xor:SI (match_dup 3) (const_int -1)))])]
10515 ;; ??? Currently never generated - xor is used instead.
10516 (define_insn "*one_cmplsi2_2_zext"
10517 [(set (reg FLAGS_REG)
10518 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10520 (set (match_operand:DI 0 "register_operand" "=r")
10521 (zero_extend:DI (not:SI (match_dup 1))))]
10522 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10523 && ix86_unary_operator_ok (NOT, SImode, operands)"
10525 [(set_attr "type" "alu1")
10526 (set_attr "mode" "SI")])
10529 [(set (match_operand 0 "flags_reg_operand" "")
10530 (match_operator 2 "compare_operator"
10531 [(not:SI (match_operand:SI 3 "register_operand" ""))
10533 (set (match_operand:DI 1 "register_operand" "")
10534 (zero_extend:DI (not:SI (match_dup 3))))]
10535 "ix86_match_ccmode (insn, CCNOmode)"
10536 [(parallel [(set (match_dup 0)
10537 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10540 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10543 (define_expand "one_cmplhi2"
10544 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10545 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10546 "TARGET_HIMODE_MATH"
10547 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10549 (define_insn "*one_cmplhi2_1"
10550 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10551 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10552 "ix86_unary_operator_ok (NOT, HImode, operands)"
10554 [(set_attr "type" "negnot")
10555 (set_attr "mode" "HI")])
10557 (define_insn "*one_cmplhi2_2"
10558 [(set (reg FLAGS_REG)
10559 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10561 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10562 (not:HI (match_dup 1)))]
10563 "ix86_match_ccmode (insn, CCNOmode)
10564 && ix86_unary_operator_ok (NEG, HImode, operands)"
10566 [(set_attr "type" "alu1")
10567 (set_attr "mode" "HI")])
10570 [(set (match_operand 0 "flags_reg_operand" "")
10571 (match_operator 2 "compare_operator"
10572 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10574 (set (match_operand:HI 1 "nonimmediate_operand" "")
10575 (not:HI (match_dup 3)))]
10576 "ix86_match_ccmode (insn, CCNOmode)"
10577 [(parallel [(set (match_dup 0)
10578 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10581 (xor:HI (match_dup 3) (const_int -1)))])]
10584 ;; %%% Potential partial reg stall on alternative 1. What to do?
10585 (define_expand "one_cmplqi2"
10586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10587 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10588 "TARGET_QIMODE_MATH"
10589 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10591 (define_insn "*one_cmplqi2_1"
10592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10593 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10594 "ix86_unary_operator_ok (NOT, QImode, operands)"
10598 [(set_attr "type" "negnot")
10599 (set_attr "mode" "QI,SI")])
10601 (define_insn "*one_cmplqi2_2"
10602 [(set (reg FLAGS_REG)
10603 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10605 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10606 (not:QI (match_dup 1)))]
10607 "ix86_match_ccmode (insn, CCNOmode)
10608 && ix86_unary_operator_ok (NOT, QImode, operands)"
10610 [(set_attr "type" "alu1")
10611 (set_attr "mode" "QI")])
10614 [(set (match_operand 0 "flags_reg_operand" "")
10615 (match_operator 2 "compare_operator"
10616 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10618 (set (match_operand:QI 1 "nonimmediate_operand" "")
10619 (not:QI (match_dup 3)))]
10620 "ix86_match_ccmode (insn, CCNOmode)"
10621 [(parallel [(set (match_dup 0)
10622 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10625 (xor:QI (match_dup 3) (const_int -1)))])]
10628 ;; Arithmetic shift instructions
10630 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10631 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10632 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10633 ;; from the assembler input.
10635 ;; This instruction shifts the target reg/mem as usual, but instead of
10636 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10637 ;; is a left shift double, bits are taken from the high order bits of
10638 ;; reg, else if the insn is a shift right double, bits are taken from the
10639 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10640 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10642 ;; Since sh[lr]d does not change the `reg' operand, that is done
10643 ;; separately, making all shifts emit pairs of shift double and normal
10644 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10645 ;; support a 63 bit shift, each shift where the count is in a reg expands
10646 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10648 ;; If the shift count is a constant, we need never emit more than one
10649 ;; shift pair, instead using moves and sign extension for counts greater
10652 (define_expand "ashlti3"
10653 [(set (match_operand:TI 0 "register_operand" "")
10654 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10655 (match_operand:QI 2 "nonmemory_operand" "")))]
10657 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10659 ;; This pattern must be defined before *ashlti3_1 to prevent
10660 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10662 (define_insn "*avx_ashlti3"
10663 [(set (match_operand:TI 0 "register_operand" "=x")
10664 (ashift:TI (match_operand:TI 1 "register_operand" "x")
10665 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10668 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10669 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10671 [(set_attr "type" "sseishft")
10672 (set_attr "prefix" "vex")
10673 (set_attr "length_immediate" "1")
10674 (set_attr "mode" "TI")])
10676 (define_insn "sse2_ashlti3"
10677 [(set (match_operand:TI 0 "register_operand" "=x")
10678 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10679 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10682 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10683 return "pslldq\t{%2, %0|%0, %2}";
10685 [(set_attr "type" "sseishft")
10686 (set_attr "prefix_data16" "1")
10687 (set_attr "length_immediate" "1")
10688 (set_attr "mode" "TI")])
10690 (define_insn "*ashlti3_1"
10691 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10692 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10693 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10694 (clobber (reg:CC FLAGS_REG))]
10697 [(set_attr "type" "multi")])
10700 [(match_scratch:DI 3 "r")
10701 (parallel [(set (match_operand:TI 0 "register_operand" "")
10702 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10703 (match_operand:QI 2 "nonmemory_operand" "")))
10704 (clobber (reg:CC FLAGS_REG))])
10708 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10711 [(set (match_operand:TI 0 "register_operand" "")
10712 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10713 (match_operand:QI 2 "nonmemory_operand" "")))
10714 (clobber (reg:CC FLAGS_REG))]
10715 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10716 ? epilogue_completed : reload_completed)"
10718 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10720 (define_insn "x86_64_shld"
10721 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10722 (ior:DI (ashift:DI (match_dup 0)
10723 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10724 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10725 (minus:QI (const_int 64) (match_dup 2)))))
10726 (clobber (reg:CC FLAGS_REG))]
10728 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10729 [(set_attr "type" "ishift")
10730 (set_attr "prefix_0f" "1")
10731 (set_attr "mode" "DI")
10732 (set_attr "athlon_decode" "vector")
10733 (set_attr "amdfam10_decode" "vector")])
10735 (define_expand "x86_64_shift_adj_1"
10736 [(set (reg:CCZ FLAGS_REG)
10737 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10740 (set (match_operand:DI 0 "register_operand" "")
10741 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10742 (match_operand:DI 1 "register_operand" "")
10745 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10746 (match_operand:DI 3 "register_operand" "r")
10751 (define_expand "x86_64_shift_adj_2"
10752 [(use (match_operand:DI 0 "register_operand" ""))
10753 (use (match_operand:DI 1 "register_operand" ""))
10754 (use (match_operand:QI 2 "register_operand" ""))]
10757 rtx label = gen_label_rtx ();
10760 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10762 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10763 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10764 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10765 gen_rtx_LABEL_REF (VOIDmode, label),
10767 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10768 JUMP_LABEL (tmp) = label;
10770 emit_move_insn (operands[0], operands[1]);
10771 ix86_expand_clear (operands[1]);
10773 emit_label (label);
10774 LABEL_NUSES (label) = 1;
10779 (define_expand "ashldi3"
10780 [(set (match_operand:DI 0 "shiftdi_operand" "")
10781 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10782 (match_operand:QI 2 "nonmemory_operand" "")))]
10784 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10786 (define_insn "*ashldi3_1_rex64"
10787 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10788 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10789 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10790 (clobber (reg:CC FLAGS_REG))]
10791 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10793 switch (get_attr_type (insn))
10796 gcc_assert (operands[2] == const1_rtx);
10797 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10798 return "add{q}\t%0, %0";
10801 gcc_assert (CONST_INT_P (operands[2]));
10802 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10803 operands[1] = gen_rtx_MULT (DImode, operands[1],
10804 GEN_INT (1 << INTVAL (operands[2])));
10805 return "lea{q}\t{%a1, %0|%0, %a1}";
10808 if (REG_P (operands[2]))
10809 return "sal{q}\t{%b2, %0|%0, %b2}";
10810 else if (operands[2] == const1_rtx
10811 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10812 return "sal{q}\t%0";
10814 return "sal{q}\t{%2, %0|%0, %2}";
10817 [(set (attr "type")
10818 (cond [(eq_attr "alternative" "1")
10819 (const_string "lea")
10820 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822 (match_operand 0 "register_operand" ""))
10823 (match_operand 2 "const1_operand" ""))
10824 (const_string "alu")
10826 (const_string "ishift")))
10827 (set (attr "length_immediate")
10829 (ior (eq_attr "type" "alu")
10830 (and (eq_attr "type" "ishift")
10831 (and (match_operand 2 "const1_operand" "")
10832 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10835 (const_string "*")))
10836 (set_attr "mode" "DI")])
10838 ;; Convert lea to the lea pattern to avoid flags dependency.
10840 [(set (match_operand:DI 0 "register_operand" "")
10841 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10842 (match_operand:QI 2 "immediate_operand" "")))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "TARGET_64BIT && reload_completed
10845 && true_regnum (operands[0]) != true_regnum (operands[1])"
10846 [(set (match_dup 0)
10847 (mult:DI (match_dup 1)
10849 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10851 ;; This pattern can't accept a variable shift count, since shifts by
10852 ;; zero don't affect the flags. We assume that shifts by constant
10853 ;; zero are optimized away.
10854 (define_insn "*ashldi3_cmp_rex64"
10855 [(set (reg FLAGS_REG)
10857 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10858 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10860 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10861 (ashift:DI (match_dup 1) (match_dup 2)))]
10863 && (optimize_function_for_size_p (cfun)
10864 || !TARGET_PARTIAL_FLAG_REG_STALL
10865 || (operands[2] == const1_rtx
10867 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10868 && ix86_match_ccmode (insn, CCGOCmode)
10869 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10871 switch (get_attr_type (insn))
10874 gcc_assert (operands[2] == const1_rtx);
10875 return "add{q}\t%0, %0";
10878 if (REG_P (operands[2]))
10879 return "sal{q}\t{%b2, %0|%0, %b2}";
10880 else if (operands[2] == const1_rtx
10881 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10882 return "sal{q}\t%0";
10884 return "sal{q}\t{%2, %0|%0, %2}";
10887 [(set (attr "type")
10888 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890 (match_operand 0 "register_operand" ""))
10891 (match_operand 2 "const1_operand" ""))
10892 (const_string "alu")
10894 (const_string "ishift")))
10895 (set (attr "length_immediate")
10897 (ior (eq_attr "type" "alu")
10898 (and (eq_attr "type" "ishift")
10899 (and (match_operand 2 "const1_operand" "")
10900 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10903 (const_string "*")))
10904 (set_attr "mode" "DI")])
10906 (define_insn "*ashldi3_cconly_rex64"
10907 [(set (reg FLAGS_REG)
10909 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10910 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10912 (clobber (match_scratch:DI 0 "=r"))]
10914 && (optimize_function_for_size_p (cfun)
10915 || !TARGET_PARTIAL_FLAG_REG_STALL
10916 || (operands[2] == const1_rtx
10918 || TARGET_DOUBLE_WITH_ADD)))
10919 && ix86_match_ccmode (insn, CCGOCmode)
10920 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10922 switch (get_attr_type (insn))
10925 gcc_assert (operands[2] == const1_rtx);
10926 return "add{q}\t%0, %0";
10929 if (REG_P (operands[2]))
10930 return "sal{q}\t{%b2, %0|%0, %b2}";
10931 else if (operands[2] == const1_rtx
10932 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10933 return "sal{q}\t%0";
10935 return "sal{q}\t{%2, %0|%0, %2}";
10938 [(set (attr "type")
10939 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10941 (match_operand 0 "register_operand" ""))
10942 (match_operand 2 "const1_operand" ""))
10943 (const_string "alu")
10945 (const_string "ishift")))
10946 (set (attr "length_immediate")
10948 (ior (eq_attr "type" "alu")
10949 (and (eq_attr "type" "ishift")
10950 (and (match_operand 2 "const1_operand" "")
10951 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10954 (const_string "*")))
10955 (set_attr "mode" "DI")])
10957 (define_insn "*ashldi3_1"
10958 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10959 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10960 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10961 (clobber (reg:CC FLAGS_REG))]
10964 [(set_attr "type" "multi")])
10966 ;; By default we don't ask for a scratch register, because when DImode
10967 ;; values are manipulated, registers are already at a premium. But if
10968 ;; we have one handy, we won't turn it away.
10970 [(match_scratch:SI 3 "r")
10971 (parallel [(set (match_operand:DI 0 "register_operand" "")
10972 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10973 (match_operand:QI 2 "nonmemory_operand" "")))
10974 (clobber (reg:CC FLAGS_REG))])
10976 "!TARGET_64BIT && TARGET_CMOVE"
10978 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10981 [(set (match_operand:DI 0 "register_operand" "")
10982 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10983 (match_operand:QI 2 "nonmemory_operand" "")))
10984 (clobber (reg:CC FLAGS_REG))]
10985 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10986 ? epilogue_completed : reload_completed)"
10988 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10990 (define_insn "x86_shld"
10991 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10992 (ior:SI (ashift:SI (match_dup 0)
10993 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10994 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10995 (minus:QI (const_int 32) (match_dup 2)))))
10996 (clobber (reg:CC FLAGS_REG))]
10998 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10999 [(set_attr "type" "ishift")
11000 (set_attr "prefix_0f" "1")
11001 (set_attr "mode" "SI")
11002 (set_attr "pent_pair" "np")
11003 (set_attr "athlon_decode" "vector")
11004 (set_attr "amdfam10_decode" "vector")])
11006 (define_expand "x86_shift_adj_1"
11007 [(set (reg:CCZ FLAGS_REG)
11008 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11011 (set (match_operand:SI 0 "register_operand" "")
11012 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11013 (match_operand:SI 1 "register_operand" "")
11016 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11017 (match_operand:SI 3 "register_operand" "r")
11022 (define_expand "x86_shift_adj_2"
11023 [(use (match_operand:SI 0 "register_operand" ""))
11024 (use (match_operand:SI 1 "register_operand" ""))
11025 (use (match_operand:QI 2 "register_operand" ""))]
11028 rtx label = gen_label_rtx ();
11031 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11033 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11034 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11035 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11036 gen_rtx_LABEL_REF (VOIDmode, label),
11038 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11039 JUMP_LABEL (tmp) = label;
11041 emit_move_insn (operands[0], operands[1]);
11042 ix86_expand_clear (operands[1]);
11044 emit_label (label);
11045 LABEL_NUSES (label) = 1;
11050 (define_expand "ashlsi3"
11051 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11052 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11053 (match_operand:QI 2 "nonmemory_operand" "")))]
11055 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11057 (define_insn "*ashlsi3_1"
11058 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11059 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11060 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11061 (clobber (reg:CC FLAGS_REG))]
11062 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11064 switch (get_attr_type (insn))
11067 gcc_assert (operands[2] == const1_rtx);
11068 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11069 return "add{l}\t%0, %0";
11075 if (REG_P (operands[2]))
11076 return "sal{l}\t{%b2, %0|%0, %b2}";
11077 else if (operands[2] == const1_rtx
11078 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11079 return "sal{l}\t%0";
11081 return "sal{l}\t{%2, %0|%0, %2}";
11084 [(set (attr "type")
11085 (cond [(eq_attr "alternative" "1")
11086 (const_string "lea")
11087 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11089 (match_operand 0 "register_operand" ""))
11090 (match_operand 2 "const1_operand" ""))
11091 (const_string "alu")
11093 (const_string "ishift")))
11094 (set (attr "length_immediate")
11096 (ior (eq_attr "type" "alu")
11097 (and (eq_attr "type" "ishift")
11098 (and (match_operand 2 "const1_operand" "")
11099 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11102 (const_string "*")))
11103 (set_attr "mode" "SI")])
11105 ;; Convert lea to the lea pattern to avoid flags dependency.
11107 [(set (match_operand 0 "register_operand" "")
11108 (ashift (match_operand 1 "index_register_operand" "")
11109 (match_operand:QI 2 "const_int_operand" "")))
11110 (clobber (reg:CC FLAGS_REG))]
11112 && true_regnum (operands[0]) != true_regnum (operands[1])
11113 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11117 enum machine_mode mode = GET_MODE (operands[0]);
11119 if (GET_MODE_SIZE (mode) < 4)
11120 operands[0] = gen_lowpart (SImode, operands[0]);
11122 operands[1] = gen_lowpart (Pmode, operands[1]);
11123 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11125 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11126 if (Pmode != SImode)
11127 pat = gen_rtx_SUBREG (SImode, pat, 0);
11128 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11132 ;; Rare case of shifting RSP is handled by generating move and shift
11134 [(set (match_operand 0 "register_operand" "")
11135 (ashift (match_operand 1 "register_operand" "")
11136 (match_operand:QI 2 "const_int_operand" "")))
11137 (clobber (reg:CC FLAGS_REG))]
11139 && true_regnum (operands[0]) != true_regnum (operands[1])"
11143 emit_move_insn (operands[0], operands[1]);
11144 pat = gen_rtx_SET (VOIDmode, operands[0],
11145 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11146 operands[0], operands[2]));
11147 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11148 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11152 (define_insn "*ashlsi3_1_zext"
11153 [(set (match_operand:DI 0 "register_operand" "=r,r")
11154 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11155 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11156 (clobber (reg:CC FLAGS_REG))]
11157 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11159 switch (get_attr_type (insn))
11162 gcc_assert (operands[2] == const1_rtx);
11163 return "add{l}\t%k0, %k0";
11169 if (REG_P (operands[2]))
11170 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11171 else if (operands[2] == const1_rtx
11172 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11173 return "sal{l}\t%k0";
11175 return "sal{l}\t{%2, %k0|%k0, %2}";
11178 [(set (attr "type")
11179 (cond [(eq_attr "alternative" "1")
11180 (const_string "lea")
11181 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11183 (match_operand 2 "const1_operand" ""))
11184 (const_string "alu")
11186 (const_string "ishift")))
11187 (set (attr "length_immediate")
11189 (ior (eq_attr "type" "alu")
11190 (and (eq_attr "type" "ishift")
11191 (and (match_operand 2 "const1_operand" "")
11192 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11195 (const_string "*")))
11196 (set_attr "mode" "SI")])
11198 ;; Convert lea to the lea pattern to avoid flags dependency.
11200 [(set (match_operand:DI 0 "register_operand" "")
11201 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11202 (match_operand:QI 2 "const_int_operand" ""))))
11203 (clobber (reg:CC FLAGS_REG))]
11204 "TARGET_64BIT && reload_completed
11205 && true_regnum (operands[0]) != true_regnum (operands[1])"
11206 [(set (match_dup 0) (zero_extend:DI
11207 (subreg:SI (mult:SI (match_dup 1)
11208 (match_dup 2)) 0)))]
11210 operands[1] = gen_lowpart (Pmode, operands[1]);
11211 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11214 ;; This pattern can't accept a variable shift count, since shifts by
11215 ;; zero don't affect the flags. We assume that shifts by constant
11216 ;; zero are optimized away.
11217 (define_insn "*ashlsi3_cmp"
11218 [(set (reg FLAGS_REG)
11220 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11221 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11223 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11224 (ashift:SI (match_dup 1) (match_dup 2)))]
11225 "(optimize_function_for_size_p (cfun)
11226 || !TARGET_PARTIAL_FLAG_REG_STALL
11227 || (operands[2] == const1_rtx
11229 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11230 && ix86_match_ccmode (insn, CCGOCmode)
11231 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11233 switch (get_attr_type (insn))
11236 gcc_assert (operands[2] == const1_rtx);
11237 return "add{l}\t%0, %0";
11240 if (REG_P (operands[2]))
11241 return "sal{l}\t{%b2, %0|%0, %b2}";
11242 else if (operands[2] == const1_rtx
11243 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11244 return "sal{l}\t%0";
11246 return "sal{l}\t{%2, %0|%0, %2}";
11249 [(set (attr "type")
11250 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11252 (match_operand 0 "register_operand" ""))
11253 (match_operand 2 "const1_operand" ""))
11254 (const_string "alu")
11256 (const_string "ishift")))
11257 (set (attr "length_immediate")
11259 (ior (eq_attr "type" "alu")
11260 (and (eq_attr "type" "ishift")
11261 (and (match_operand 2 "const1_operand" "")
11262 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11265 (const_string "*")))
11266 (set_attr "mode" "SI")])
11268 (define_insn "*ashlsi3_cconly"
11269 [(set (reg FLAGS_REG)
11271 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11272 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11274 (clobber (match_scratch:SI 0 "=r"))]
11275 "(optimize_function_for_size_p (cfun)
11276 || !TARGET_PARTIAL_FLAG_REG_STALL
11277 || (operands[2] == const1_rtx
11279 || TARGET_DOUBLE_WITH_ADD)))
11280 && ix86_match_ccmode (insn, CCGOCmode)
11281 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11283 switch (get_attr_type (insn))
11286 gcc_assert (operands[2] == const1_rtx);
11287 return "add{l}\t%0, %0";
11290 if (REG_P (operands[2]))
11291 return "sal{l}\t{%b2, %0|%0, %b2}";
11292 else if (operands[2] == const1_rtx
11293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11294 return "sal{l}\t%0";
11296 return "sal{l}\t{%2, %0|%0, %2}";
11299 [(set (attr "type")
11300 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11302 (match_operand 0 "register_operand" ""))
11303 (match_operand 2 "const1_operand" ""))
11304 (const_string "alu")
11306 (const_string "ishift")))
11307 (set (attr "length_immediate")
11309 (ior (eq_attr "type" "alu")
11310 (and (eq_attr "type" "ishift")
11311 (and (match_operand 2 "const1_operand" "")
11312 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11315 (const_string "*")))
11316 (set_attr "mode" "SI")])
11318 (define_insn "*ashlsi3_cmp_zext"
11319 [(set (reg FLAGS_REG)
11321 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11322 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11324 (set (match_operand:DI 0 "register_operand" "=r")
11325 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11327 && (optimize_function_for_size_p (cfun)
11328 || !TARGET_PARTIAL_FLAG_REG_STALL
11329 || (operands[2] == const1_rtx
11331 || TARGET_DOUBLE_WITH_ADD)))
11332 && ix86_match_ccmode (insn, CCGOCmode)
11333 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11335 switch (get_attr_type (insn))
11338 gcc_assert (operands[2] == const1_rtx);
11339 return "add{l}\t%k0, %k0";
11342 if (REG_P (operands[2]))
11343 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11344 else if (operands[2] == const1_rtx
11345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11346 return "sal{l}\t%k0";
11348 return "sal{l}\t{%2, %k0|%k0, %2}";
11351 [(set (attr "type")
11352 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11354 (match_operand 2 "const1_operand" ""))
11355 (const_string "alu")
11357 (const_string "ishift")))
11358 (set (attr "length_immediate")
11360 (ior (eq_attr "type" "alu")
11361 (and (eq_attr "type" "ishift")
11362 (and (match_operand 2 "const1_operand" "")
11363 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11366 (const_string "*")))
11367 (set_attr "mode" "SI")])
11369 (define_expand "ashlhi3"
11370 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11371 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))]
11373 "TARGET_HIMODE_MATH"
11374 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11376 (define_insn "*ashlhi3_1_lea"
11377 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11378 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11379 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "!TARGET_PARTIAL_REG_STALL
11382 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11384 switch (get_attr_type (insn))
11389 gcc_assert (operands[2] == const1_rtx);
11390 return "add{w}\t%0, %0";
11393 if (REG_P (operands[2]))
11394 return "sal{w}\t{%b2, %0|%0, %b2}";
11395 else if (operands[2] == const1_rtx
11396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11397 return "sal{w}\t%0";
11399 return "sal{w}\t{%2, %0|%0, %2}";
11402 [(set (attr "type")
11403 (cond [(eq_attr "alternative" "1")
11404 (const_string "lea")
11405 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11407 (match_operand 0 "register_operand" ""))
11408 (match_operand 2 "const1_operand" ""))
11409 (const_string "alu")
11411 (const_string "ishift")))
11412 (set (attr "length_immediate")
11414 (ior (eq_attr "type" "alu")
11415 (and (eq_attr "type" "ishift")
11416 (and (match_operand 2 "const1_operand" "")
11417 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11420 (const_string "*")))
11421 (set_attr "mode" "HI,SI")])
11423 (define_insn "*ashlhi3_1"
11424 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11426 (match_operand:QI 2 "nonmemory_operand" "cI")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "TARGET_PARTIAL_REG_STALL
11429 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11431 switch (get_attr_type (insn))
11434 gcc_assert (operands[2] == const1_rtx);
11435 return "add{w}\t%0, %0";
11438 if (REG_P (operands[2]))
11439 return "sal{w}\t{%b2, %0|%0, %b2}";
11440 else if (operands[2] == const1_rtx
11441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11442 return "sal{w}\t%0";
11444 return "sal{w}\t{%2, %0|%0, %2}";
11447 [(set (attr "type")
11448 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11450 (match_operand 0 "register_operand" ""))
11451 (match_operand 2 "const1_operand" ""))
11452 (const_string "alu")
11454 (const_string "ishift")))
11455 (set (attr "length_immediate")
11457 (ior (eq_attr "type" "alu")
11458 (and (eq_attr "type" "ishift")
11459 (and (match_operand 2 "const1_operand" "")
11460 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11463 (const_string "*")))
11464 (set_attr "mode" "HI")])
11466 ;; This pattern can't accept a variable shift count, since shifts by
11467 ;; zero don't affect the flags. We assume that shifts by constant
11468 ;; zero are optimized away.
11469 (define_insn "*ashlhi3_cmp"
11470 [(set (reg FLAGS_REG)
11472 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11473 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11475 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11476 (ashift:HI (match_dup 1) (match_dup 2)))]
11477 "(optimize_function_for_size_p (cfun)
11478 || !TARGET_PARTIAL_FLAG_REG_STALL
11479 || (operands[2] == const1_rtx
11481 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11482 && ix86_match_ccmode (insn, CCGOCmode)
11483 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11485 switch (get_attr_type (insn))
11488 gcc_assert (operands[2] == const1_rtx);
11489 return "add{w}\t%0, %0";
11492 if (REG_P (operands[2]))
11493 return "sal{w}\t{%b2, %0|%0, %b2}";
11494 else if (operands[2] == const1_rtx
11495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11496 return "sal{w}\t%0";
11498 return "sal{w}\t{%2, %0|%0, %2}";
11501 [(set (attr "type")
11502 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11504 (match_operand 0 "register_operand" ""))
11505 (match_operand 2 "const1_operand" ""))
11506 (const_string "alu")
11508 (const_string "ishift")))
11509 (set (attr "length_immediate")
11511 (ior (eq_attr "type" "alu")
11512 (and (eq_attr "type" "ishift")
11513 (and (match_operand 2 "const1_operand" "")
11514 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11517 (const_string "*")))
11518 (set_attr "mode" "HI")])
11520 (define_insn "*ashlhi3_cconly"
11521 [(set (reg FLAGS_REG)
11523 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11524 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11526 (clobber (match_scratch:HI 0 "=r"))]
11527 "(optimize_function_for_size_p (cfun)
11528 || !TARGET_PARTIAL_FLAG_REG_STALL
11529 || (operands[2] == const1_rtx
11531 || TARGET_DOUBLE_WITH_ADD)))
11532 && ix86_match_ccmode (insn, CCGOCmode)
11533 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11535 switch (get_attr_type (insn))
11538 gcc_assert (operands[2] == const1_rtx);
11539 return "add{w}\t%0, %0";
11542 if (REG_P (operands[2]))
11543 return "sal{w}\t{%b2, %0|%0, %b2}";
11544 else if (operands[2] == const1_rtx
11545 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11546 return "sal{w}\t%0";
11548 return "sal{w}\t{%2, %0|%0, %2}";
11551 [(set (attr "type")
11552 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11554 (match_operand 0 "register_operand" ""))
11555 (match_operand 2 "const1_operand" ""))
11556 (const_string "alu")
11558 (const_string "ishift")))
11559 (set (attr "length_immediate")
11561 (ior (eq_attr "type" "alu")
11562 (and (eq_attr "type" "ishift")
11563 (and (match_operand 2 "const1_operand" "")
11564 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11567 (const_string "*")))
11568 (set_attr "mode" "HI")])
11570 (define_expand "ashlqi3"
11571 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11572 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11573 (match_operand:QI 2 "nonmemory_operand" "")))]
11574 "TARGET_QIMODE_MATH"
11575 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11577 ;; %%% Potential partial reg stall on alternative 2. What to do?
11579 (define_insn "*ashlqi3_1_lea"
11580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11581 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11582 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11583 (clobber (reg:CC FLAGS_REG))]
11584 "!TARGET_PARTIAL_REG_STALL
11585 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11587 switch (get_attr_type (insn))
11592 gcc_assert (operands[2] == const1_rtx);
11593 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11594 return "add{l}\t%k0, %k0";
11596 return "add{b}\t%0, %0";
11599 if (REG_P (operands[2]))
11601 if (get_attr_mode (insn) == MODE_SI)
11602 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11604 return "sal{b}\t{%b2, %0|%0, %b2}";
11606 else if (operands[2] == const1_rtx
11607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11609 if (get_attr_mode (insn) == MODE_SI)
11610 return "sal{l}\t%0";
11612 return "sal{b}\t%0";
11616 if (get_attr_mode (insn) == MODE_SI)
11617 return "sal{l}\t{%2, %k0|%k0, %2}";
11619 return "sal{b}\t{%2, %0|%0, %2}";
11623 [(set (attr "type")
11624 (cond [(eq_attr "alternative" "2")
11625 (const_string "lea")
11626 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11628 (match_operand 0 "register_operand" ""))
11629 (match_operand 2 "const1_operand" ""))
11630 (const_string "alu")
11632 (const_string "ishift")))
11633 (set (attr "length_immediate")
11635 (ior (eq_attr "type" "alu")
11636 (and (eq_attr "type" "ishift")
11637 (and (match_operand 2 "const1_operand" "")
11638 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11641 (const_string "*")))
11642 (set_attr "mode" "QI,SI,SI")])
11644 (define_insn "*ashlqi3_1"
11645 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11646 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11647 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11648 (clobber (reg:CC FLAGS_REG))]
11649 "TARGET_PARTIAL_REG_STALL
11650 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11652 switch (get_attr_type (insn))
11655 gcc_assert (operands[2] == const1_rtx);
11656 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11657 return "add{l}\t%k0, %k0";
11659 return "add{b}\t%0, %0";
11662 if (REG_P (operands[2]))
11664 if (get_attr_mode (insn) == MODE_SI)
11665 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11667 return "sal{b}\t{%b2, %0|%0, %b2}";
11669 else if (operands[2] == const1_rtx
11670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11672 if (get_attr_mode (insn) == MODE_SI)
11673 return "sal{l}\t%0";
11675 return "sal{b}\t%0";
11679 if (get_attr_mode (insn) == MODE_SI)
11680 return "sal{l}\t{%2, %k0|%k0, %2}";
11682 return "sal{b}\t{%2, %0|%0, %2}";
11686 [(set (attr "type")
11687 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11689 (match_operand 0 "register_operand" ""))
11690 (match_operand 2 "const1_operand" ""))
11691 (const_string "alu")
11693 (const_string "ishift")))
11694 (set (attr "length_immediate")
11696 (ior (eq_attr "type" "alu")
11697 (and (eq_attr "type" "ishift")
11698 (and (match_operand 2 "const1_operand" "")
11699 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11702 (const_string "*")))
11703 (set_attr "mode" "QI,SI")])
11705 ;; This pattern can't accept a variable shift count, since shifts by
11706 ;; zero don't affect the flags. We assume that shifts by constant
11707 ;; zero are optimized away.
11708 (define_insn "*ashlqi3_cmp"
11709 [(set (reg FLAGS_REG)
11711 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11714 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11715 (ashift:QI (match_dup 1) (match_dup 2)))]
11716 "(optimize_function_for_size_p (cfun)
11717 || !TARGET_PARTIAL_FLAG_REG_STALL
11718 || (operands[2] == const1_rtx
11720 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11721 && ix86_match_ccmode (insn, CCGOCmode)
11722 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11724 switch (get_attr_type (insn))
11727 gcc_assert (operands[2] == const1_rtx);
11728 return "add{b}\t%0, %0";
11731 if (REG_P (operands[2]))
11732 return "sal{b}\t{%b2, %0|%0, %b2}";
11733 else if (operands[2] == const1_rtx
11734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11735 return "sal{b}\t%0";
11737 return "sal{b}\t{%2, %0|%0, %2}";
11740 [(set (attr "type")
11741 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11743 (match_operand 0 "register_operand" ""))
11744 (match_operand 2 "const1_operand" ""))
11745 (const_string "alu")
11747 (const_string "ishift")))
11748 (set (attr "length_immediate")
11750 (ior (eq_attr "type" "alu")
11751 (and (eq_attr "type" "ishift")
11752 (and (match_operand 2 "const1_operand" "")
11753 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11756 (const_string "*")))
11757 (set_attr "mode" "QI")])
11759 (define_insn "*ashlqi3_cconly"
11760 [(set (reg FLAGS_REG)
11762 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11763 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11765 (clobber (match_scratch:QI 0 "=q"))]
11766 "(optimize_function_for_size_p (cfun)
11767 || !TARGET_PARTIAL_FLAG_REG_STALL
11768 || (operands[2] == const1_rtx
11770 || TARGET_DOUBLE_WITH_ADD)))
11771 && ix86_match_ccmode (insn, CCGOCmode)
11772 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11774 switch (get_attr_type (insn))
11777 gcc_assert (operands[2] == const1_rtx);
11778 return "add{b}\t%0, %0";
11781 if (REG_P (operands[2]))
11782 return "sal{b}\t{%b2, %0|%0, %b2}";
11783 else if (operands[2] == const1_rtx
11784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11785 return "sal{b}\t%0";
11787 return "sal{b}\t{%2, %0|%0, %2}";
11790 [(set (attr "type")
11791 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11793 (match_operand 0 "register_operand" ""))
11794 (match_operand 2 "const1_operand" ""))
11795 (const_string "alu")
11797 (const_string "ishift")))
11798 (set (attr "length_immediate")
11800 (ior (eq_attr "type" "alu")
11801 (and (eq_attr "type" "ishift")
11802 (and (match_operand 2 "const1_operand" "")
11803 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11806 (const_string "*")))
11807 (set_attr "mode" "QI")])
11809 ;; See comment above `ashldi3' about how this works.
11811 (define_expand "ashrti3"
11812 [(set (match_operand:TI 0 "register_operand" "")
11813 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11814 (match_operand:QI 2 "nonmemory_operand" "")))]
11816 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11818 (define_insn "*ashrti3_1"
11819 [(set (match_operand:TI 0 "register_operand" "=r")
11820 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11821 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11822 (clobber (reg:CC FLAGS_REG))]
11825 [(set_attr "type" "multi")])
11828 [(match_scratch:DI 3 "r")
11829 (parallel [(set (match_operand:TI 0 "register_operand" "")
11830 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11831 (match_operand:QI 2 "nonmemory_operand" "")))
11832 (clobber (reg:CC FLAGS_REG))])
11836 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11839 [(set (match_operand:TI 0 "register_operand" "")
11840 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11841 (match_operand:QI 2 "nonmemory_operand" "")))
11842 (clobber (reg:CC FLAGS_REG))]
11843 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11844 ? epilogue_completed : reload_completed)"
11846 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11848 (define_insn "x86_64_shrd"
11849 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11850 (ior:DI (ashiftrt:DI (match_dup 0)
11851 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11852 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11853 (minus:QI (const_int 64) (match_dup 2)))))
11854 (clobber (reg:CC FLAGS_REG))]
11856 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11857 [(set_attr "type" "ishift")
11858 (set_attr "prefix_0f" "1")
11859 (set_attr "mode" "DI")
11860 (set_attr "athlon_decode" "vector")
11861 (set_attr "amdfam10_decode" "vector")])
11863 (define_expand "ashrdi3"
11864 [(set (match_operand:DI 0 "shiftdi_operand" "")
11865 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11866 (match_operand:QI 2 "nonmemory_operand" "")))]
11868 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11870 (define_expand "x86_64_shift_adj_3"
11871 [(use (match_operand:DI 0 "register_operand" ""))
11872 (use (match_operand:DI 1 "register_operand" ""))
11873 (use (match_operand:QI 2 "register_operand" ""))]
11876 rtx label = gen_label_rtx ();
11879 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11881 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11882 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11883 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11884 gen_rtx_LABEL_REF (VOIDmode, label),
11886 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11887 JUMP_LABEL (tmp) = label;
11889 emit_move_insn (operands[0], operands[1]);
11890 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11892 emit_label (label);
11893 LABEL_NUSES (label) = 1;
11898 (define_insn "ashrdi3_63_rex64"
11899 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11900 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11901 (match_operand:DI 2 "const_int_operand" "i,i")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "TARGET_64BIT && INTVAL (operands[2]) == 63
11904 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11905 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11908 sar{q}\t{%2, %0|%0, %2}"
11909 [(set_attr "type" "imovx,ishift")
11910 (set_attr "prefix_0f" "0,*")
11911 (set_attr "length_immediate" "0,*")
11912 (set_attr "modrm" "0,1")
11913 (set_attr "mode" "DI")])
11915 (define_insn "*ashrdi3_1_one_bit_rex64"
11916 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11917 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11918 (match_operand:QI 2 "const1_operand" "")))
11919 (clobber (reg:CC FLAGS_REG))]
11921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11922 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11924 [(set_attr "type" "ishift")
11925 (set_attr "length_immediate" "0")
11926 (set_attr "mode" "DI")])
11928 (define_insn "*ashrdi3_1_rex64"
11929 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11930 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11931 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11932 (clobber (reg:CC FLAGS_REG))]
11933 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11935 sar{q}\t{%2, %0|%0, %2}
11936 sar{q}\t{%b2, %0|%0, %b2}"
11937 [(set_attr "type" "ishift")
11938 (set_attr "mode" "DI")])
11940 ;; This pattern can't accept a variable shift count, since shifts by
11941 ;; zero don't affect the flags. We assume that shifts by constant
11942 ;; zero are optimized away.
11943 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11944 [(set (reg FLAGS_REG)
11946 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11947 (match_operand:QI 2 "const1_operand" ""))
11949 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11950 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11952 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11953 && ix86_match_ccmode (insn, CCGOCmode)
11954 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11956 [(set_attr "type" "ishift")
11957 (set_attr "length_immediate" "0")
11958 (set_attr "mode" "DI")])
11960 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11961 [(set (reg FLAGS_REG)
11963 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const1_operand" ""))
11966 (clobber (match_scratch:DI 0 "=r"))]
11968 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11969 && ix86_match_ccmode (insn, CCGOCmode)
11970 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11972 [(set_attr "type" "ishift")
11973 (set_attr "length_immediate" "0")
11974 (set_attr "mode" "DI")])
11976 ;; This pattern can't accept a variable shift count, since shifts by
11977 ;; zero don't affect the flags. We assume that shifts by constant
11978 ;; zero are optimized away.
11979 (define_insn "*ashrdi3_cmp_rex64"
11980 [(set (reg FLAGS_REG)
11982 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11983 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11985 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11988 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11989 && ix86_match_ccmode (insn, CCGOCmode)
11990 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11991 "sar{q}\t{%2, %0|%0, %2}"
11992 [(set_attr "type" "ishift")
11993 (set_attr "mode" "DI")])
11995 (define_insn "*ashrdi3_cconly_rex64"
11996 [(set (reg FLAGS_REG)
11998 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11999 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12001 (clobber (match_scratch:DI 0 "=r"))]
12003 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12004 && ix86_match_ccmode (insn, CCGOCmode)
12005 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12006 "sar{q}\t{%2, %0|%0, %2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "DI")])
12010 (define_insn "*ashrdi3_1"
12011 [(set (match_operand:DI 0 "register_operand" "=r")
12012 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12013 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12014 (clobber (reg:CC FLAGS_REG))]
12017 [(set_attr "type" "multi")])
12019 ;; By default we don't ask for a scratch register, because when DImode
12020 ;; values are manipulated, registers are already at a premium. But if
12021 ;; we have one handy, we won't turn it away.
12023 [(match_scratch:SI 3 "r")
12024 (parallel [(set (match_operand:DI 0 "register_operand" "")
12025 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12026 (match_operand:QI 2 "nonmemory_operand" "")))
12027 (clobber (reg:CC FLAGS_REG))])
12029 "!TARGET_64BIT && TARGET_CMOVE"
12031 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12034 [(set (match_operand:DI 0 "register_operand" "")
12035 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12036 (match_operand:QI 2 "nonmemory_operand" "")))
12037 (clobber (reg:CC FLAGS_REG))]
12038 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12039 ? epilogue_completed : reload_completed)"
12041 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12043 (define_insn "x86_shrd"
12044 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12045 (ior:SI (ashiftrt:SI (match_dup 0)
12046 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12047 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12048 (minus:QI (const_int 32) (match_dup 2)))))
12049 (clobber (reg:CC FLAGS_REG))]
12051 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "prefix_0f" "1")
12054 (set_attr "pent_pair" "np")
12055 (set_attr "mode" "SI")])
12057 (define_expand "x86_shift_adj_3"
12058 [(use (match_operand:SI 0 "register_operand" ""))
12059 (use (match_operand:SI 1 "register_operand" ""))
12060 (use (match_operand:QI 2 "register_operand" ""))]
12063 rtx label = gen_label_rtx ();
12066 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12068 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12069 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12070 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12071 gen_rtx_LABEL_REF (VOIDmode, label),
12073 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12074 JUMP_LABEL (tmp) = label;
12076 emit_move_insn (operands[0], operands[1]);
12077 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12079 emit_label (label);
12080 LABEL_NUSES (label) = 1;
12085 (define_expand "ashrsi3_31"
12086 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12087 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12088 (match_operand:SI 2 "const_int_operand" "i,i")))
12089 (clobber (reg:CC FLAGS_REG))])]
12092 (define_insn "*ashrsi3_31"
12093 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12094 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12095 (match_operand:SI 2 "const_int_operand" "i,i")))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "INTVAL (operands[2]) == 31
12098 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12099 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12102 sar{l}\t{%2, %0|%0, %2}"
12103 [(set_attr "type" "imovx,ishift")
12104 (set_attr "prefix_0f" "0,*")
12105 (set_attr "length_immediate" "0,*")
12106 (set_attr "modrm" "0,1")
12107 (set_attr "mode" "SI")])
12109 (define_insn "*ashrsi3_31_zext"
12110 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12111 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12112 (match_operand:SI 2 "const_int_operand" "i,i"))))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12115 && INTVAL (operands[2]) == 31
12116 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12119 sar{l}\t{%2, %k0|%k0, %2}"
12120 [(set_attr "type" "imovx,ishift")
12121 (set_attr "prefix_0f" "0,*")
12122 (set_attr "length_immediate" "0,*")
12123 (set_attr "modrm" "0,1")
12124 (set_attr "mode" "SI")])
12126 (define_expand "ashrsi3"
12127 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12128 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12129 (match_operand:QI 2 "nonmemory_operand" "")))]
12131 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12133 (define_insn "*ashrsi3_1_one_bit"
12134 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12135 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12136 (match_operand:QI 2 "const1_operand" "")))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12139 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12141 [(set_attr "type" "ishift")
12142 (set_attr "length_immediate" "0")
12143 (set_attr "mode" "SI")])
12145 (define_insn "*ashrsi3_1_one_bit_zext"
12146 [(set (match_operand:DI 0 "register_operand" "=r")
12147 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12148 (match_operand:QI 2 "const1_operand" ""))))
12149 (clobber (reg:CC FLAGS_REG))]
12151 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12152 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12154 [(set_attr "type" "ishift")
12155 (set_attr "length_immediate" "0")
12156 (set_attr "mode" "SI")])
12158 (define_insn "*ashrsi3_1"
12159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12160 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12161 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12165 sar{l}\t{%2, %0|%0, %2}
12166 sar{l}\t{%b2, %0|%0, %b2}"
12167 [(set_attr "type" "ishift")
12168 (set_attr "mode" "SI")])
12170 (define_insn "*ashrsi3_1_zext"
12171 [(set (match_operand:DI 0 "register_operand" "=r,r")
12172 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12177 sar{l}\t{%2, %k0|%k0, %2}
12178 sar{l}\t{%b2, %k0|%k0, %b2}"
12179 [(set_attr "type" "ishift")
12180 (set_attr "mode" "SI")])
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrsi3_one_bit_cmp"
12186 [(set (reg FLAGS_REG)
12188 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" ""))
12191 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12192 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12193 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12194 && ix86_match_ccmode (insn, CCGOCmode)
12195 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set_attr "length_immediate" "0")
12199 (set_attr "mode" "SI")])
12201 (define_insn "*ashrsi3_one_bit_cconly"
12202 [(set (reg FLAGS_REG)
12204 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12205 (match_operand:QI 2 "const1_operand" ""))
12207 (clobber (match_scratch:SI 0 "=r"))]
12208 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12209 && ix86_match_ccmode (insn, CCGOCmode)
12210 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12212 [(set_attr "type" "ishift")
12213 (set_attr "length_immediate" "0")
12214 (set_attr "mode" "SI")])
12216 (define_insn "*ashrsi3_one_bit_cmp_zext"
12217 [(set (reg FLAGS_REG)
12219 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12220 (match_operand:QI 2 "const1_operand" ""))
12222 (set (match_operand:DI 0 "register_operand" "=r")
12223 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12225 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12226 && ix86_match_ccmode (insn, CCmode)
12227 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12229 [(set_attr "type" "ishift")
12230 (set_attr "length_immediate" "0")
12231 (set_attr "mode" "SI")])
12233 ;; This pattern can't accept a variable shift count, since shifts by
12234 ;; zero don't affect the flags. We assume that shifts by constant
12235 ;; zero are optimized away.
12236 (define_insn "*ashrsi3_cmp"
12237 [(set (reg FLAGS_REG)
12239 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12242 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12243 (ashiftrt:SI (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, SImode, operands)"
12247 "sar{l}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "SI")])
12251 (define_insn "*ashrsi3_cconly"
12252 [(set (reg FLAGS_REG)
12254 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12255 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12257 (clobber (match_scratch:SI 0 "=r"))]
12258 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12259 && ix86_match_ccmode (insn, CCGOCmode)
12260 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12261 "sar{l}\t{%2, %0|%0, %2}"
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "SI")])
12265 (define_insn "*ashrsi3_cmp_zext"
12266 [(set (reg FLAGS_REG)
12268 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12269 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12271 (set (match_operand:DI 0 "register_operand" "=r")
12272 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12274 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12275 && ix86_match_ccmode (insn, CCGOCmode)
12276 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12277 "sar{l}\t{%2, %k0|%k0, %2}"
12278 [(set_attr "type" "ishift")
12279 (set_attr "mode" "SI")])
12281 (define_expand "ashrhi3"
12282 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12283 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12284 (match_operand:QI 2 "nonmemory_operand" "")))]
12285 "TARGET_HIMODE_MATH"
12286 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12288 (define_insn "*ashrhi3_1_one_bit"
12289 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12290 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12291 (match_operand:QI 2 "const1_operand" "")))
12292 (clobber (reg:CC FLAGS_REG))]
12293 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12294 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12296 [(set_attr "type" "ishift")
12297 (set_attr "length_immediate" "0")
12298 (set_attr "mode" "HI")])
12300 (define_insn "*ashrhi3_1"
12301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12302 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12303 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12307 sar{w}\t{%2, %0|%0, %2}
12308 sar{w}\t{%b2, %0|%0, %b2}"
12309 [(set_attr "type" "ishift")
12310 (set_attr "mode" "HI")])
12312 ;; This pattern can't accept a variable shift count, since shifts by
12313 ;; zero don't affect the flags. We assume that shifts by constant
12314 ;; zero are optimized away.
12315 (define_insn "*ashrhi3_one_bit_cmp"
12316 [(set (reg FLAGS_REG)
12318 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12319 (match_operand:QI 2 "const1_operand" ""))
12321 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12322 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12323 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12324 && ix86_match_ccmode (insn, CCGOCmode)
12325 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12327 [(set_attr "type" "ishift")
12328 (set_attr "length_immediate" "0")
12329 (set_attr "mode" "HI")])
12331 (define_insn "*ashrhi3_one_bit_cconly"
12332 [(set (reg FLAGS_REG)
12334 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12335 (match_operand:QI 2 "const1_operand" ""))
12337 (clobber (match_scratch:HI 0 "=r"))]
12338 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12339 && ix86_match_ccmode (insn, CCGOCmode)
12340 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12342 [(set_attr "type" "ishift")
12343 (set_attr "length_immediate" "0")
12344 (set_attr "mode" "HI")])
12346 ;; This pattern can't accept a variable shift count, since shifts by
12347 ;; zero don't affect the flags. We assume that shifts by constant
12348 ;; zero are optimized away.
12349 (define_insn "*ashrhi3_cmp"
12350 [(set (reg FLAGS_REG)
12352 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12355 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12356 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12357 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12358 && ix86_match_ccmode (insn, CCGOCmode)
12359 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12360 "sar{w}\t{%2, %0|%0, %2}"
12361 [(set_attr "type" "ishift")
12362 (set_attr "mode" "HI")])
12364 (define_insn "*ashrhi3_cconly"
12365 [(set (reg FLAGS_REG)
12367 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12370 (clobber (match_scratch:HI 0 "=r"))]
12371 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12372 && ix86_match_ccmode (insn, CCGOCmode)
12373 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12374 "sar{w}\t{%2, %0|%0, %2}"
12375 [(set_attr "type" "ishift")
12376 (set_attr "mode" "HI")])
12378 (define_expand "ashrqi3"
12379 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12380 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))]
12382 "TARGET_QIMODE_MATH"
12383 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12385 (define_insn "*ashrqi3_1_one_bit"
12386 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12387 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12388 (match_operand:QI 2 "const1_operand" "")))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12391 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12393 [(set_attr "type" "ishift")
12394 (set_attr "length_immediate" "0")
12395 (set_attr "mode" "QI")])
12397 (define_insn "*ashrqi3_1_one_bit_slp"
12398 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12399 (ashiftrt:QI (match_dup 0)
12400 (match_operand:QI 1 "const1_operand" "")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12403 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12404 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12406 [(set_attr "type" "ishift1")
12407 (set_attr "length_immediate" "0")
12408 (set_attr "mode" "QI")])
12410 (define_insn "*ashrqi3_1"
12411 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12412 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12413 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12414 (clobber (reg:CC FLAGS_REG))]
12415 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12417 sar{b}\t{%2, %0|%0, %2}
12418 sar{b}\t{%b2, %0|%0, %b2}"
12419 [(set_attr "type" "ishift")
12420 (set_attr "mode" "QI")])
12422 (define_insn "*ashrqi3_1_slp"
12423 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12424 (ashiftrt:QI (match_dup 0)
12425 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12426 (clobber (reg:CC FLAGS_REG))]
12427 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12430 sar{b}\t{%1, %0|%0, %1}
12431 sar{b}\t{%b1, %0|%0, %b1}"
12432 [(set_attr "type" "ishift1")
12433 (set_attr "mode" "QI")])
12435 ;; This pattern can't accept a variable shift count, since shifts by
12436 ;; zero don't affect the flags. We assume that shifts by constant
12437 ;; zero are optimized away.
12438 (define_insn "*ashrqi3_one_bit_cmp"
12439 [(set (reg FLAGS_REG)
12441 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12442 (match_operand:QI 2 "const1_operand" "I"))
12444 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12445 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12446 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12447 && ix86_match_ccmode (insn, CCGOCmode)
12448 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12450 [(set_attr "type" "ishift")
12451 (set_attr "length_immediate" "0")
12452 (set_attr "mode" "QI")])
12454 (define_insn "*ashrqi3_one_bit_cconly"
12455 [(set (reg FLAGS_REG)
12457 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12458 (match_operand:QI 2 "const1_operand" ""))
12460 (clobber (match_scratch:QI 0 "=q"))]
12461 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12462 && ix86_match_ccmode (insn, CCGOCmode)
12463 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12465 [(set_attr "type" "ishift")
12466 (set_attr "length_immediate" "0")
12467 (set_attr "mode" "QI")])
12469 ;; This pattern can't accept a variable shift count, since shifts by
12470 ;; zero don't affect the flags. We assume that shifts by constant
12471 ;; zero are optimized away.
12472 (define_insn "*ashrqi3_cmp"
12473 [(set (reg FLAGS_REG)
12475 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12478 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12479 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12480 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12481 && ix86_match_ccmode (insn, CCGOCmode)
12482 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12483 "sar{b}\t{%2, %0|%0, %2}"
12484 [(set_attr "type" "ishift")
12485 (set_attr "mode" "QI")])
12487 (define_insn "*ashrqi3_cconly"
12488 [(set (reg FLAGS_REG)
12490 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12493 (clobber (match_scratch:QI 0 "=q"))]
12494 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12495 && ix86_match_ccmode (insn, CCGOCmode)
12496 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12497 "sar{b}\t{%2, %0|%0, %2}"
12498 [(set_attr "type" "ishift")
12499 (set_attr "mode" "QI")])
12502 ;; Logical shift instructions
12504 ;; See comment above `ashldi3' about how this works.
12506 (define_expand "lshrti3"
12507 [(set (match_operand:TI 0 "register_operand" "")
12508 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12509 (match_operand:QI 2 "nonmemory_operand" "")))]
12511 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12513 ;; This pattern must be defined before *lshrti3_1 to prevent
12514 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12516 (define_insn "*avx_lshrti3"
12517 [(set (match_operand:TI 0 "register_operand" "=x")
12518 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12519 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12522 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12523 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12525 [(set_attr "type" "sseishft")
12526 (set_attr "prefix" "vex")
12527 (set_attr "length_immediate" "1")
12528 (set_attr "mode" "TI")])
12530 (define_insn "sse2_lshrti3"
12531 [(set (match_operand:TI 0 "register_operand" "=x")
12532 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12533 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12536 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12537 return "psrldq\t{%2, %0|%0, %2}";
12539 [(set_attr "type" "sseishft")
12540 (set_attr "prefix_data16" "1")
12541 (set_attr "length_immediate" "1")
12542 (set_attr "mode" "TI")])
12544 (define_insn "*lshrti3_1"
12545 [(set (match_operand:TI 0 "register_operand" "=r")
12546 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12547 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12548 (clobber (reg:CC FLAGS_REG))]
12551 [(set_attr "type" "multi")])
12554 [(match_scratch:DI 3 "r")
12555 (parallel [(set (match_operand:TI 0 "register_operand" "")
12556 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12557 (match_operand:QI 2 "nonmemory_operand" "")))
12558 (clobber (reg:CC FLAGS_REG))])
12562 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12565 [(set (match_operand:TI 0 "register_operand" "")
12566 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12567 (match_operand:QI 2 "nonmemory_operand" "")))
12568 (clobber (reg:CC FLAGS_REG))]
12569 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12570 ? epilogue_completed : reload_completed)"
12572 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12574 (define_expand "lshrdi3"
12575 [(set (match_operand:DI 0 "shiftdi_operand" "")
12576 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12577 (match_operand:QI 2 "nonmemory_operand" "")))]
12579 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12581 (define_insn "*lshrdi3_1_one_bit_rex64"
12582 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12583 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12584 (match_operand:QI 2 "const1_operand" "")))
12585 (clobber (reg:CC FLAGS_REG))]
12587 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12588 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12590 [(set_attr "type" "ishift")
12591 (set_attr "length_immediate" "0")
12592 (set_attr "mode" "DI")])
12594 (define_insn "*lshrdi3_1_rex64"
12595 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12596 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12597 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12601 shr{q}\t{%2, %0|%0, %2}
12602 shr{q}\t{%b2, %0|%0, %b2}"
12603 [(set_attr "type" "ishift")
12604 (set_attr "mode" "DI")])
12606 ;; This pattern can't accept a variable shift count, since shifts by
12607 ;; zero don't affect the flags. We assume that shifts by constant
12608 ;; zero are optimized away.
12609 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const1_operand" ""))
12615 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12616 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12618 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12619 && ix86_match_ccmode (insn, CCGOCmode)
12620 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12622 [(set_attr "type" "ishift")
12623 (set_attr "length_immediate" "0")
12624 (set_attr "mode" "DI")])
12626 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12627 [(set (reg FLAGS_REG)
12629 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12630 (match_operand:QI 2 "const1_operand" ""))
12632 (clobber (match_scratch:DI 0 "=r"))]
12634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12635 && ix86_match_ccmode (insn, CCGOCmode)
12636 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12638 [(set_attr "type" "ishift")
12639 (set_attr "length_immediate" "0")
12640 (set_attr "mode" "DI")])
12642 ;; This pattern can't accept a variable shift count, since shifts by
12643 ;; zero don't affect the flags. We assume that shifts by constant
12644 ;; zero are optimized away.
12645 (define_insn "*lshrdi3_cmp_rex64"
12646 [(set (reg FLAGS_REG)
12648 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12649 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12651 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12652 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12654 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12655 && ix86_match_ccmode (insn, CCGOCmode)
12656 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12657 "shr{q}\t{%2, %0|%0, %2}"
12658 [(set_attr "type" "ishift")
12659 (set_attr "mode" "DI")])
12661 (define_insn "*lshrdi3_cconly_rex64"
12662 [(set (reg FLAGS_REG)
12664 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12665 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12667 (clobber (match_scratch:DI 0 "=r"))]
12669 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12670 && ix86_match_ccmode (insn, CCGOCmode)
12671 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12672 "shr{q}\t{%2, %0|%0, %2}"
12673 [(set_attr "type" "ishift")
12674 (set_attr "mode" "DI")])
12676 (define_insn "*lshrdi3_1"
12677 [(set (match_operand:DI 0 "register_operand" "=r")
12678 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12679 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12680 (clobber (reg:CC FLAGS_REG))]
12683 [(set_attr "type" "multi")])
12685 ;; By default we don't ask for a scratch register, because when DImode
12686 ;; values are manipulated, registers are already at a premium. But if
12687 ;; we have one handy, we won't turn it away.
12689 [(match_scratch:SI 3 "r")
12690 (parallel [(set (match_operand:DI 0 "register_operand" "")
12691 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12692 (match_operand:QI 2 "nonmemory_operand" "")))
12693 (clobber (reg:CC FLAGS_REG))])
12695 "!TARGET_64BIT && TARGET_CMOVE"
12697 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12700 [(set (match_operand:DI 0 "register_operand" "")
12701 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12702 (match_operand:QI 2 "nonmemory_operand" "")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12705 ? epilogue_completed : reload_completed)"
12707 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12709 (define_expand "lshrsi3"
12710 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12711 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12712 (match_operand:QI 2 "nonmemory_operand" "")))]
12714 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12716 (define_insn "*lshrsi3_1_one_bit"
12717 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12718 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12719 (match_operand:QI 2 "const1_operand" "")))
12720 (clobber (reg:CC FLAGS_REG))]
12721 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12722 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12724 [(set_attr "type" "ishift")
12725 (set_attr "length_immediate" "0")
12726 (set_attr "mode" "SI")])
12728 (define_insn "*lshrsi3_1_one_bit_zext"
12729 [(set (match_operand:DI 0 "register_operand" "=r")
12730 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12731 (match_operand:QI 2 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12735 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12737 [(set_attr "type" "ishift")
12738 (set_attr "length_immediate" "0")
12739 (set_attr "mode" "SI")])
12741 (define_insn "*lshrsi3_1"
12742 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12743 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12744 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12745 (clobber (reg:CC FLAGS_REG))]
12746 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12748 shr{l}\t{%2, %0|%0, %2}
12749 shr{l}\t{%b2, %0|%0, %b2}"
12750 [(set_attr "type" "ishift")
12751 (set_attr "mode" "SI")])
12753 (define_insn "*lshrsi3_1_zext"
12754 [(set (match_operand:DI 0 "register_operand" "=r,r")
12756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12757 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12761 shr{l}\t{%2, %k0|%k0, %2}
12762 shr{l}\t{%b2, %k0|%k0, %b2}"
12763 [(set_attr "type" "ishift")
12764 (set_attr "mode" "SI")])
12766 ;; This pattern can't accept a variable shift count, since shifts by
12767 ;; zero don't affect the flags. We assume that shifts by constant
12768 ;; zero are optimized away.
12769 (define_insn "*lshrsi3_one_bit_cmp"
12770 [(set (reg FLAGS_REG)
12772 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const1_operand" ""))
12775 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12776 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12777 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12778 && ix86_match_ccmode (insn, CCGOCmode)
12779 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 [(set_attr "type" "ishift")
12782 (set_attr "length_immediate" "0")
12783 (set_attr "mode" "SI")])
12785 (define_insn "*lshrsi3_one_bit_cconly"
12786 [(set (reg FLAGS_REG)
12788 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12789 (match_operand:QI 2 "const1_operand" ""))
12791 (clobber (match_scratch:SI 0 "=r"))]
12792 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12793 && ix86_match_ccmode (insn, CCGOCmode)
12794 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12796 [(set_attr "type" "ishift")
12797 (set_attr "length_immediate" "0")
12798 (set_attr "mode" "SI")])
12800 (define_insn "*lshrsi3_cmp_one_bit_zext"
12801 [(set (reg FLAGS_REG)
12803 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12804 (match_operand:QI 2 "const1_operand" ""))
12806 (set (match_operand:DI 0 "register_operand" "=r")
12807 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12809 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12810 && ix86_match_ccmode (insn, CCGOCmode)
12811 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12813 [(set_attr "type" "ishift")
12814 (set_attr "length_immediate" "0")
12815 (set_attr "mode" "SI")])
12817 ;; This pattern can't accept a variable shift count, since shifts by
12818 ;; zero don't affect the flags. We assume that shifts by constant
12819 ;; zero are optimized away.
12820 (define_insn "*lshrsi3_cmp"
12821 [(set (reg FLAGS_REG)
12823 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12824 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12826 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12827 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12828 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12829 && ix86_match_ccmode (insn, CCGOCmode)
12830 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12831 "shr{l}\t{%2, %0|%0, %2}"
12832 [(set_attr "type" "ishift")
12833 (set_attr "mode" "SI")])
12835 (define_insn "*lshrsi3_cconly"
12836 [(set (reg FLAGS_REG)
12838 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12839 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12841 (clobber (match_scratch:SI 0 "=r"))]
12842 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12843 && ix86_match_ccmode (insn, CCGOCmode)
12844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845 "shr{l}\t{%2, %0|%0, %2}"
12846 [(set_attr "type" "ishift")
12847 (set_attr "mode" "SI")])
12849 (define_insn "*lshrsi3_cmp_zext"
12850 [(set (reg FLAGS_REG)
12852 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12853 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12855 (set (match_operand:DI 0 "register_operand" "=r")
12856 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12858 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12859 && ix86_match_ccmode (insn, CCGOCmode)
12860 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12861 "shr{l}\t{%2, %k0|%k0, %2}"
12862 [(set_attr "type" "ishift")
12863 (set_attr "mode" "SI")])
12865 (define_expand "lshrhi3"
12866 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12867 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12868 (match_operand:QI 2 "nonmemory_operand" "")))]
12869 "TARGET_HIMODE_MATH"
12870 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12872 (define_insn "*lshrhi3_1_one_bit"
12873 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12874 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12875 (match_operand:QI 2 "const1_operand" "")))
12876 (clobber (reg:CC FLAGS_REG))]
12877 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12878 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12880 [(set_attr "type" "ishift")
12881 (set_attr "length_immediate" "0")
12882 (set_attr "mode" "HI")])
12884 (define_insn "*lshrhi3_1"
12885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12886 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12887 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12888 (clobber (reg:CC FLAGS_REG))]
12889 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12891 shr{w}\t{%2, %0|%0, %2}
12892 shr{w}\t{%b2, %0|%0, %b2}"
12893 [(set_attr "type" "ishift")
12894 (set_attr "mode" "HI")])
12896 ;; This pattern can't accept a variable shift count, since shifts by
12897 ;; zero don't affect the flags. We assume that shifts by constant
12898 ;; zero are optimized away.
12899 (define_insn "*lshrhi3_one_bit_cmp"
12900 [(set (reg FLAGS_REG)
12902 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" ""))
12905 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12906 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12907 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12908 && ix86_match_ccmode (insn, CCGOCmode)
12909 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911 [(set_attr "type" "ishift")
12912 (set_attr "length_immediate" "0")
12913 (set_attr "mode" "HI")])
12915 (define_insn "*lshrhi3_one_bit_cconly"
12916 [(set (reg FLAGS_REG)
12918 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" ""))
12921 (clobber (match_scratch:HI 0 "=r"))]
12922 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12923 && ix86_match_ccmode (insn, CCGOCmode)
12924 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12926 [(set_attr "type" "ishift")
12927 (set_attr "length_immediate" "0")
12928 (set_attr "mode" "HI")])
12930 ;; This pattern can't accept a variable shift count, since shifts by
12931 ;; zero don't affect the flags. We assume that shifts by constant
12932 ;; zero are optimized away.
12933 (define_insn "*lshrhi3_cmp"
12934 [(set (reg FLAGS_REG)
12936 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12937 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12939 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12940 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12941 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12942 && ix86_match_ccmode (insn, CCGOCmode)
12943 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12944 "shr{w}\t{%2, %0|%0, %2}"
12945 [(set_attr "type" "ishift")
12946 (set_attr "mode" "HI")])
12948 (define_insn "*lshrhi3_cconly"
12949 [(set (reg FLAGS_REG)
12951 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12952 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12954 (clobber (match_scratch:HI 0 "=r"))]
12955 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12956 && ix86_match_ccmode (insn, CCGOCmode)
12957 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12958 "shr{w}\t{%2, %0|%0, %2}"
12959 [(set_attr "type" "ishift")
12960 (set_attr "mode" "HI")])
12962 (define_expand "lshrqi3"
12963 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12964 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12965 (match_operand:QI 2 "nonmemory_operand" "")))]
12966 "TARGET_QIMODE_MATH"
12967 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12969 (define_insn "*lshrqi3_1_one_bit"
12970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12971 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12972 (match_operand:QI 2 "const1_operand" "")))
12973 (clobber (reg:CC FLAGS_REG))]
12974 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12975 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12977 [(set_attr "type" "ishift")
12978 (set_attr "length_immediate" "0")
12979 (set_attr "mode" "QI")])
12981 (define_insn "*lshrqi3_1_one_bit_slp"
12982 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12983 (lshiftrt:QI (match_dup 0)
12984 (match_operand:QI 1 "const1_operand" "")))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12987 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12989 [(set_attr "type" "ishift1")
12990 (set_attr "length_immediate" "0")
12991 (set_attr "mode" "QI")])
12993 (define_insn "*lshrqi3_1"
12994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12995 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12996 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12997 (clobber (reg:CC FLAGS_REG))]
12998 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13000 shr{b}\t{%2, %0|%0, %2}
13001 shr{b}\t{%b2, %0|%0, %b2}"
13002 [(set_attr "type" "ishift")
13003 (set_attr "mode" "QI")])
13005 (define_insn "*lshrqi3_1_slp"
13006 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13007 (lshiftrt:QI (match_dup 0)
13008 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13009 (clobber (reg:CC FLAGS_REG))]
13010 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13011 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13013 shr{b}\t{%1, %0|%0, %1}
13014 shr{b}\t{%b1, %0|%0, %b1}"
13015 [(set_attr "type" "ishift1")
13016 (set_attr "mode" "QI")])
13018 ;; This pattern can't accept a variable shift count, since shifts by
13019 ;; zero don't affect the flags. We assume that shifts by constant
13020 ;; zero are optimized away.
13021 (define_insn "*lshrqi2_one_bit_cmp"
13022 [(set (reg FLAGS_REG)
13024 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13025 (match_operand:QI 2 "const1_operand" ""))
13027 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13028 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13029 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13030 && ix86_match_ccmode (insn, CCGOCmode)
13031 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13033 [(set_attr "type" "ishift")
13034 (set_attr "length_immediate" "0")
13035 (set_attr "mode" "QI")])
13037 (define_insn "*lshrqi2_one_bit_cconly"
13038 [(set (reg FLAGS_REG)
13040 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13041 (match_operand:QI 2 "const1_operand" ""))
13043 (clobber (match_scratch:QI 0 "=q"))]
13044 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13045 && ix86_match_ccmode (insn, CCGOCmode)
13046 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13048 [(set_attr "type" "ishift")
13049 (set_attr "length_immediate" "0")
13050 (set_attr "mode" "QI")])
13052 ;; This pattern can't accept a variable shift count, since shifts by
13053 ;; zero don't affect the flags. We assume that shifts by constant
13054 ;; zero are optimized away.
13055 (define_insn "*lshrqi2_cmp"
13056 [(set (reg FLAGS_REG)
13058 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13059 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13061 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13063 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13064 && ix86_match_ccmode (insn, CCGOCmode)
13065 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13066 "shr{b}\t{%2, %0|%0, %2}"
13067 [(set_attr "type" "ishift")
13068 (set_attr "mode" "QI")])
13070 (define_insn "*lshrqi2_cconly"
13071 [(set (reg FLAGS_REG)
13073 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13074 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13076 (clobber (match_scratch:QI 0 "=q"))]
13077 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13078 && ix86_match_ccmode (insn, CCGOCmode)
13079 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13080 "shr{b}\t{%2, %0|%0, %2}"
13081 [(set_attr "type" "ishift")
13082 (set_attr "mode" "QI")])
13084 ;; Rotate instructions
13086 (define_expand "rotldi3"
13087 [(set (match_operand:DI 0 "shiftdi_operand" "")
13088 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13089 (match_operand:QI 2 "nonmemory_operand" "")))]
13094 ix86_expand_binary_operator (ROTATE, DImode, operands);
13097 if (!const_1_to_31_operand (operands[2], VOIDmode))
13099 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13103 ;; Implement rotation using two double-precision shift instructions
13104 ;; and a scratch register.
13105 (define_insn_and_split "ix86_rotldi3"
13106 [(set (match_operand:DI 0 "register_operand" "=r")
13107 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13108 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13109 (clobber (reg:CC FLAGS_REG))
13110 (clobber (match_scratch:SI 3 "=&r"))]
13113 "&& reload_completed"
13114 [(set (match_dup 3) (match_dup 4))
13116 [(set (match_dup 4)
13117 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13118 (lshiftrt:SI (match_dup 5)
13119 (minus:QI (const_int 32) (match_dup 2)))))
13120 (clobber (reg:CC FLAGS_REG))])
13122 [(set (match_dup 5)
13123 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13124 (lshiftrt:SI (match_dup 3)
13125 (minus:QI (const_int 32) (match_dup 2)))))
13126 (clobber (reg:CC FLAGS_REG))])]
13127 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13129 (define_insn "*rotlsi3_1_one_bit_rex64"
13130 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13131 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13132 (match_operand:QI 2 "const1_operand" "")))
13133 (clobber (reg:CC FLAGS_REG))]
13135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13136 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13138 [(set_attr "type" "rotate")
13139 (set_attr "length_immediate" "0")
13140 (set_attr "mode" "DI")])
13142 (define_insn "*rotldi3_1_rex64"
13143 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13144 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13145 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13146 (clobber (reg:CC FLAGS_REG))]
13147 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13149 rol{q}\t{%2, %0|%0, %2}
13150 rol{q}\t{%b2, %0|%0, %b2}"
13151 [(set_attr "type" "rotate")
13152 (set_attr "mode" "DI")])
13154 (define_expand "rotlsi3"
13155 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13156 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13157 (match_operand:QI 2 "nonmemory_operand" "")))]
13159 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13161 (define_insn "*rotlsi3_1_one_bit"
13162 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13163 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13164 (match_operand:QI 2 "const1_operand" "")))
13165 (clobber (reg:CC FLAGS_REG))]
13166 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13167 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13169 [(set_attr "type" "rotate")
13170 (set_attr "length_immediate" "0")
13171 (set_attr "mode" "SI")])
13173 (define_insn "*rotlsi3_1_one_bit_zext"
13174 [(set (match_operand:DI 0 "register_operand" "=r")
13176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13177 (match_operand:QI 2 "const1_operand" ""))))
13178 (clobber (reg:CC FLAGS_REG))]
13180 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13181 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13183 [(set_attr "type" "rotate")
13184 (set_attr "length_immediate" "0")
13185 (set_attr "mode" "SI")])
13187 (define_insn "*rotlsi3_1"
13188 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13189 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13190 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13191 (clobber (reg:CC FLAGS_REG))]
13192 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13194 rol{l}\t{%2, %0|%0, %2}
13195 rol{l}\t{%b2, %0|%0, %b2}"
13196 [(set_attr "type" "rotate")
13197 (set_attr "mode" "SI")])
13199 (define_insn "*rotlsi3_1_zext"
13200 [(set (match_operand:DI 0 "register_operand" "=r,r")
13202 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13203 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13204 (clobber (reg:CC FLAGS_REG))]
13205 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13207 rol{l}\t{%2, %k0|%k0, %2}
13208 rol{l}\t{%b2, %k0|%k0, %b2}"
13209 [(set_attr "type" "rotate")
13210 (set_attr "mode" "SI")])
13212 (define_expand "rotlhi3"
13213 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13214 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13215 (match_operand:QI 2 "nonmemory_operand" "")))]
13216 "TARGET_HIMODE_MATH"
13217 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13219 (define_insn "*rotlhi3_1_one_bit"
13220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13225 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set_attr "length_immediate" "0")
13229 (set_attr "mode" "HI")])
13231 (define_insn "*rotlhi3_1"
13232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13233 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13234 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13235 (clobber (reg:CC FLAGS_REG))]
13236 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13238 rol{w}\t{%2, %0|%0, %2}
13239 rol{w}\t{%b2, %0|%0, %b2}"
13240 [(set_attr "type" "rotate")
13241 (set_attr "mode" "HI")])
13244 [(set (match_operand:HI 0 "register_operand" "")
13245 (rotate:HI (match_dup 0) (const_int 8)))
13246 (clobber (reg:CC FLAGS_REG))]
13248 [(parallel [(set (strict_low_part (match_dup 0))
13249 (bswap:HI (match_dup 0)))
13250 (clobber (reg:CC FLAGS_REG))])]
13253 (define_expand "rotlqi3"
13254 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13255 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13256 (match_operand:QI 2 "nonmemory_operand" "")))]
13257 "TARGET_QIMODE_MATH"
13258 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13260 (define_insn "*rotlqi3_1_one_bit_slp"
13261 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13262 (rotate:QI (match_dup 0)
13263 (match_operand:QI 1 "const1_operand" "")))
13264 (clobber (reg:CC FLAGS_REG))]
13265 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13268 [(set_attr "type" "rotate1")
13269 (set_attr "length_immediate" "0")
13270 (set_attr "mode" "QI")])
13272 (define_insn "*rotlqi3_1_one_bit"
13273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13274 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13275 (match_operand:QI 2 "const1_operand" "")))
13276 (clobber (reg:CC FLAGS_REG))]
13277 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13278 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13280 [(set_attr "type" "rotate")
13281 (set_attr "length_immediate" "0")
13282 (set_attr "mode" "QI")])
13284 (define_insn "*rotlqi3_1_slp"
13285 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13286 (rotate:QI (match_dup 0)
13287 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13288 (clobber (reg:CC FLAGS_REG))]
13289 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13290 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13292 rol{b}\t{%1, %0|%0, %1}
13293 rol{b}\t{%b1, %0|%0, %b1}"
13294 [(set_attr "type" "rotate1")
13295 (set_attr "mode" "QI")])
13297 (define_insn "*rotlqi3_1"
13298 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13299 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13300 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13301 (clobber (reg:CC FLAGS_REG))]
13302 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13304 rol{b}\t{%2, %0|%0, %2}
13305 rol{b}\t{%b2, %0|%0, %b2}"
13306 [(set_attr "type" "rotate")
13307 (set_attr "mode" "QI")])
13309 (define_expand "rotrdi3"
13310 [(set (match_operand:DI 0 "shiftdi_operand" "")
13311 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13312 (match_operand:QI 2 "nonmemory_operand" "")))]
13317 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13320 if (!const_1_to_31_operand (operands[2], VOIDmode))
13322 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13326 ;; Implement rotation using two double-precision shift instructions
13327 ;; and a scratch register.
13328 (define_insn_and_split "ix86_rotrdi3"
13329 [(set (match_operand:DI 0 "register_operand" "=r")
13330 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13331 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13332 (clobber (reg:CC FLAGS_REG))
13333 (clobber (match_scratch:SI 3 "=&r"))]
13336 "&& reload_completed"
13337 [(set (match_dup 3) (match_dup 4))
13339 [(set (match_dup 4)
13340 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13341 (ashift:SI (match_dup 5)
13342 (minus:QI (const_int 32) (match_dup 2)))))
13343 (clobber (reg:CC FLAGS_REG))])
13345 [(set (match_dup 5)
13346 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13347 (ashift:SI (match_dup 3)
13348 (minus:QI (const_int 32) (match_dup 2)))))
13349 (clobber (reg:CC FLAGS_REG))])]
13350 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13352 (define_insn "*rotrdi3_1_one_bit_rex64"
13353 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13354 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13355 (match_operand:QI 2 "const1_operand" "")))
13356 (clobber (reg:CC FLAGS_REG))]
13358 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13359 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13361 [(set_attr "type" "rotate")
13362 (set_attr "length_immediate" "0")
13363 (set_attr "mode" "DI")])
13365 (define_insn "*rotrdi3_1_rex64"
13366 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13367 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13368 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13369 (clobber (reg:CC FLAGS_REG))]
13370 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13372 ror{q}\t{%2, %0|%0, %2}
13373 ror{q}\t{%b2, %0|%0, %b2}"
13374 [(set_attr "type" "rotate")
13375 (set_attr "mode" "DI")])
13377 (define_expand "rotrsi3"
13378 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13379 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13380 (match_operand:QI 2 "nonmemory_operand" "")))]
13382 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13384 (define_insn "*rotrsi3_1_one_bit"
13385 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13386 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13387 (match_operand:QI 2 "const1_operand" "")))
13388 (clobber (reg:CC FLAGS_REG))]
13389 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13390 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13392 [(set_attr "type" "rotate")
13393 (set_attr "length_immediate" "0")
13394 (set_attr "mode" "SI")])
13396 (define_insn "*rotrsi3_1_one_bit_zext"
13397 [(set (match_operand:DI 0 "register_operand" "=r")
13399 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13400 (match_operand:QI 2 "const1_operand" ""))))
13401 (clobber (reg:CC FLAGS_REG))]
13403 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13404 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13406 [(set_attr "type" "rotate")
13407 (set_attr "length_immediate" "0")
13408 (set_attr "mode" "SI")])
13410 (define_insn "*rotrsi3_1"
13411 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13412 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13413 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13414 (clobber (reg:CC FLAGS_REG))]
13415 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13417 ror{l}\t{%2, %0|%0, %2}
13418 ror{l}\t{%b2, %0|%0, %b2}"
13419 [(set_attr "type" "rotate")
13420 (set_attr "mode" "SI")])
13422 (define_insn "*rotrsi3_1_zext"
13423 [(set (match_operand:DI 0 "register_operand" "=r,r")
13425 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13426 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13427 (clobber (reg:CC FLAGS_REG))]
13428 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13430 ror{l}\t{%2, %k0|%k0, %2}
13431 ror{l}\t{%b2, %k0|%k0, %b2}"
13432 [(set_attr "type" "rotate")
13433 (set_attr "mode" "SI")])
13435 (define_expand "rotrhi3"
13436 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13437 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13438 (match_operand:QI 2 "nonmemory_operand" "")))]
13439 "TARGET_HIMODE_MATH"
13440 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13442 (define_insn "*rotrhi3_one_bit"
13443 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13444 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13445 (match_operand:QI 2 "const1_operand" "")))
13446 (clobber (reg:CC FLAGS_REG))]
13447 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13448 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13450 [(set_attr "type" "rotate")
13451 (set_attr "length_immediate" "0")
13452 (set_attr "mode" "HI")])
13454 (define_insn "*rotrhi3_1"
13455 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13456 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13457 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13458 (clobber (reg:CC FLAGS_REG))]
13459 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13461 ror{w}\t{%2, %0|%0, %2}
13462 ror{w}\t{%b2, %0|%0, %b2}"
13463 [(set_attr "type" "rotate")
13464 (set_attr "mode" "HI")])
13467 [(set (match_operand:HI 0 "register_operand" "")
13468 (rotatert:HI (match_dup 0) (const_int 8)))
13469 (clobber (reg:CC FLAGS_REG))]
13471 [(parallel [(set (strict_low_part (match_dup 0))
13472 (bswap:HI (match_dup 0)))
13473 (clobber (reg:CC FLAGS_REG))])]
13476 (define_expand "rotrqi3"
13477 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13478 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13479 (match_operand:QI 2 "nonmemory_operand" "")))]
13480 "TARGET_QIMODE_MATH"
13481 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13483 (define_insn "*rotrqi3_1_one_bit"
13484 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13485 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13486 (match_operand:QI 2 "const1_operand" "")))
13487 (clobber (reg:CC FLAGS_REG))]
13488 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13489 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13491 [(set_attr "type" "rotate")
13492 (set_attr "length_immediate" "0")
13493 (set_attr "mode" "QI")])
13495 (define_insn "*rotrqi3_1_one_bit_slp"
13496 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13497 (rotatert:QI (match_dup 0)
13498 (match_operand:QI 1 "const1_operand" "")))
13499 (clobber (reg:CC FLAGS_REG))]
13500 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13503 [(set_attr "type" "rotate1")
13504 (set_attr "length_immediate" "0")
13505 (set_attr "mode" "QI")])
13507 (define_insn "*rotrqi3_1"
13508 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13509 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13510 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13511 (clobber (reg:CC FLAGS_REG))]
13512 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13514 ror{b}\t{%2, %0|%0, %2}
13515 ror{b}\t{%b2, %0|%0, %b2}"
13516 [(set_attr "type" "rotate")
13517 (set_attr "mode" "QI")])
13519 (define_insn "*rotrqi3_1_slp"
13520 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13521 (rotatert:QI (match_dup 0)
13522 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13523 (clobber (reg:CC FLAGS_REG))]
13524 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13527 ror{b}\t{%1, %0|%0, %1}
13528 ror{b}\t{%b1, %0|%0, %b1}"
13529 [(set_attr "type" "rotate1")
13530 (set_attr "mode" "QI")])
13532 ;; Bit set / bit test instructions
13534 (define_expand "extv"
13535 [(set (match_operand:SI 0 "register_operand" "")
13536 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13537 (match_operand:SI 2 "const8_operand" "")
13538 (match_operand:SI 3 "const8_operand" "")))]
13541 /* Handle extractions from %ah et al. */
13542 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13545 /* From mips.md: extract_bit_field doesn't verify that our source
13546 matches the predicate, so check it again here. */
13547 if (! ext_register_operand (operands[1], VOIDmode))
13551 (define_expand "extzv"
13552 [(set (match_operand:SI 0 "register_operand" "")
13553 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13554 (match_operand:SI 2 "const8_operand" "")
13555 (match_operand:SI 3 "const8_operand" "")))]
13558 /* Handle extractions from %ah et al. */
13559 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13562 /* From mips.md: extract_bit_field doesn't verify that our source
13563 matches the predicate, so check it again here. */
13564 if (! ext_register_operand (operands[1], VOIDmode))
13568 (define_expand "insv"
13569 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13570 (match_operand 1 "const8_operand" "")
13571 (match_operand 2 "const8_operand" ""))
13572 (match_operand 3 "register_operand" ""))]
13575 /* Handle insertions to %ah et al. */
13576 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13579 /* From mips.md: insert_bit_field doesn't verify that our source
13580 matches the predicate, so check it again here. */
13581 if (! ext_register_operand (operands[0], VOIDmode))
13585 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13587 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13592 ;; %%% bts, btr, btc, bt.
13593 ;; In general these instructions are *slow* when applied to memory,
13594 ;; since they enforce atomic operation. When applied to registers,
13595 ;; it depends on the cpu implementation. They're never faster than
13596 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13597 ;; no point. But in 64-bit, we can't hold the relevant immediates
13598 ;; within the instruction itself, so operating on bits in the high
13599 ;; 32-bits of a register becomes easier.
13601 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13602 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13603 ;; negdf respectively, so they can never be disabled entirely.
13605 (define_insn "*btsq"
13606 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13608 (match_operand:DI 1 "const_0_to_63_operand" ""))
13610 (clobber (reg:CC FLAGS_REG))]
13611 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13612 "bts{q}\t{%1, %0|%0, %1}"
13613 [(set_attr "type" "alu1")
13614 (set_attr "prefix_0f" "1")
13615 (set_attr "mode" "DI")])
13617 (define_insn "*btrq"
13618 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13620 (match_operand:DI 1 "const_0_to_63_operand" ""))
13622 (clobber (reg:CC FLAGS_REG))]
13623 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13624 "btr{q}\t{%1, %0|%0, %1}"
13625 [(set_attr "type" "alu1")
13626 (set_attr "prefix_0f" "1")
13627 (set_attr "mode" "DI")])
13629 (define_insn "*btcq"
13630 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13632 (match_operand:DI 1 "const_0_to_63_operand" ""))
13633 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13634 (clobber (reg:CC FLAGS_REG))]
13635 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13636 "btc{q}\t{%1, %0|%0, %1}"
13637 [(set_attr "type" "alu1")
13638 (set_attr "prefix_0f" "1")
13639 (set_attr "mode" "DI")])
13641 ;; Allow Nocona to avoid these instructions if a register is available.
13644 [(match_scratch:DI 2 "r")
13645 (parallel [(set (zero_extract:DI
13646 (match_operand:DI 0 "register_operand" "")
13648 (match_operand:DI 1 "const_0_to_63_operand" ""))
13650 (clobber (reg:CC FLAGS_REG))])]
13651 "TARGET_64BIT && !TARGET_USE_BT"
13654 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13657 if (HOST_BITS_PER_WIDE_INT >= 64)
13658 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13659 else if (i < HOST_BITS_PER_WIDE_INT)
13660 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13662 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13664 op1 = immed_double_const (lo, hi, DImode);
13667 emit_move_insn (operands[2], op1);
13671 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13676 [(match_scratch:DI 2 "r")
13677 (parallel [(set (zero_extract:DI
13678 (match_operand:DI 0 "register_operand" "")
13680 (match_operand:DI 1 "const_0_to_63_operand" ""))
13682 (clobber (reg:CC FLAGS_REG))])]
13683 "TARGET_64BIT && !TARGET_USE_BT"
13686 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13689 if (HOST_BITS_PER_WIDE_INT >= 64)
13690 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13691 else if (i < HOST_BITS_PER_WIDE_INT)
13692 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13694 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13696 op1 = immed_double_const (~lo, ~hi, DImode);
13699 emit_move_insn (operands[2], op1);
13703 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13708 [(match_scratch:DI 2 "r")
13709 (parallel [(set (zero_extract:DI
13710 (match_operand:DI 0 "register_operand" "")
13712 (match_operand:DI 1 "const_0_to_63_operand" ""))
13713 (not:DI (zero_extract:DI
13714 (match_dup 0) (const_int 1) (match_dup 1))))
13715 (clobber (reg:CC FLAGS_REG))])]
13716 "TARGET_64BIT && !TARGET_USE_BT"
13719 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13722 if (HOST_BITS_PER_WIDE_INT >= 64)
13723 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13724 else if (i < HOST_BITS_PER_WIDE_INT)
13725 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13727 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13729 op1 = immed_double_const (lo, hi, DImode);
13732 emit_move_insn (operands[2], op1);
13736 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13740 (define_insn "*btdi_rex64"
13741 [(set (reg:CCC FLAGS_REG)
13744 (match_operand:DI 0 "register_operand" "r")
13746 (match_operand:DI 1 "nonmemory_operand" "rN"))
13748 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13749 "bt{q}\t{%1, %0|%0, %1}"
13750 [(set_attr "type" "alu1")
13751 (set_attr "prefix_0f" "1")
13752 (set_attr "mode" "DI")])
13754 (define_insn "*btsi"
13755 [(set (reg:CCC FLAGS_REG)
13758 (match_operand:SI 0 "register_operand" "r")
13760 (match_operand:SI 1 "nonmemory_operand" "rN"))
13762 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13763 "bt{l}\t{%1, %0|%0, %1}"
13764 [(set_attr "type" "alu1")
13765 (set_attr "prefix_0f" "1")
13766 (set_attr "mode" "SI")])
13768 ;; Store-flag instructions.
13770 ;; For all sCOND expanders, also expand the compare or test insn that
13771 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13773 (define_insn_and_split "*setcc_di_1"
13774 [(set (match_operand:DI 0 "register_operand" "=q")
13775 (match_operator:DI 1 "ix86_comparison_operator"
13776 [(reg FLAGS_REG) (const_int 0)]))]
13777 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13779 "&& reload_completed"
13780 [(set (match_dup 2) (match_dup 1))
13781 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13783 PUT_MODE (operands[1], QImode);
13784 operands[2] = gen_lowpart (QImode, operands[0]);
13787 (define_insn_and_split "*setcc_si_1_and"
13788 [(set (match_operand:SI 0 "register_operand" "=q")
13789 (match_operator:SI 1 "ix86_comparison_operator"
13790 [(reg FLAGS_REG) (const_int 0)]))
13791 (clobber (reg:CC FLAGS_REG))]
13792 "!TARGET_PARTIAL_REG_STALL
13793 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13795 "&& reload_completed"
13796 [(set (match_dup 2) (match_dup 1))
13797 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13798 (clobber (reg:CC FLAGS_REG))])]
13800 PUT_MODE (operands[1], QImode);
13801 operands[2] = gen_lowpart (QImode, operands[0]);
13804 (define_insn_and_split "*setcc_si_1_movzbl"
13805 [(set (match_operand:SI 0 "register_operand" "=q")
13806 (match_operator:SI 1 "ix86_comparison_operator"
13807 [(reg FLAGS_REG) (const_int 0)]))]
13808 "!TARGET_PARTIAL_REG_STALL
13809 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13811 "&& reload_completed"
13812 [(set (match_dup 2) (match_dup 1))
13813 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13815 PUT_MODE (operands[1], QImode);
13816 operands[2] = gen_lowpart (QImode, operands[0]);
13819 (define_insn_and_split "*setcc_<mode>_2"
13820 [(set (match_operand:SWI48 0 "register_operand" "=q")
13821 (match_operator:SWI48 1 "ix86_comparison_operator"
13822 [(reg FLAGS_REG) (const_int 0)]))
13823 (clobber (reg:CC FLAGS_REG))]
13824 "TARGET_PARTIAL_REG_STALL"
13826 "&& reload_completed"
13827 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
13829 PUT_MODE (operands[1], QImode);
13830 operands[2] = gen_lowpart (QImode, operands[0]);
13831 ix86_expand_clear (operands[0]);
13834 (define_insn "*setcc_qi"
13835 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13836 (match_operator:QI 1 "ix86_comparison_operator"
13837 [(reg FLAGS_REG) (const_int 0)]))]
13840 [(set_attr "type" "setcc")
13841 (set_attr "mode" "QI")])
13843 (define_insn "*setcc_qi_slp"
13844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13845 (match_operator:QI 1 "ix86_comparison_operator"
13846 [(reg FLAGS_REG) (const_int 0)]))]
13849 [(set_attr "type" "setcc")
13850 (set_attr "mode" "QI")])
13852 ;; In general it is not safe to assume too much about CCmode registers,
13853 ;; so simplify-rtx stops when it sees a second one. Under certain
13854 ;; conditions this is safe on x86, so help combine not create
13861 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13862 (ne:QI (match_operator 1 "ix86_comparison_operator"
13863 [(reg FLAGS_REG) (const_int 0)])
13866 [(set (match_dup 0) (match_dup 1))]
13868 PUT_MODE (operands[1], QImode);
13872 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13873 (ne:QI (match_operator 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)])
13877 [(set (match_dup 0) (match_dup 1))]
13879 PUT_MODE (operands[1], QImode);
13883 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13884 (eq:QI (match_operator 1 "ix86_comparison_operator"
13885 [(reg FLAGS_REG) (const_int 0)])
13888 [(set (match_dup 0) (match_dup 1))]
13890 rtx new_op1 = copy_rtx (operands[1]);
13891 operands[1] = new_op1;
13892 PUT_MODE (new_op1, QImode);
13893 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13894 GET_MODE (XEXP (new_op1, 0))));
13896 /* Make sure that (a) the CCmode we have for the flags is strong
13897 enough for the reversed compare or (b) we have a valid FP compare. */
13898 if (! ix86_comparison_operator (new_op1, VOIDmode))
13903 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13904 (eq:QI (match_operator 1 "ix86_comparison_operator"
13905 [(reg FLAGS_REG) (const_int 0)])
13908 [(set (match_dup 0) (match_dup 1))]
13910 rtx new_op1 = copy_rtx (operands[1]);
13911 operands[1] = new_op1;
13912 PUT_MODE (new_op1, QImode);
13913 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13914 GET_MODE (XEXP (new_op1, 0))));
13916 /* Make sure that (a) the CCmode we have for the flags is strong
13917 enough for the reversed compare or (b) we have a valid FP compare. */
13918 if (! ix86_comparison_operator (new_op1, VOIDmode))
13922 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13923 ;; subsequent logical operations are used to imitate conditional moves.
13924 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13927 (define_insn "*avx_setcc<mode>"
13928 [(set (match_operand:MODEF 0 "register_operand" "=x")
13929 (match_operator:MODEF 1 "avx_comparison_float_operator"
13930 [(match_operand:MODEF 2 "register_operand" "x")
13931 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13933 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13934 [(set_attr "type" "ssecmp")
13935 (set_attr "prefix" "vex")
13936 (set_attr "length_immediate" "1")
13937 (set_attr "mode" "<MODE>")])
13939 (define_insn "*sse_setcc<mode>"
13940 [(set (match_operand:MODEF 0 "register_operand" "=x")
13941 (match_operator:MODEF 1 "sse_comparison_operator"
13942 [(match_operand:MODEF 2 "register_operand" "0")
13943 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13944 "SSE_FLOAT_MODE_P (<MODE>mode)"
13945 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13946 [(set_attr "type" "ssecmp")
13947 (set_attr "length_immediate" "1")
13948 (set_attr "mode" "<MODE>")])
13950 ;; Basic conditional jump instructions.
13951 ;; We ignore the overflow flag for signed branch instructions.
13953 (define_insn "*jcc_1"
13955 (if_then_else (match_operator 1 "ix86_comparison_operator"
13956 [(reg FLAGS_REG) (const_int 0)])
13957 (label_ref (match_operand 0 "" ""))
13961 [(set_attr "type" "ibr")
13962 (set_attr "modrm" "0")
13963 (set (attr "length")
13964 (if_then_else (and (ge (minus (match_dup 0) (pc))
13966 (lt (minus (match_dup 0) (pc))
13971 (define_insn "*jcc_2"
13973 (if_then_else (match_operator 1 "ix86_comparison_operator"
13974 [(reg FLAGS_REG) (const_int 0)])
13976 (label_ref (match_operand 0 "" ""))))]
13979 [(set_attr "type" "ibr")
13980 (set_attr "modrm" "0")
13981 (set (attr "length")
13982 (if_then_else (and (ge (minus (match_dup 0) (pc))
13984 (lt (minus (match_dup 0) (pc))
13989 ;; In general it is not safe to assume too much about CCmode registers,
13990 ;; so simplify-rtx stops when it sees a second one. Under certain
13991 ;; conditions this is safe on x86, so help combine not create
13999 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14000 [(reg FLAGS_REG) (const_int 0)])
14002 (label_ref (match_operand 1 "" ""))
14006 (if_then_else (match_dup 0)
14007 (label_ref (match_dup 1))
14010 PUT_MODE (operands[0], VOIDmode);
14015 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14016 [(reg FLAGS_REG) (const_int 0)])
14018 (label_ref (match_operand 1 "" ""))
14022 (if_then_else (match_dup 0)
14023 (label_ref (match_dup 1))
14026 rtx new_op0 = copy_rtx (operands[0]);
14027 operands[0] = new_op0;
14028 PUT_MODE (new_op0, VOIDmode);
14029 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14030 GET_MODE (XEXP (new_op0, 0))));
14032 /* Make sure that (a) the CCmode we have for the flags is strong
14033 enough for the reversed compare or (b) we have a valid FP compare. */
14034 if (! ix86_comparison_operator (new_op0, VOIDmode))
14038 ;; zero_extend in SImode is correct, since this is what combine pass
14039 ;; generates from shift insn with QImode operand. Actually, the mode of
14040 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14041 ;; appropriate modulo of the bit offset value.
14043 (define_insn_and_split "*jcc_btdi_rex64"
14045 (if_then_else (match_operator 0 "bt_comparison_operator"
14047 (match_operand:DI 1 "register_operand" "r")
14050 (match_operand:QI 2 "register_operand" "r")))
14052 (label_ref (match_operand 3 "" ""))
14054 (clobber (reg:CC FLAGS_REG))]
14055 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14058 [(set (reg:CCC FLAGS_REG)
14066 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14067 (label_ref (match_dup 3))
14070 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14072 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14075 ;; avoid useless masking of bit offset operand
14076 (define_insn_and_split "*jcc_btdi_mask_rex64"
14078 (if_then_else (match_operator 0 "bt_comparison_operator"
14080 (match_operand:DI 1 "register_operand" "r")
14083 (match_operand:SI 2 "register_operand" "r")
14084 (match_operand:SI 3 "const_int_operand" "n")))])
14085 (label_ref (match_operand 4 "" ""))
14087 (clobber (reg:CC FLAGS_REG))]
14088 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14089 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14092 [(set (reg:CCC FLAGS_REG)
14100 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14101 (label_ref (match_dup 4))
14104 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14106 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14109 (define_insn_and_split "*jcc_btsi"
14111 (if_then_else (match_operator 0 "bt_comparison_operator"
14113 (match_operand:SI 1 "register_operand" "r")
14116 (match_operand:QI 2 "register_operand" "r")))
14118 (label_ref (match_operand 3 "" ""))
14120 (clobber (reg:CC FLAGS_REG))]
14121 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14124 [(set (reg:CCC FLAGS_REG)
14132 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14133 (label_ref (match_dup 3))
14136 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14138 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14141 ;; avoid useless masking of bit offset operand
14142 (define_insn_and_split "*jcc_btsi_mask"
14144 (if_then_else (match_operator 0 "bt_comparison_operator"
14146 (match_operand:SI 1 "register_operand" "r")
14149 (match_operand:SI 2 "register_operand" "r")
14150 (match_operand:SI 3 "const_int_operand" "n")))])
14151 (label_ref (match_operand 4 "" ""))
14153 (clobber (reg:CC FLAGS_REG))]
14154 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14155 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14158 [(set (reg:CCC FLAGS_REG)
14166 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14167 (label_ref (match_dup 4))
14169 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14171 (define_insn_and_split "*jcc_btsi_1"
14173 (if_then_else (match_operator 0 "bt_comparison_operator"
14176 (match_operand:SI 1 "register_operand" "r")
14177 (match_operand:QI 2 "register_operand" "r"))
14180 (label_ref (match_operand 3 "" ""))
14182 (clobber (reg:CC FLAGS_REG))]
14183 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14186 [(set (reg:CCC FLAGS_REG)
14194 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14195 (label_ref (match_dup 3))
14198 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14200 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14203 ;; avoid useless masking of bit offset operand
14204 (define_insn_and_split "*jcc_btsi_mask_1"
14207 (match_operator 0 "bt_comparison_operator"
14210 (match_operand:SI 1 "register_operand" "r")
14213 (match_operand:SI 2 "register_operand" "r")
14214 (match_operand:SI 3 "const_int_operand" "n")) 0))
14217 (label_ref (match_operand 4 "" ""))
14219 (clobber (reg:CC FLAGS_REG))]
14220 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14221 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14224 [(set (reg:CCC FLAGS_REG)
14232 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14233 (label_ref (match_dup 4))
14235 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14237 ;; Define combination compare-and-branch fp compare instructions to help
14240 (define_insn "*fp_jcc_3_387"
14242 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14243 [(match_operand 1 "register_operand" "f")
14244 (match_operand 2 "nonimmediate_operand" "fm")])
14245 (label_ref (match_operand 3 "" ""))
14247 (clobber (reg:CCFP FPSR_REG))
14248 (clobber (reg:CCFP FLAGS_REG))
14249 (clobber (match_scratch:HI 4 "=a"))]
14251 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14253 && SELECT_CC_MODE (GET_CODE (operands[0]),
14254 operands[1], operands[2]) == CCFPmode
14258 (define_insn "*fp_jcc_4_387"
14260 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14261 [(match_operand 1 "register_operand" "f")
14262 (match_operand 2 "nonimmediate_operand" "fm")])
14264 (label_ref (match_operand 3 "" ""))))
14265 (clobber (reg:CCFP FPSR_REG))
14266 (clobber (reg:CCFP FLAGS_REG))
14267 (clobber (match_scratch:HI 4 "=a"))]
14269 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14270 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14271 && SELECT_CC_MODE (GET_CODE (operands[0]),
14272 operands[1], operands[2]) == CCFPmode
14276 (define_insn "*fp_jcc_5_387"
14278 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14279 [(match_operand 1 "register_operand" "f")
14280 (match_operand 2 "register_operand" "f")])
14281 (label_ref (match_operand 3 "" ""))
14283 (clobber (reg:CCFP FPSR_REG))
14284 (clobber (reg:CCFP FLAGS_REG))
14285 (clobber (match_scratch:HI 4 "=a"))]
14286 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14287 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14291 (define_insn "*fp_jcc_6_387"
14293 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14294 [(match_operand 1 "register_operand" "f")
14295 (match_operand 2 "register_operand" "f")])
14297 (label_ref (match_operand 3 "" ""))))
14298 (clobber (reg:CCFP FPSR_REG))
14299 (clobber (reg:CCFP FLAGS_REG))
14300 (clobber (match_scratch:HI 4 "=a"))]
14301 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14302 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14306 (define_insn "*fp_jcc_7_387"
14308 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14309 [(match_operand 1 "register_operand" "f")
14310 (match_operand 2 "const0_operand" "")])
14311 (label_ref (match_operand 3 "" ""))
14313 (clobber (reg:CCFP FPSR_REG))
14314 (clobber (reg:CCFP FLAGS_REG))
14315 (clobber (match_scratch:HI 4 "=a"))]
14316 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14317 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14318 && SELECT_CC_MODE (GET_CODE (operands[0]),
14319 operands[1], operands[2]) == CCFPmode
14323 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14324 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14325 ;; with a precedence over other operators and is always put in the first
14326 ;; place. Swap condition and operands to match ficom instruction.
14328 (define_insn "*fp_jcc_8<mode>_387"
14330 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14331 [(match_operator 1 "float_operator"
14332 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14333 (match_operand 3 "register_operand" "f,f")])
14334 (label_ref (match_operand 4 "" ""))
14336 (clobber (reg:CCFP FPSR_REG))
14337 (clobber (reg:CCFP FLAGS_REG))
14338 (clobber (match_scratch:HI 5 "=a,a"))]
14339 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14340 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14341 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14342 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14348 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14349 [(match_operand 1 "register_operand" "")
14350 (match_operand 2 "nonimmediate_operand" "")])
14351 (match_operand 3 "" "")
14352 (match_operand 4 "" "")))
14353 (clobber (reg:CCFP FPSR_REG))
14354 (clobber (reg:CCFP FLAGS_REG))]
14358 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14359 operands[3], operands[4], NULL_RTX, NULL_RTX);
14365 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14366 [(match_operand 1 "register_operand" "")
14367 (match_operand 2 "general_operand" "")])
14368 (match_operand 3 "" "")
14369 (match_operand 4 "" "")))
14370 (clobber (reg:CCFP FPSR_REG))
14371 (clobber (reg:CCFP FLAGS_REG))
14372 (clobber (match_scratch:HI 5 "=a"))]
14376 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14377 operands[3], operands[4], operands[5], NULL_RTX);
14383 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14384 [(match_operator 1 "float_operator"
14385 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14386 (match_operand 3 "register_operand" "")])
14387 (match_operand 4 "" "")
14388 (match_operand 5 "" "")))
14389 (clobber (reg:CCFP FPSR_REG))
14390 (clobber (reg:CCFP FLAGS_REG))
14391 (clobber (match_scratch:HI 6 "=a"))]
14395 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14396 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14397 operands[3], operands[7],
14398 operands[4], operands[5], operands[6], NULL_RTX);
14402 ;; %%% Kill this when reload knows how to do it.
14405 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14406 [(match_operator 1 "float_operator"
14407 [(match_operand:X87MODEI12 2 "register_operand" "")])
14408 (match_operand 3 "register_operand" "")])
14409 (match_operand 4 "" "")
14410 (match_operand 5 "" "")))
14411 (clobber (reg:CCFP FPSR_REG))
14412 (clobber (reg:CCFP FLAGS_REG))
14413 (clobber (match_scratch:HI 6 "=a"))]
14417 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14418 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14419 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14420 operands[3], operands[7],
14421 operands[4], operands[5], operands[6], operands[2]);
14425 ;; Unconditional and other jump instructions
14427 (define_insn "jump"
14429 (label_ref (match_operand 0 "" "")))]
14432 [(set_attr "type" "ibr")
14433 (set (attr "length")
14434 (if_then_else (and (ge (minus (match_dup 0) (pc))
14436 (lt (minus (match_dup 0) (pc))
14440 (set_attr "modrm" "0")])
14442 (define_expand "indirect_jump"
14443 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14447 (define_insn "*indirect_jump"
14448 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14451 [(set_attr "type" "ibr")
14452 (set_attr "length_immediate" "0")])
14454 (define_expand "tablejump"
14455 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14456 (use (label_ref (match_operand 1 "" "")))])]
14459 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14460 relative. Convert the relative address to an absolute address. */
14464 enum rtx_code code;
14466 /* We can't use @GOTOFF for text labels on VxWorks;
14467 see gotoff_operand. */
14468 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14472 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14474 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14478 op1 = pic_offset_table_rtx;
14483 op0 = pic_offset_table_rtx;
14487 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14492 (define_insn "*tablejump_1"
14493 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14494 (use (label_ref (match_operand 1 "" "")))]
14497 [(set_attr "type" "ibr")
14498 (set_attr "length_immediate" "0")])
14500 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14503 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14504 (set (match_operand:QI 1 "register_operand" "")
14505 (match_operator:QI 2 "ix86_comparison_operator"
14506 [(reg FLAGS_REG) (const_int 0)]))
14507 (set (match_operand 3 "q_regs_operand" "")
14508 (zero_extend (match_dup 1)))]
14509 "(peep2_reg_dead_p (3, operands[1])
14510 || operands_match_p (operands[1], operands[3]))
14511 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14512 [(set (match_dup 4) (match_dup 0))
14513 (set (strict_low_part (match_dup 5))
14516 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14517 operands[5] = gen_lowpart (QImode, operands[3]);
14518 ix86_expand_clear (operands[3]);
14521 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14524 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14525 (set (match_operand:QI 1 "register_operand" "")
14526 (match_operator:QI 2 "ix86_comparison_operator"
14527 [(reg FLAGS_REG) (const_int 0)]))
14528 (parallel [(set (match_operand 3 "q_regs_operand" "")
14529 (zero_extend (match_dup 1)))
14530 (clobber (reg:CC FLAGS_REG))])]
14531 "(peep2_reg_dead_p (3, operands[1])
14532 || operands_match_p (operands[1], operands[3]))
14533 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14534 [(set (match_dup 4) (match_dup 0))
14535 (set (strict_low_part (match_dup 5))
14538 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14539 operands[5] = gen_lowpart (QImode, operands[3]);
14540 ix86_expand_clear (operands[3]);
14543 ;; Call instructions.
14545 ;; The predicates normally associated with named expanders are not properly
14546 ;; checked for calls. This is a bug in the generic code, but it isn't that
14547 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14549 ;; Call subroutine returning no value.
14551 (define_expand "call_pop"
14552 [(parallel [(call (match_operand:QI 0 "" "")
14553 (match_operand:SI 1 "" ""))
14554 (set (reg:SI SP_REG)
14555 (plus:SI (reg:SI SP_REG)
14556 (match_operand:SI 3 "" "")))])]
14559 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14563 (define_insn "*call_pop_0"
14564 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14565 (match_operand:SI 1 "" ""))
14566 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14567 (match_operand:SI 2 "immediate_operand" "")))]
14570 if (SIBLING_CALL_P (insn))
14573 return "call\t%P0";
14575 [(set_attr "type" "call")])
14577 (define_insn "*call_pop_1"
14578 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14579 (match_operand:SI 1 "" ""))
14580 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14581 (match_operand:SI 2 "immediate_operand" "i")))]
14582 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14584 if (constant_call_address_operand (operands[0], Pmode))
14585 return "call\t%P0";
14586 return "call\t%A0";
14588 [(set_attr "type" "call")])
14590 (define_insn "*sibcall_pop_1"
14591 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14592 (match_operand:SI 1 "" ""))
14593 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14594 (match_operand:SI 2 "immediate_operand" "i,i")))]
14595 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14599 [(set_attr "type" "call")])
14601 (define_expand "call"
14602 [(call (match_operand:QI 0 "" "")
14603 (match_operand 1 "" ""))
14604 (use (match_operand 2 "" ""))]
14607 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14611 (define_expand "sibcall"
14612 [(call (match_operand:QI 0 "" "")
14613 (match_operand 1 "" ""))
14614 (use (match_operand 2 "" ""))]
14617 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14621 (define_insn "*call_0"
14622 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14623 (match_operand 1 "" ""))]
14626 if (SIBLING_CALL_P (insn))
14629 return "call\t%P0";
14631 [(set_attr "type" "call")])
14633 (define_insn "*call_1"
14634 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14635 (match_operand 1 "" ""))]
14636 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14638 if (constant_call_address_operand (operands[0], Pmode))
14639 return "call\t%P0";
14640 return "call\t%A0";
14642 [(set_attr "type" "call")])
14644 (define_insn "*sibcall_1"
14645 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14646 (match_operand 1 "" ""))]
14647 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14651 [(set_attr "type" "call")])
14653 (define_insn "*call_1_rex64"
14654 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14655 (match_operand 1 "" ""))]
14656 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14657 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14659 if (constant_call_address_operand (operands[0], Pmode))
14660 return "call\t%P0";
14661 return "call\t%A0";
14663 [(set_attr "type" "call")])
14665 (define_insn "*call_1_rex64_ms_sysv"
14666 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14667 (match_operand 1 "" ""))
14668 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14669 (clobber (reg:TI XMM6_REG))
14670 (clobber (reg:TI XMM7_REG))
14671 (clobber (reg:TI XMM8_REG))
14672 (clobber (reg:TI XMM9_REG))
14673 (clobber (reg:TI XMM10_REG))
14674 (clobber (reg:TI XMM11_REG))
14675 (clobber (reg:TI XMM12_REG))
14676 (clobber (reg:TI XMM13_REG))
14677 (clobber (reg:TI XMM14_REG))
14678 (clobber (reg:TI XMM15_REG))
14679 (clobber (reg:DI SI_REG))
14680 (clobber (reg:DI DI_REG))]
14681 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14683 if (constant_call_address_operand (operands[0], Pmode))
14684 return "call\t%P0";
14685 return "call\t%A0";
14687 [(set_attr "type" "call")])
14689 (define_insn "*call_1_rex64_large"
14690 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14691 (match_operand 1 "" ""))]
14692 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14694 [(set_attr "type" "call")])
14696 (define_insn "*sibcall_1_rex64"
14697 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14698 (match_operand 1 "" ""))]
14699 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14703 [(set_attr "type" "call")])
14705 ;; Call subroutine, returning value in operand 0
14706 (define_expand "call_value_pop"
14707 [(parallel [(set (match_operand 0 "" "")
14708 (call (match_operand:QI 1 "" "")
14709 (match_operand:SI 2 "" "")))
14710 (set (reg:SI SP_REG)
14711 (plus:SI (reg:SI SP_REG)
14712 (match_operand:SI 4 "" "")))])]
14715 ix86_expand_call (operands[0], operands[1], operands[2],
14716 operands[3], operands[4], 0);
14720 (define_expand "call_value"
14721 [(set (match_operand 0 "" "")
14722 (call (match_operand:QI 1 "" "")
14723 (match_operand:SI 2 "" "")))
14724 (use (match_operand:SI 3 "" ""))]
14725 ;; Operand 2 not used on the i386.
14728 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14732 (define_expand "sibcall_value"
14733 [(set (match_operand 0 "" "")
14734 (call (match_operand:QI 1 "" "")
14735 (match_operand:SI 2 "" "")))
14736 (use (match_operand:SI 3 "" ""))]
14737 ;; Operand 2 not used on the i386.
14740 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14744 ;; Call subroutine returning any type.
14746 (define_expand "untyped_call"
14747 [(parallel [(call (match_operand 0 "" "")
14749 (match_operand 1 "" "")
14750 (match_operand 2 "" "")])]
14755 /* In order to give reg-stack an easier job in validating two
14756 coprocessor registers as containing a possible return value,
14757 simply pretend the untyped call returns a complex long double
14760 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14761 and should have the default ABI. */
14763 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14764 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14765 operands[0], const0_rtx,
14766 GEN_INT ((TARGET_64BIT
14767 ? (ix86_abi == SYSV_ABI
14768 ? X86_64_SSE_REGPARM_MAX
14769 : X86_64_MS_SSE_REGPARM_MAX)
14770 : X86_32_SSE_REGPARM_MAX)
14774 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14776 rtx set = XVECEXP (operands[2], 0, i);
14777 emit_move_insn (SET_DEST (set), SET_SRC (set));
14780 /* The optimizer does not know that the call sets the function value
14781 registers we stored in the result block. We avoid problems by
14782 claiming that all hard registers are used and clobbered at this
14784 emit_insn (gen_blockage ());
14789 ;; Prologue and epilogue instructions
14791 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14792 ;; all of memory. This blocks insns from being moved across this point.
14794 (define_insn "blockage"
14795 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14798 [(set_attr "length" "0")])
14800 ;; Do not schedule instructions accessing memory across this point.
14802 (define_expand "memory_blockage"
14803 [(set (match_dup 0)
14804 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14807 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14808 MEM_VOLATILE_P (operands[0]) = 1;
14811 (define_insn "*memory_blockage"
14812 [(set (match_operand:BLK 0 "" "")
14813 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14816 [(set_attr "length" "0")])
14818 ;; As USE insns aren't meaningful after reload, this is used instead
14819 ;; to prevent deleting instructions setting registers for PIC code
14820 (define_insn "prologue_use"
14821 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14824 [(set_attr "length" "0")])
14826 ;; Insn emitted into the body of a function to return from a function.
14827 ;; This is only done if the function's epilogue is known to be simple.
14828 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14830 (define_expand "return"
14832 "ix86_can_use_return_insn_p ()"
14834 if (crtl->args.pops_args)
14836 rtx popc = GEN_INT (crtl->args.pops_args);
14837 emit_jump_insn (gen_return_pop_internal (popc));
14842 (define_insn "return_internal"
14846 [(set_attr "length" "1")
14847 (set_attr "atom_unit" "jeu")
14848 (set_attr "length_immediate" "0")
14849 (set_attr "modrm" "0")])
14851 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14852 ;; instruction Athlon and K8 have.
14854 (define_insn "return_internal_long"
14856 (unspec [(const_int 0)] UNSPEC_REP)]
14859 [(set_attr "length" "2")
14860 (set_attr "atom_unit" "jeu")
14861 (set_attr "length_immediate" "0")
14862 (set_attr "prefix_rep" "1")
14863 (set_attr "modrm" "0")])
14865 (define_insn "return_pop_internal"
14867 (use (match_operand:SI 0 "const_int_operand" ""))]
14870 [(set_attr "length" "3")
14871 (set_attr "atom_unit" "jeu")
14872 (set_attr "length_immediate" "2")
14873 (set_attr "modrm" "0")])
14875 (define_insn "return_indirect_internal"
14877 (use (match_operand:SI 0 "register_operand" "r"))]
14880 [(set_attr "type" "ibr")
14881 (set_attr "length_immediate" "0")])
14887 [(set_attr "length" "1")
14888 (set_attr "length_immediate" "0")
14889 (set_attr "modrm" "0")])
14891 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
14892 ;; branch prediction penalty for the third jump in a 16-byte
14896 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14899 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14900 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14902 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14903 The align insn is used to avoid 3 jump instructions in the row to improve
14904 branch prediction and the benefits hardly outweigh the cost of extra 8
14905 nops on the average inserted by full alignment pseudo operation. */
14909 [(set_attr "length" "16")])
14911 (define_expand "prologue"
14914 "ix86_expand_prologue (); DONE;")
14916 (define_insn "set_got"
14917 [(set (match_operand:SI 0 "register_operand" "=r")
14918 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14919 (clobber (reg:CC FLAGS_REG))]
14921 { return output_set_got (operands[0], NULL_RTX); }
14922 [(set_attr "type" "multi")
14923 (set_attr "length" "12")])
14925 (define_insn "set_got_labelled"
14926 [(set (match_operand:SI 0 "register_operand" "=r")
14927 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14929 (clobber (reg:CC FLAGS_REG))]
14931 { return output_set_got (operands[0], operands[1]); }
14932 [(set_attr "type" "multi")
14933 (set_attr "length" "12")])
14935 (define_insn "set_got_rex64"
14936 [(set (match_operand:DI 0 "register_operand" "=r")
14937 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14939 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14940 [(set_attr "type" "lea")
14941 (set_attr "length_address" "4")
14942 (set_attr "mode" "DI")])
14944 (define_insn "set_rip_rex64"
14945 [(set (match_operand:DI 0 "register_operand" "=r")
14946 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14948 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14949 [(set_attr "type" "lea")
14950 (set_attr "length_address" "4")
14951 (set_attr "mode" "DI")])
14953 (define_insn "set_got_offset_rex64"
14954 [(set (match_operand:DI 0 "register_operand" "=r")
14956 [(label_ref (match_operand 1 "" ""))]
14957 UNSPEC_SET_GOT_OFFSET))]
14959 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14960 [(set_attr "type" "imov")
14961 (set_attr "length_immediate" "0")
14962 (set_attr "length_address" "8")
14963 (set_attr "mode" "DI")])
14965 (define_expand "epilogue"
14968 "ix86_expand_epilogue (1); DONE;")
14970 (define_expand "sibcall_epilogue"
14973 "ix86_expand_epilogue (0); DONE;")
14975 (define_expand "eh_return"
14976 [(use (match_operand 0 "register_operand" ""))]
14979 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14981 /* Tricky bit: we write the address of the handler to which we will
14982 be returning into someone else's stack frame, one word below the
14983 stack address we wish to restore. */
14984 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14985 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14986 tmp = gen_rtx_MEM (Pmode, tmp);
14987 emit_move_insn (tmp, ra);
14989 emit_jump_insn (gen_eh_return_internal ());
14994 (define_insn_and_split "eh_return_internal"
14998 "epilogue_completed"
15000 "ix86_expand_epilogue (2); DONE;")
15002 (define_insn "leave"
15003 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15004 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15005 (clobber (mem:BLK (scratch)))]
15008 [(set_attr "type" "leave")])
15010 (define_insn "leave_rex64"
15011 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15012 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15013 (clobber (mem:BLK (scratch)))]
15016 [(set_attr "type" "leave")])
15018 (define_expand "ffssi2"
15020 [(set (match_operand:SI 0 "register_operand" "")
15021 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15022 (clobber (match_scratch:SI 2 ""))
15023 (clobber (reg:CC FLAGS_REG))])]
15028 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15033 (define_expand "ffs_cmove"
15034 [(set (match_dup 2) (const_int -1))
15035 (parallel [(set (reg:CCZ FLAGS_REG)
15036 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15038 (set (match_operand:SI 0 "register_operand" "")
15039 (ctz:SI (match_dup 1)))])
15040 (set (match_dup 0) (if_then_else:SI
15041 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15044 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15045 (clobber (reg:CC FLAGS_REG))])]
15047 "operands[2] = gen_reg_rtx (SImode);")
15049 (define_insn_and_split "*ffs_no_cmove"
15050 [(set (match_operand:SI 0 "register_operand" "=r")
15051 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15052 (clobber (match_scratch:SI 2 "=&q"))
15053 (clobber (reg:CC FLAGS_REG))]
15056 "&& reload_completed"
15057 [(parallel [(set (reg:CCZ FLAGS_REG)
15058 (compare:CCZ (match_dup 1) (const_int 0)))
15059 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15060 (set (strict_low_part (match_dup 3))
15061 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15062 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15063 (clobber (reg:CC FLAGS_REG))])
15064 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15065 (clobber (reg:CC FLAGS_REG))])
15066 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15067 (clobber (reg:CC FLAGS_REG))])]
15069 operands[3] = gen_lowpart (QImode, operands[2]);
15070 ix86_expand_clear (operands[2]);
15073 (define_insn "*ffssi_1"
15074 [(set (reg:CCZ FLAGS_REG)
15075 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15077 (set (match_operand:SI 0 "register_operand" "=r")
15078 (ctz:SI (match_dup 1)))]
15080 "bsf{l}\t{%1, %0|%0, %1}"
15081 [(set_attr "type" "alu1")
15082 (set_attr "prefix_0f" "1")
15083 (set_attr "mode" "SI")])
15085 (define_expand "ffsdi2"
15086 [(set (match_dup 2) (const_int -1))
15087 (parallel [(set (reg:CCZ FLAGS_REG)
15088 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15090 (set (match_operand:DI 0 "register_operand" "")
15091 (ctz:DI (match_dup 1)))])
15092 (set (match_dup 0) (if_then_else:DI
15093 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15096 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15097 (clobber (reg:CC FLAGS_REG))])]
15099 "operands[2] = gen_reg_rtx (DImode);")
15101 (define_insn "*ffsdi_1"
15102 [(set (reg:CCZ FLAGS_REG)
15103 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15105 (set (match_operand:DI 0 "register_operand" "=r")
15106 (ctz:DI (match_dup 1)))]
15108 "bsf{q}\t{%1, %0|%0, %1}"
15109 [(set_attr "type" "alu1")
15110 (set_attr "prefix_0f" "1")
15111 (set_attr "mode" "DI")])
15113 (define_insn "ctzsi2"
15114 [(set (match_operand:SI 0 "register_operand" "=r")
15115 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15116 (clobber (reg:CC FLAGS_REG))]
15118 "bsf{l}\t{%1, %0|%0, %1}"
15119 [(set_attr "type" "alu1")
15120 (set_attr "prefix_0f" "1")
15121 (set_attr "mode" "SI")])
15123 (define_insn "ctzdi2"
15124 [(set (match_operand:DI 0 "register_operand" "=r")
15125 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15126 (clobber (reg:CC FLAGS_REG))]
15128 "bsf{q}\t{%1, %0|%0, %1}"
15129 [(set_attr "type" "alu1")
15130 (set_attr "prefix_0f" "1")
15131 (set_attr "mode" "DI")])
15133 (define_expand "clzsi2"
15135 [(set (match_operand:SI 0 "register_operand" "")
15136 (minus:SI (const_int 31)
15137 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15138 (clobber (reg:CC FLAGS_REG))])
15140 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15141 (clobber (reg:CC FLAGS_REG))])]
15146 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15151 (define_insn "clzsi2_abm"
15152 [(set (match_operand:SI 0 "register_operand" "=r")
15153 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15154 (clobber (reg:CC FLAGS_REG))]
15156 "lzcnt{l}\t{%1, %0|%0, %1}"
15157 [(set_attr "prefix_rep" "1")
15158 (set_attr "type" "bitmanip")
15159 (set_attr "mode" "SI")])
15162 [(set (match_operand:SI 0 "register_operand" "=r")
15163 (minus:SI (const_int 31)
15164 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15165 (clobber (reg:CC FLAGS_REG))]
15167 "bsr{l}\t{%1, %0|%0, %1}"
15168 [(set_attr "type" "alu1")
15169 (set_attr "prefix_0f" "1")
15170 (set_attr "mode" "SI")])
15172 (define_insn "popcount<mode>2"
15173 [(set (match_operand:SWI248 0 "register_operand" "=r")
15175 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15176 (clobber (reg:CC FLAGS_REG))]
15180 return "popcnt\t{%1, %0|%0, %1}";
15182 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15185 [(set_attr "prefix_rep" "1")
15186 (set_attr "type" "bitmanip")
15187 (set_attr "mode" "<MODE>")])
15189 (define_insn "*popcount<mode>2_cmp"
15190 [(set (reg FLAGS_REG)
15193 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15195 (set (match_operand:SWI248 0 "register_operand" "=r")
15196 (popcount:SWI248 (match_dup 1)))]
15197 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15200 return "popcnt\t{%1, %0|%0, %1}";
15202 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15205 [(set_attr "prefix_rep" "1")
15206 (set_attr "type" "bitmanip")
15207 (set_attr "mode" "<MODE>")])
15209 (define_insn "*popcountsi2_cmp_zext"
15210 [(set (reg FLAGS_REG)
15212 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15214 (set (match_operand:DI 0 "register_operand" "=r")
15215 (zero_extend:DI(popcount:SI (match_dup 1))))]
15216 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15219 return "popcnt\t{%1, %0|%0, %1}";
15221 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15224 [(set_attr "prefix_rep" "1")
15225 (set_attr "type" "bitmanip")
15226 (set_attr "mode" "SI")])
15228 (define_expand "bswapsi2"
15229 [(set (match_operand:SI 0 "register_operand" "")
15230 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15233 if (!(TARGET_BSWAP || TARGET_MOVBE))
15235 rtx x = operands[0];
15237 emit_move_insn (x, operands[1]);
15238 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15239 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15240 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15245 (define_insn "*bswapsi_movbe"
15246 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
15247 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
15248 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15251 movbe\t{%1, %0|%0, %1}
15252 movbe\t{%1, %0|%0, %1}"
15253 [(set_attr "type" "*,imov,imov")
15254 (set_attr "modrm" "*,1,1")
15255 (set_attr "prefix_0f" "1")
15256 (set_attr "prefix_extra" "*,1,1")
15257 (set_attr "length" "2,*,*")
15258 (set_attr "mode" "SI")])
15260 (define_insn "*bswapsi_1"
15261 [(set (match_operand:SI 0 "register_operand" "=r")
15262 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15265 [(set_attr "prefix_0f" "1")
15266 (set_attr "length" "2")])
15268 (define_insn "*bswaphi_lowpart_1"
15269 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15270 (bswap:HI (match_dup 0)))
15271 (clobber (reg:CC FLAGS_REG))]
15272 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15274 xchg{b}\t{%h0, %b0|%b0, %h0}
15275 rol{w}\t{$8, %0|%0, 8}"
15276 [(set_attr "length" "2,4")
15277 (set_attr "mode" "QI,HI")])
15279 (define_insn "bswaphi_lowpart"
15280 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15281 (bswap:HI (match_dup 0)))
15282 (clobber (reg:CC FLAGS_REG))]
15284 "rol{w}\t{$8, %0|%0, 8}"
15285 [(set_attr "length" "4")
15286 (set_attr "mode" "HI")])
15288 (define_expand "bswapdi2"
15289 [(set (match_operand:DI 0 "register_operand" "")
15290 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
15294 (define_insn "*bswapdi_movbe"
15295 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
15296 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
15297 "TARGET_64BIT && TARGET_MOVBE
15298 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15301 movbe\t{%1, %0|%0, %1}
15302 movbe\t{%1, %0|%0, %1}"
15303 [(set_attr "type" "*,imov,imov")
15304 (set_attr "modrm" "*,1,1")
15305 (set_attr "prefix_0f" "1")
15306 (set_attr "prefix_extra" "*,1,1")
15307 (set_attr "length" "3,*,*")
15308 (set_attr "mode" "DI")])
15310 (define_insn "*bswapdi_1"
15311 [(set (match_operand:DI 0 "register_operand" "=r")
15312 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15315 [(set_attr "prefix_0f" "1")
15316 (set_attr "length" "3")])
15318 (define_expand "clzdi2"
15320 [(set (match_operand:DI 0 "register_operand" "")
15321 (minus:DI (const_int 63)
15322 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15323 (clobber (reg:CC FLAGS_REG))])
15325 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15326 (clobber (reg:CC FLAGS_REG))])]
15331 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15336 (define_insn "clzdi2_abm"
15337 [(set (match_operand:DI 0 "register_operand" "=r")
15338 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15339 (clobber (reg:CC FLAGS_REG))]
15340 "TARGET_64BIT && TARGET_ABM"
15341 "lzcnt{q}\t{%1, %0|%0, %1}"
15342 [(set_attr "prefix_rep" "1")
15343 (set_attr "type" "bitmanip")
15344 (set_attr "mode" "DI")])
15346 (define_insn "bsr_rex64"
15347 [(set (match_operand:DI 0 "register_operand" "=r")
15348 (minus:DI (const_int 63)
15349 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15350 (clobber (reg:CC FLAGS_REG))]
15352 "bsr{q}\t{%1, %0|%0, %1}"
15353 [(set_attr "type" "alu1")
15354 (set_attr "prefix_0f" "1")
15355 (set_attr "mode" "DI")])
15357 (define_expand "clzhi2"
15359 [(set (match_operand:HI 0 "register_operand" "")
15360 (minus:HI (const_int 15)
15361 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15362 (clobber (reg:CC FLAGS_REG))])
15364 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15365 (clobber (reg:CC FLAGS_REG))])]
15370 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15375 (define_insn "clzhi2_abm"
15376 [(set (match_operand:HI 0 "register_operand" "=r")
15377 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15378 (clobber (reg:CC FLAGS_REG))]
15380 "lzcnt{w}\t{%1, %0|%0, %1}"
15381 [(set_attr "prefix_rep" "1")
15382 (set_attr "type" "bitmanip")
15383 (set_attr "mode" "HI")])
15385 (define_insn "*bsrhi"
15386 [(set (match_operand:HI 0 "register_operand" "=r")
15387 (minus:HI (const_int 15)
15388 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15389 (clobber (reg:CC FLAGS_REG))]
15391 "bsr{w}\t{%1, %0|%0, %1}"
15392 [(set_attr "type" "alu1")
15393 (set_attr "prefix_0f" "1")
15394 (set_attr "mode" "HI")])
15396 (define_expand "paritydi2"
15397 [(set (match_operand:DI 0 "register_operand" "")
15398 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15401 rtx scratch = gen_reg_rtx (QImode);
15404 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15405 NULL_RTX, operands[1]));
15407 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15408 gen_rtx_REG (CCmode, FLAGS_REG),
15410 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15413 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15416 rtx tmp = gen_reg_rtx (SImode);
15418 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15419 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15424 (define_insn_and_split "paritydi2_cmp"
15425 [(set (reg:CC FLAGS_REG)
15426 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15427 (clobber (match_scratch:DI 0 "=r"))
15428 (clobber (match_scratch:SI 1 "=&r"))
15429 (clobber (match_scratch:HI 2 "=Q"))]
15432 "&& reload_completed"
15434 [(set (match_dup 1)
15435 (xor:SI (match_dup 1) (match_dup 4)))
15436 (clobber (reg:CC FLAGS_REG))])
15438 [(set (reg:CC FLAGS_REG)
15439 (parity:CC (match_dup 1)))
15440 (clobber (match_dup 1))
15441 (clobber (match_dup 2))])]
15443 operands[4] = gen_lowpart (SImode, operands[3]);
15447 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15448 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15451 operands[1] = gen_highpart (SImode, operands[3]);
15454 (define_expand "paritysi2"
15455 [(set (match_operand:SI 0 "register_operand" "")
15456 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15459 rtx scratch = gen_reg_rtx (QImode);
15462 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15464 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15465 gen_rtx_REG (CCmode, FLAGS_REG),
15467 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15469 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15473 (define_insn_and_split "paritysi2_cmp"
15474 [(set (reg:CC FLAGS_REG)
15475 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15476 (clobber (match_scratch:SI 0 "=r"))
15477 (clobber (match_scratch:HI 1 "=&Q"))]
15480 "&& reload_completed"
15482 [(set (match_dup 1)
15483 (xor:HI (match_dup 1) (match_dup 3)))
15484 (clobber (reg:CC FLAGS_REG))])
15486 [(set (reg:CC FLAGS_REG)
15487 (parity:CC (match_dup 1)))
15488 (clobber (match_dup 1))])]
15490 operands[3] = gen_lowpart (HImode, operands[2]);
15492 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15493 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15496 (define_insn "*parityhi2_cmp"
15497 [(set (reg:CC FLAGS_REG)
15498 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15499 (clobber (match_scratch:HI 0 "=Q"))]
15501 "xor{b}\t{%h0, %b0|%b0, %h0}"
15502 [(set_attr "length" "2")
15503 (set_attr "mode" "HI")])
15505 (define_insn "*parityqi2_cmp"
15506 [(set (reg:CC FLAGS_REG)
15507 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15510 [(set_attr "length" "2")
15511 (set_attr "mode" "QI")])
15513 ;; Thread-local storage patterns for ELF.
15515 ;; Note that these code sequences must appear exactly as shown
15516 ;; in order to allow linker relaxation.
15518 (define_insn "*tls_global_dynamic_32_gnu"
15519 [(set (match_operand:SI 0 "register_operand" "=a")
15520 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15521 (match_operand:SI 2 "tls_symbolic_operand" "")
15522 (match_operand:SI 3 "call_insn_operand" "")]
15524 (clobber (match_scratch:SI 4 "=d"))
15525 (clobber (match_scratch:SI 5 "=c"))
15526 (clobber (reg:CC FLAGS_REG))]
15527 "!TARGET_64BIT && TARGET_GNU_TLS"
15528 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15529 [(set_attr "type" "multi")
15530 (set_attr "length" "12")])
15532 (define_insn "*tls_global_dynamic_32_sun"
15533 [(set (match_operand:SI 0 "register_operand" "=a")
15534 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15535 (match_operand:SI 2 "tls_symbolic_operand" "")
15536 (match_operand:SI 3 "call_insn_operand" "")]
15538 (clobber (match_scratch:SI 4 "=d"))
15539 (clobber (match_scratch:SI 5 "=c"))
15540 (clobber (reg:CC FLAGS_REG))]
15541 "!TARGET_64BIT && TARGET_SUN_TLS"
15542 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15543 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15544 [(set_attr "type" "multi")
15545 (set_attr "length" "14")])
15547 (define_expand "tls_global_dynamic_32"
15548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15551 (match_operand:SI 1 "tls_symbolic_operand" "")
15554 (clobber (match_scratch:SI 4 ""))
15555 (clobber (match_scratch:SI 5 ""))
15556 (clobber (reg:CC FLAGS_REG))])]
15560 operands[2] = pic_offset_table_rtx;
15563 operands[2] = gen_reg_rtx (Pmode);
15564 emit_insn (gen_set_got (operands[2]));
15566 if (TARGET_GNU2_TLS)
15568 emit_insn (gen_tls_dynamic_gnu2_32
15569 (operands[0], operands[1], operands[2]));
15572 operands[3] = ix86_tls_get_addr ();
15575 (define_insn "*tls_global_dynamic_64"
15576 [(set (match_operand:DI 0 "register_operand" "=a")
15577 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15578 (match_operand:DI 3 "" "")))
15579 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15582 { 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"; }
15583 [(set_attr "type" "multi")
15584 (set_attr "length" "16")])
15586 (define_expand "tls_global_dynamic_64"
15587 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15588 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15589 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15593 if (TARGET_GNU2_TLS)
15595 emit_insn (gen_tls_dynamic_gnu2_64
15596 (operands[0], operands[1]));
15599 operands[2] = ix86_tls_get_addr ();
15602 (define_insn "*tls_local_dynamic_base_32_gnu"
15603 [(set (match_operand:SI 0 "register_operand" "=a")
15604 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15605 (match_operand:SI 2 "call_insn_operand" "")]
15606 UNSPEC_TLS_LD_BASE))
15607 (clobber (match_scratch:SI 3 "=d"))
15608 (clobber (match_scratch:SI 4 "=c"))
15609 (clobber (reg:CC FLAGS_REG))]
15610 "!TARGET_64BIT && TARGET_GNU_TLS"
15611 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15612 [(set_attr "type" "multi")
15613 (set_attr "length" "11")])
15615 (define_insn "*tls_local_dynamic_base_32_sun"
15616 [(set (match_operand:SI 0 "register_operand" "=a")
15617 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15618 (match_operand:SI 2 "call_insn_operand" "")]
15619 UNSPEC_TLS_LD_BASE))
15620 (clobber (match_scratch:SI 3 "=d"))
15621 (clobber (match_scratch:SI 4 "=c"))
15622 (clobber (reg:CC FLAGS_REG))]
15623 "!TARGET_64BIT && TARGET_SUN_TLS"
15624 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15625 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15626 [(set_attr "type" "multi")
15627 (set_attr "length" "13")])
15629 (define_expand "tls_local_dynamic_base_32"
15630 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15631 (unspec:SI [(match_dup 1) (match_dup 2)]
15632 UNSPEC_TLS_LD_BASE))
15633 (clobber (match_scratch:SI 3 ""))
15634 (clobber (match_scratch:SI 4 ""))
15635 (clobber (reg:CC FLAGS_REG))])]
15639 operands[1] = pic_offset_table_rtx;
15642 operands[1] = gen_reg_rtx (Pmode);
15643 emit_insn (gen_set_got (operands[1]));
15645 if (TARGET_GNU2_TLS)
15647 emit_insn (gen_tls_dynamic_gnu2_32
15648 (operands[0], ix86_tls_module_base (), operands[1]));
15651 operands[2] = ix86_tls_get_addr ();
15654 (define_insn "*tls_local_dynamic_base_64"
15655 [(set (match_operand:DI 0 "register_operand" "=a")
15656 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15657 (match_operand:DI 2 "" "")))
15658 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15660 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15661 [(set_attr "type" "multi")
15662 (set_attr "length" "12")])
15664 (define_expand "tls_local_dynamic_base_64"
15665 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15666 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15667 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15670 if (TARGET_GNU2_TLS)
15672 emit_insn (gen_tls_dynamic_gnu2_64
15673 (operands[0], ix86_tls_module_base ()));
15676 operands[1] = ix86_tls_get_addr ();
15679 ;; Local dynamic of a single variable is a lose. Show combine how
15680 ;; to convert that back to global dynamic.
15682 (define_insn_and_split "*tls_local_dynamic_32_once"
15683 [(set (match_operand:SI 0 "register_operand" "=a")
15684 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15685 (match_operand:SI 2 "call_insn_operand" "")]
15686 UNSPEC_TLS_LD_BASE)
15687 (const:SI (unspec:SI
15688 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15690 (clobber (match_scratch:SI 4 "=d"))
15691 (clobber (match_scratch:SI 5 "=c"))
15692 (clobber (reg:CC FLAGS_REG))]
15696 [(parallel [(set (match_dup 0)
15697 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15699 (clobber (match_dup 4))
15700 (clobber (match_dup 5))
15701 (clobber (reg:CC FLAGS_REG))])]
15704 ;; Load and add the thread base pointer from %gs:0.
15706 (define_insn "*load_tp_si"
15707 [(set (match_operand:SI 0 "register_operand" "=r")
15708 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15710 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15711 [(set_attr "type" "imov")
15712 (set_attr "modrm" "0")
15713 (set_attr "length" "7")
15714 (set_attr "memory" "load")
15715 (set_attr "imm_disp" "false")])
15717 (define_insn "*add_tp_si"
15718 [(set (match_operand:SI 0 "register_operand" "=r")
15719 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15720 (match_operand:SI 1 "register_operand" "0")))
15721 (clobber (reg:CC FLAGS_REG))]
15723 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15724 [(set_attr "type" "alu")
15725 (set_attr "modrm" "0")
15726 (set_attr "length" "7")
15727 (set_attr "memory" "load")
15728 (set_attr "imm_disp" "false")])
15730 (define_insn "*load_tp_di"
15731 [(set (match_operand:DI 0 "register_operand" "=r")
15732 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15734 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15735 [(set_attr "type" "imov")
15736 (set_attr "modrm" "0")
15737 (set_attr "length" "7")
15738 (set_attr "memory" "load")
15739 (set_attr "imm_disp" "false")])
15741 (define_insn "*add_tp_di"
15742 [(set (match_operand:DI 0 "register_operand" "=r")
15743 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15744 (match_operand:DI 1 "register_operand" "0")))
15745 (clobber (reg:CC FLAGS_REG))]
15747 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15748 [(set_attr "type" "alu")
15749 (set_attr "modrm" "0")
15750 (set_attr "length" "7")
15751 (set_attr "memory" "load")
15752 (set_attr "imm_disp" "false")])
15754 ;; GNU2 TLS patterns can be split.
15756 (define_expand "tls_dynamic_gnu2_32"
15757 [(set (match_dup 3)
15758 (plus:SI (match_operand:SI 2 "register_operand" "")
15760 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15763 [(set (match_operand:SI 0 "register_operand" "")
15764 (unspec:SI [(match_dup 1) (match_dup 3)
15765 (match_dup 2) (reg:SI SP_REG)]
15767 (clobber (reg:CC FLAGS_REG))])]
15768 "!TARGET_64BIT && TARGET_GNU2_TLS"
15770 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15771 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15774 (define_insn "*tls_dynamic_lea_32"
15775 [(set (match_operand:SI 0 "register_operand" "=r")
15776 (plus:SI (match_operand:SI 1 "register_operand" "b")
15778 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15779 UNSPEC_TLSDESC))))]
15780 "!TARGET_64BIT && TARGET_GNU2_TLS"
15781 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15782 [(set_attr "type" "lea")
15783 (set_attr "mode" "SI")
15784 (set_attr "length" "6")
15785 (set_attr "length_address" "4")])
15787 (define_insn "*tls_dynamic_call_32"
15788 [(set (match_operand:SI 0 "register_operand" "=a")
15789 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15790 (match_operand:SI 2 "register_operand" "0")
15791 ;; we have to make sure %ebx still points to the GOT
15792 (match_operand:SI 3 "register_operand" "b")
15795 (clobber (reg:CC FLAGS_REG))]
15796 "!TARGET_64BIT && TARGET_GNU2_TLS"
15797 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15798 [(set_attr "type" "call")
15799 (set_attr "length" "2")
15800 (set_attr "length_address" "0")])
15802 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15803 [(set (match_operand:SI 0 "register_operand" "=&a")
15805 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15806 (match_operand:SI 4 "" "")
15807 (match_operand:SI 2 "register_operand" "b")
15810 (const:SI (unspec:SI
15811 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15813 (clobber (reg:CC FLAGS_REG))]
15814 "!TARGET_64BIT && TARGET_GNU2_TLS"
15817 [(set (match_dup 0) (match_dup 5))]
15819 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15820 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15823 (define_expand "tls_dynamic_gnu2_64"
15824 [(set (match_dup 2)
15825 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15828 [(set (match_operand:DI 0 "register_operand" "")
15829 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15831 (clobber (reg:CC FLAGS_REG))])]
15832 "TARGET_64BIT && TARGET_GNU2_TLS"
15834 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15835 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15838 (define_insn "*tls_dynamic_lea_64"
15839 [(set (match_operand:DI 0 "register_operand" "=r")
15840 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15842 "TARGET_64BIT && TARGET_GNU2_TLS"
15843 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15844 [(set_attr "type" "lea")
15845 (set_attr "mode" "DI")
15846 (set_attr "length" "7")
15847 (set_attr "length_address" "4")])
15849 (define_insn "*tls_dynamic_call_64"
15850 [(set (match_operand:DI 0 "register_operand" "=a")
15851 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15852 (match_operand:DI 2 "register_operand" "0")
15855 (clobber (reg:CC FLAGS_REG))]
15856 "TARGET_64BIT && TARGET_GNU2_TLS"
15857 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15858 [(set_attr "type" "call")
15859 (set_attr "length" "2")
15860 (set_attr "length_address" "0")])
15862 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15863 [(set (match_operand:DI 0 "register_operand" "=&a")
15865 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15866 (match_operand:DI 3 "" "")
15869 (const:DI (unspec:DI
15870 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15872 (clobber (reg:CC FLAGS_REG))]
15873 "TARGET_64BIT && TARGET_GNU2_TLS"
15876 [(set (match_dup 0) (match_dup 4))]
15878 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15879 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15884 ;; These patterns match the binary 387 instructions for addM3, subM3,
15885 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15886 ;; SFmode. The first is the normal insn, the second the same insn but
15887 ;; with one operand a conversion, and the third the same insn but with
15888 ;; the other operand a conversion. The conversion may be SFmode or
15889 ;; SImode if the target mode DFmode, but only SImode if the target mode
15892 ;; Gcc is slightly more smart about handling normal two address instructions
15893 ;; so use special patterns for add and mull.
15895 (define_insn "*fop_<mode>_comm_mixed_avx"
15896 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15897 (match_operator:MODEF 3 "binary_fp_operator"
15898 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15899 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15900 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15901 && COMMUTATIVE_ARITH_P (operands[3])
15902 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15903 "* return output_387_binary_op (insn, operands);"
15904 [(set (attr "type")
15905 (if_then_else (eq_attr "alternative" "1")
15906 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15907 (const_string "ssemul")
15908 (const_string "sseadd"))
15909 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15910 (const_string "fmul")
15911 (const_string "fop"))))
15912 (set_attr "prefix" "orig,maybe_vex")
15913 (set_attr "mode" "<MODE>")])
15915 (define_insn "*fop_<mode>_comm_mixed"
15916 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15917 (match_operator:MODEF 3 "binary_fp_operator"
15918 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15919 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15921 && COMMUTATIVE_ARITH_P (operands[3])
15922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15923 "* return output_387_binary_op (insn, operands);"
15924 [(set (attr "type")
15925 (if_then_else (eq_attr "alternative" "1")
15926 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15927 (const_string "ssemul")
15928 (const_string "sseadd"))
15929 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15930 (const_string "fmul")
15931 (const_string "fop"))))
15932 (set_attr "mode" "<MODE>")])
15934 (define_insn "*fop_<mode>_comm_avx"
15935 [(set (match_operand:MODEF 0 "register_operand" "=x")
15936 (match_operator:MODEF 3 "binary_fp_operator"
15937 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15938 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15939 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15940 && COMMUTATIVE_ARITH_P (operands[3])
15941 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15942 "* return output_387_binary_op (insn, operands);"
15943 [(set (attr "type")
15944 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15945 (const_string "ssemul")
15946 (const_string "sseadd")))
15947 (set_attr "prefix" "vex")
15948 (set_attr "mode" "<MODE>")])
15950 (define_insn "*fop_<mode>_comm_sse"
15951 [(set (match_operand:MODEF 0 "register_operand" "=x")
15952 (match_operator:MODEF 3 "binary_fp_operator"
15953 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15954 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15955 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15956 && COMMUTATIVE_ARITH_P (operands[3])
15957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15958 "* return output_387_binary_op (insn, operands);"
15959 [(set (attr "type")
15960 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15961 (const_string "ssemul")
15962 (const_string "sseadd")))
15963 (set_attr "mode" "<MODE>")])
15965 (define_insn "*fop_<mode>_comm_i387"
15966 [(set (match_operand:MODEF 0 "register_operand" "=f")
15967 (match_operator:MODEF 3 "binary_fp_operator"
15968 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15969 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15970 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15971 && COMMUTATIVE_ARITH_P (operands[3])
15972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15973 "* return output_387_binary_op (insn, operands);"
15974 [(set (attr "type")
15975 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15976 (const_string "fmul")
15977 (const_string "fop")))
15978 (set_attr "mode" "<MODE>")])
15980 (define_insn "*fop_<mode>_1_mixed_avx"
15981 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15982 (match_operator:MODEF 3 "binary_fp_operator"
15983 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15984 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15985 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15986 && !COMMUTATIVE_ARITH_P (operands[3])
15987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15988 "* return output_387_binary_op (insn, operands);"
15989 [(set (attr "type")
15990 (cond [(and (eq_attr "alternative" "2")
15991 (match_operand:MODEF 3 "mult_operator" ""))
15992 (const_string "ssemul")
15993 (and (eq_attr "alternative" "2")
15994 (match_operand:MODEF 3 "div_operator" ""))
15995 (const_string "ssediv")
15996 (eq_attr "alternative" "2")
15997 (const_string "sseadd")
15998 (match_operand:MODEF 3 "mult_operator" "")
15999 (const_string "fmul")
16000 (match_operand:MODEF 3 "div_operator" "")
16001 (const_string "fdiv")
16003 (const_string "fop")))
16004 (set_attr "prefix" "orig,orig,maybe_vex")
16005 (set_attr "mode" "<MODE>")])
16007 (define_insn "*fop_<mode>_1_mixed"
16008 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16009 (match_operator:MODEF 3 "binary_fp_operator"
16010 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16011 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16012 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16013 && !COMMUTATIVE_ARITH_P (operands[3])
16014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16015 "* return output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (cond [(and (eq_attr "alternative" "2")
16018 (match_operand:MODEF 3 "mult_operator" ""))
16019 (const_string "ssemul")
16020 (and (eq_attr "alternative" "2")
16021 (match_operand:MODEF 3 "div_operator" ""))
16022 (const_string "ssediv")
16023 (eq_attr "alternative" "2")
16024 (const_string "sseadd")
16025 (match_operand:MODEF 3 "mult_operator" "")
16026 (const_string "fmul")
16027 (match_operand:MODEF 3 "div_operator" "")
16028 (const_string "fdiv")
16030 (const_string "fop")))
16031 (set_attr "mode" "<MODE>")])
16033 (define_insn "*rcpsf2_sse"
16034 [(set (match_operand:SF 0 "register_operand" "=x")
16035 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16038 "%vrcpss\t{%1, %d0|%d0, %1}"
16039 [(set_attr "type" "sse")
16040 (set_attr "atom_sse_attr" "rcp")
16041 (set_attr "prefix" "maybe_vex")
16042 (set_attr "mode" "SF")])
16044 (define_insn "*fop_<mode>_1_avx"
16045 [(set (match_operand:MODEF 0 "register_operand" "=x")
16046 (match_operator:MODEF 3 "binary_fp_operator"
16047 [(match_operand:MODEF 1 "register_operand" "x")
16048 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16049 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16050 && !COMMUTATIVE_ARITH_P (operands[3])"
16051 "* return output_387_binary_op (insn, operands);"
16052 [(set (attr "type")
16053 (cond [(match_operand:MODEF 3 "mult_operator" "")
16054 (const_string "ssemul")
16055 (match_operand:MODEF 3 "div_operator" "")
16056 (const_string "ssediv")
16058 (const_string "sseadd")))
16059 (set_attr "prefix" "vex")
16060 (set_attr "mode" "<MODE>")])
16062 (define_insn "*fop_<mode>_1_sse"
16063 [(set (match_operand:MODEF 0 "register_operand" "=x")
16064 (match_operator:MODEF 3 "binary_fp_operator"
16065 [(match_operand:MODEF 1 "register_operand" "0")
16066 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16067 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16068 && !COMMUTATIVE_ARITH_P (operands[3])"
16069 "* return output_387_binary_op (insn, operands);"
16070 [(set (attr "type")
16071 (cond [(match_operand:MODEF 3 "mult_operator" "")
16072 (const_string "ssemul")
16073 (match_operand:MODEF 3 "div_operator" "")
16074 (const_string "ssediv")
16076 (const_string "sseadd")))
16077 (set_attr "mode" "<MODE>")])
16079 ;; This pattern is not fully shadowed by the pattern above.
16080 (define_insn "*fop_<mode>_1_i387"
16081 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16082 (match_operator:MODEF 3 "binary_fp_operator"
16083 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16084 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16085 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16086 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16087 && !COMMUTATIVE_ARITH_P (operands[3])
16088 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16089 "* return output_387_binary_op (insn, operands);"
16090 [(set (attr "type")
16091 (cond [(match_operand:MODEF 3 "mult_operator" "")
16092 (const_string "fmul")
16093 (match_operand:MODEF 3 "div_operator" "")
16094 (const_string "fdiv")
16096 (const_string "fop")))
16097 (set_attr "mode" "<MODE>")])
16099 ;; ??? Add SSE splitters for these!
16100 (define_insn "*fop_<MODEF:mode>_2_i387"
16101 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16102 (match_operator:MODEF 3 "binary_fp_operator"
16104 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16105 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16106 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16107 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16108 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16109 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16110 [(set (attr "type")
16111 (cond [(match_operand:MODEF 3 "mult_operator" "")
16112 (const_string "fmul")
16113 (match_operand:MODEF 3 "div_operator" "")
16114 (const_string "fdiv")
16116 (const_string "fop")))
16117 (set_attr "fp_int_src" "true")
16118 (set_attr "mode" "<X87MODEI12:MODE>")])
16120 (define_insn "*fop_<MODEF:mode>_3_i387"
16121 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16122 (match_operator:MODEF 3 "binary_fp_operator"
16123 [(match_operand:MODEF 1 "register_operand" "0,0")
16125 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16126 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16127 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16128 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16129 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16130 [(set (attr "type")
16131 (cond [(match_operand:MODEF 3 "mult_operator" "")
16132 (const_string "fmul")
16133 (match_operand:MODEF 3 "div_operator" "")
16134 (const_string "fdiv")
16136 (const_string "fop")))
16137 (set_attr "fp_int_src" "true")
16138 (set_attr "mode" "<MODE>")])
16140 (define_insn "*fop_df_4_i387"
16141 [(set (match_operand:DF 0 "register_operand" "=f,f")
16142 (match_operator:DF 3 "binary_fp_operator"
16144 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16145 (match_operand:DF 2 "register_operand" "0,f")]))]
16146 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16147 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16148 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16149 "* return output_387_binary_op (insn, operands);"
16150 [(set (attr "type")
16151 (cond [(match_operand:DF 3 "mult_operator" "")
16152 (const_string "fmul")
16153 (match_operand:DF 3 "div_operator" "")
16154 (const_string "fdiv")
16156 (const_string "fop")))
16157 (set_attr "mode" "SF")])
16159 (define_insn "*fop_df_5_i387"
16160 [(set (match_operand:DF 0 "register_operand" "=f,f")
16161 (match_operator:DF 3 "binary_fp_operator"
16162 [(match_operand:DF 1 "register_operand" "0,f")
16164 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16165 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16166 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16167 "* return output_387_binary_op (insn, operands);"
16168 [(set (attr "type")
16169 (cond [(match_operand:DF 3 "mult_operator" "")
16170 (const_string "fmul")
16171 (match_operand:DF 3 "div_operator" "")
16172 (const_string "fdiv")
16174 (const_string "fop")))
16175 (set_attr "mode" "SF")])
16177 (define_insn "*fop_df_6_i387"
16178 [(set (match_operand:DF 0 "register_operand" "=f,f")
16179 (match_operator:DF 3 "binary_fp_operator"
16181 (match_operand:SF 1 "register_operand" "0,f"))
16183 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16184 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16185 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16186 "* return output_387_binary_op (insn, operands);"
16187 [(set (attr "type")
16188 (cond [(match_operand:DF 3 "mult_operator" "")
16189 (const_string "fmul")
16190 (match_operand:DF 3 "div_operator" "")
16191 (const_string "fdiv")
16193 (const_string "fop")))
16194 (set_attr "mode" "SF")])
16196 (define_insn "*fop_xf_comm_i387"
16197 [(set (match_operand:XF 0 "register_operand" "=f")
16198 (match_operator:XF 3 "binary_fp_operator"
16199 [(match_operand:XF 1 "register_operand" "%0")
16200 (match_operand:XF 2 "register_operand" "f")]))]
16202 && COMMUTATIVE_ARITH_P (operands[3])"
16203 "* return output_387_binary_op (insn, operands);"
16204 [(set (attr "type")
16205 (if_then_else (match_operand:XF 3 "mult_operator" "")
16206 (const_string "fmul")
16207 (const_string "fop")))
16208 (set_attr "mode" "XF")])
16210 (define_insn "*fop_xf_1_i387"
16211 [(set (match_operand:XF 0 "register_operand" "=f,f")
16212 (match_operator:XF 3 "binary_fp_operator"
16213 [(match_operand:XF 1 "register_operand" "0,f")
16214 (match_operand:XF 2 "register_operand" "f,0")]))]
16216 && !COMMUTATIVE_ARITH_P (operands[3])"
16217 "* return output_387_binary_op (insn, operands);"
16218 [(set (attr "type")
16219 (cond [(match_operand:XF 3 "mult_operator" "")
16220 (const_string "fmul")
16221 (match_operand:XF 3 "div_operator" "")
16222 (const_string "fdiv")
16224 (const_string "fop")))
16225 (set_attr "mode" "XF")])
16227 (define_insn "*fop_xf_2_i387"
16228 [(set (match_operand:XF 0 "register_operand" "=f,f")
16229 (match_operator:XF 3 "binary_fp_operator"
16231 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16232 (match_operand:XF 2 "register_operand" "0,0")]))]
16233 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16234 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16235 [(set (attr "type")
16236 (cond [(match_operand:XF 3 "mult_operator" "")
16237 (const_string "fmul")
16238 (match_operand:XF 3 "div_operator" "")
16239 (const_string "fdiv")
16241 (const_string "fop")))
16242 (set_attr "fp_int_src" "true")
16243 (set_attr "mode" "<MODE>")])
16245 (define_insn "*fop_xf_3_i387"
16246 [(set (match_operand:XF 0 "register_operand" "=f,f")
16247 (match_operator:XF 3 "binary_fp_operator"
16248 [(match_operand:XF 1 "register_operand" "0,0")
16250 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16251 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16252 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16253 [(set (attr "type")
16254 (cond [(match_operand:XF 3 "mult_operator" "")
16255 (const_string "fmul")
16256 (match_operand:XF 3 "div_operator" "")
16257 (const_string "fdiv")
16259 (const_string "fop")))
16260 (set_attr "fp_int_src" "true")
16261 (set_attr "mode" "<MODE>")])
16263 (define_insn "*fop_xf_4_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f,f")
16265 (match_operator:XF 3 "binary_fp_operator"
16267 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16268 (match_operand:XF 2 "register_operand" "0,f")]))]
16270 "* return output_387_binary_op (insn, operands);"
16271 [(set (attr "type")
16272 (cond [(match_operand:XF 3 "mult_operator" "")
16273 (const_string "fmul")
16274 (match_operand:XF 3 "div_operator" "")
16275 (const_string "fdiv")
16277 (const_string "fop")))
16278 (set_attr "mode" "<MODE>")])
16280 (define_insn "*fop_xf_5_i387"
16281 [(set (match_operand:XF 0 "register_operand" "=f,f")
16282 (match_operator:XF 3 "binary_fp_operator"
16283 [(match_operand:XF 1 "register_operand" "0,f")
16285 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16287 "* return output_387_binary_op (insn, operands);"
16288 [(set (attr "type")
16289 (cond [(match_operand:XF 3 "mult_operator" "")
16290 (const_string "fmul")
16291 (match_operand:XF 3 "div_operator" "")
16292 (const_string "fdiv")
16294 (const_string "fop")))
16295 (set_attr "mode" "<MODE>")])
16297 (define_insn "*fop_xf_6_i387"
16298 [(set (match_operand:XF 0 "register_operand" "=f,f")
16299 (match_operator:XF 3 "binary_fp_operator"
16301 (match_operand:MODEF 1 "register_operand" "0,f"))
16303 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16305 "* return output_387_binary_op (insn, operands);"
16306 [(set (attr "type")
16307 (cond [(match_operand:XF 3 "mult_operator" "")
16308 (const_string "fmul")
16309 (match_operand:XF 3 "div_operator" "")
16310 (const_string "fdiv")
16312 (const_string "fop")))
16313 (set_attr "mode" "<MODE>")])
16316 [(set (match_operand 0 "register_operand" "")
16317 (match_operator 3 "binary_fp_operator"
16318 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16319 (match_operand 2 "register_operand" "")]))]
16321 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16322 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16325 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16326 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16327 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16328 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16329 GET_MODE (operands[3]),
16332 ix86_free_from_memory (GET_MODE (operands[1]));
16337 [(set (match_operand 0 "register_operand" "")
16338 (match_operator 3 "binary_fp_operator"
16339 [(match_operand 1 "register_operand" "")
16340 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16342 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16343 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16346 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16347 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16348 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16349 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16350 GET_MODE (operands[3]),
16353 ix86_free_from_memory (GET_MODE (operands[2]));
16357 ;; FPU special functions.
16359 ;; This pattern implements a no-op XFmode truncation for
16360 ;; all fancy i386 XFmode math functions.
16362 (define_insn "truncxf<mode>2_i387_noop_unspec"
16363 [(set (match_operand:MODEF 0 "register_operand" "=f")
16364 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16365 UNSPEC_TRUNC_NOOP))]
16366 "TARGET_USE_FANCY_MATH_387"
16367 "* return output_387_reg_move (insn, operands);"
16368 [(set_attr "type" "fmov")
16369 (set_attr "mode" "<MODE>")])
16371 (define_insn "sqrtxf2"
16372 [(set (match_operand:XF 0 "register_operand" "=f")
16373 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16374 "TARGET_USE_FANCY_MATH_387"
16376 [(set_attr "type" "fpspc")
16377 (set_attr "mode" "XF")
16378 (set_attr "athlon_decode" "direct")
16379 (set_attr "amdfam10_decode" "direct")])
16381 (define_insn "sqrt_extend<mode>xf2_i387"
16382 [(set (match_operand:XF 0 "register_operand" "=f")
16385 (match_operand:MODEF 1 "register_operand" "0"))))]
16386 "TARGET_USE_FANCY_MATH_387"
16388 [(set_attr "type" "fpspc")
16389 (set_attr "mode" "XF")
16390 (set_attr "athlon_decode" "direct")
16391 (set_attr "amdfam10_decode" "direct")])
16393 (define_insn "*rsqrtsf2_sse"
16394 [(set (match_operand:SF 0 "register_operand" "=x")
16395 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16398 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16399 [(set_attr "type" "sse")
16400 (set_attr "atom_sse_attr" "rcp")
16401 (set_attr "prefix" "maybe_vex")
16402 (set_attr "mode" "SF")])
16404 (define_expand "rsqrtsf2"
16405 [(set (match_operand:SF 0 "register_operand" "")
16406 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16410 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16414 (define_insn "*sqrt<mode>2_sse"
16415 [(set (match_operand:MODEF 0 "register_operand" "=x")
16417 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16418 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16419 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16420 [(set_attr "type" "sse")
16421 (set_attr "atom_sse_attr" "sqrt")
16422 (set_attr "prefix" "maybe_vex")
16423 (set_attr "mode" "<MODE>")
16424 (set_attr "athlon_decode" "*")
16425 (set_attr "amdfam10_decode" "*")])
16427 (define_expand "sqrt<mode>2"
16428 [(set (match_operand:MODEF 0 "register_operand" "")
16430 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16431 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16434 if (<MODE>mode == SFmode
16435 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16436 && flag_finite_math_only && !flag_trapping_math
16437 && flag_unsafe_math_optimizations)
16439 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16443 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16445 rtx op0 = gen_reg_rtx (XFmode);
16446 rtx op1 = force_reg (<MODE>mode, operands[1]);
16448 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16449 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16454 (define_insn "fpremxf4_i387"
16455 [(set (match_operand:XF 0 "register_operand" "=f")
16456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16457 (match_operand:XF 3 "register_operand" "1")]
16459 (set (match_operand:XF 1 "register_operand" "=u")
16460 (unspec:XF [(match_dup 2) (match_dup 3)]
16462 (set (reg:CCFP FPSR_REG)
16463 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16465 "TARGET_USE_FANCY_MATH_387"
16467 [(set_attr "type" "fpspc")
16468 (set_attr "mode" "XF")])
16470 (define_expand "fmodxf3"
16471 [(use (match_operand:XF 0 "register_operand" ""))
16472 (use (match_operand:XF 1 "general_operand" ""))
16473 (use (match_operand:XF 2 "general_operand" ""))]
16474 "TARGET_USE_FANCY_MATH_387"
16476 rtx label = gen_label_rtx ();
16478 rtx op1 = gen_reg_rtx (XFmode);
16479 rtx op2 = gen_reg_rtx (XFmode);
16481 emit_move_insn (op2, operands[2]);
16482 emit_move_insn (op1, operands[1]);
16484 emit_label (label);
16485 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16486 ix86_emit_fp_unordered_jump (label);
16487 LABEL_NUSES (label) = 1;
16489 emit_move_insn (operands[0], op1);
16493 (define_expand "fmod<mode>3"
16494 [(use (match_operand:MODEF 0 "register_operand" ""))
16495 (use (match_operand:MODEF 1 "general_operand" ""))
16496 (use (match_operand:MODEF 2 "general_operand" ""))]
16497 "TARGET_USE_FANCY_MATH_387"
16499 rtx label = gen_label_rtx ();
16501 rtx op1 = gen_reg_rtx (XFmode);
16502 rtx op2 = gen_reg_rtx (XFmode);
16504 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16507 emit_label (label);
16508 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16509 ix86_emit_fp_unordered_jump (label);
16510 LABEL_NUSES (label) = 1;
16512 /* Truncate the result properly for strict SSE math. */
16513 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16514 && !TARGET_MIX_SSE_I387)
16515 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16517 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16522 (define_insn "fprem1xf4_i387"
16523 [(set (match_operand:XF 0 "register_operand" "=f")
16524 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16525 (match_operand:XF 3 "register_operand" "1")]
16527 (set (match_operand:XF 1 "register_operand" "=u")
16528 (unspec:XF [(match_dup 2) (match_dup 3)]
16530 (set (reg:CCFP FPSR_REG)
16531 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16533 "TARGET_USE_FANCY_MATH_387"
16535 [(set_attr "type" "fpspc")
16536 (set_attr "mode" "XF")])
16538 (define_expand "remainderxf3"
16539 [(use (match_operand:XF 0 "register_operand" ""))
16540 (use (match_operand:XF 1 "general_operand" ""))
16541 (use (match_operand:XF 2 "general_operand" ""))]
16542 "TARGET_USE_FANCY_MATH_387"
16544 rtx label = gen_label_rtx ();
16546 rtx op1 = gen_reg_rtx (XFmode);
16547 rtx op2 = gen_reg_rtx (XFmode);
16549 emit_move_insn (op2, operands[2]);
16550 emit_move_insn (op1, operands[1]);
16552 emit_label (label);
16553 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16554 ix86_emit_fp_unordered_jump (label);
16555 LABEL_NUSES (label) = 1;
16557 emit_move_insn (operands[0], op1);
16561 (define_expand "remainder<mode>3"
16562 [(use (match_operand:MODEF 0 "register_operand" ""))
16563 (use (match_operand:MODEF 1 "general_operand" ""))
16564 (use (match_operand:MODEF 2 "general_operand" ""))]
16565 "TARGET_USE_FANCY_MATH_387"
16567 rtx label = gen_label_rtx ();
16569 rtx op1 = gen_reg_rtx (XFmode);
16570 rtx op2 = gen_reg_rtx (XFmode);
16572 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16573 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16575 emit_label (label);
16577 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16578 ix86_emit_fp_unordered_jump (label);
16579 LABEL_NUSES (label) = 1;
16581 /* Truncate the result properly for strict SSE math. */
16582 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16583 && !TARGET_MIX_SSE_I387)
16584 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16586 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16591 (define_insn "*sinxf2_i387"
16592 [(set (match_operand:XF 0 "register_operand" "=f")
16593 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16594 "TARGET_USE_FANCY_MATH_387
16595 && flag_unsafe_math_optimizations"
16597 [(set_attr "type" "fpspc")
16598 (set_attr "mode" "XF")])
16600 (define_insn "*sin_extend<mode>xf2_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f")
16602 (unspec:XF [(float_extend:XF
16603 (match_operand:MODEF 1 "register_operand" "0"))]
16605 "TARGET_USE_FANCY_MATH_387
16606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16607 || TARGET_MIX_SSE_I387)
16608 && flag_unsafe_math_optimizations"
16610 [(set_attr "type" "fpspc")
16611 (set_attr "mode" "XF")])
16613 (define_insn "*cosxf2_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16616 "TARGET_USE_FANCY_MATH_387
16617 && flag_unsafe_math_optimizations"
16619 [(set_attr "type" "fpspc")
16620 (set_attr "mode" "XF")])
16622 (define_insn "*cos_extend<mode>xf2_i387"
16623 [(set (match_operand:XF 0 "register_operand" "=f")
16624 (unspec:XF [(float_extend:XF
16625 (match_operand:MODEF 1 "register_operand" "0"))]
16627 "TARGET_USE_FANCY_MATH_387
16628 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16629 || TARGET_MIX_SSE_I387)
16630 && flag_unsafe_math_optimizations"
16632 [(set_attr "type" "fpspc")
16633 (set_attr "mode" "XF")])
16635 ;; When sincos pattern is defined, sin and cos builtin functions will be
16636 ;; expanded to sincos pattern with one of its outputs left unused.
16637 ;; CSE pass will figure out if two sincos patterns can be combined,
16638 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16639 ;; depending on the unused output.
16641 (define_insn "sincosxf3"
16642 [(set (match_operand:XF 0 "register_operand" "=f")
16643 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16644 UNSPEC_SINCOS_COS))
16645 (set (match_operand:XF 1 "register_operand" "=u")
16646 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16647 "TARGET_USE_FANCY_MATH_387
16648 && flag_unsafe_math_optimizations"
16650 [(set_attr "type" "fpspc")
16651 (set_attr "mode" "XF")])
16654 [(set (match_operand:XF 0 "register_operand" "")
16655 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16656 UNSPEC_SINCOS_COS))
16657 (set (match_operand:XF 1 "register_operand" "")
16658 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16659 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16660 && !(reload_completed || reload_in_progress)"
16661 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16665 [(set (match_operand:XF 0 "register_operand" "")
16666 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16667 UNSPEC_SINCOS_COS))
16668 (set (match_operand:XF 1 "register_operand" "")
16669 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16670 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16671 && !(reload_completed || reload_in_progress)"
16672 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16675 (define_insn "sincos_extend<mode>xf3_i387"
16676 [(set (match_operand:XF 0 "register_operand" "=f")
16677 (unspec:XF [(float_extend:XF
16678 (match_operand:MODEF 2 "register_operand" "0"))]
16679 UNSPEC_SINCOS_COS))
16680 (set (match_operand:XF 1 "register_operand" "=u")
16681 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16684 || TARGET_MIX_SSE_I387)
16685 && flag_unsafe_math_optimizations"
16687 [(set_attr "type" "fpspc")
16688 (set_attr "mode" "XF")])
16691 [(set (match_operand:XF 0 "register_operand" "")
16692 (unspec:XF [(float_extend:XF
16693 (match_operand:MODEF 2 "register_operand" ""))]
16694 UNSPEC_SINCOS_COS))
16695 (set (match_operand:XF 1 "register_operand" "")
16696 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16697 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16698 && !(reload_completed || reload_in_progress)"
16699 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16703 [(set (match_operand:XF 0 "register_operand" "")
16704 (unspec:XF [(float_extend:XF
16705 (match_operand:MODEF 2 "register_operand" ""))]
16706 UNSPEC_SINCOS_COS))
16707 (set (match_operand:XF 1 "register_operand" "")
16708 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16709 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16710 && !(reload_completed || reload_in_progress)"
16711 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16714 (define_expand "sincos<mode>3"
16715 [(use (match_operand:MODEF 0 "register_operand" ""))
16716 (use (match_operand:MODEF 1 "register_operand" ""))
16717 (use (match_operand:MODEF 2 "register_operand" ""))]
16718 "TARGET_USE_FANCY_MATH_387
16719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16720 || TARGET_MIX_SSE_I387)
16721 && flag_unsafe_math_optimizations"
16723 rtx op0 = gen_reg_rtx (XFmode);
16724 rtx op1 = gen_reg_rtx (XFmode);
16726 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16732 (define_insn "fptanxf4_i387"
16733 [(set (match_operand:XF 0 "register_operand" "=f")
16734 (match_operand:XF 3 "const_double_operand" "F"))
16735 (set (match_operand:XF 1 "register_operand" "=u")
16736 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16738 "TARGET_USE_FANCY_MATH_387
16739 && flag_unsafe_math_optimizations
16740 && standard_80387_constant_p (operands[3]) == 2"
16742 [(set_attr "type" "fpspc")
16743 (set_attr "mode" "XF")])
16745 (define_insn "fptan_extend<mode>xf4_i387"
16746 [(set (match_operand:MODEF 0 "register_operand" "=f")
16747 (match_operand:MODEF 3 "const_double_operand" "F"))
16748 (set (match_operand:XF 1 "register_operand" "=u")
16749 (unspec:XF [(float_extend:XF
16750 (match_operand:MODEF 2 "register_operand" "0"))]
16752 "TARGET_USE_FANCY_MATH_387
16753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16754 || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations
16756 && standard_80387_constant_p (operands[3]) == 2"
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "XF")])
16761 (define_expand "tanxf2"
16762 [(use (match_operand:XF 0 "register_operand" ""))
16763 (use (match_operand:XF 1 "register_operand" ""))]
16764 "TARGET_USE_FANCY_MATH_387
16765 && flag_unsafe_math_optimizations"
16767 rtx one = gen_reg_rtx (XFmode);
16768 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16770 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16774 (define_expand "tan<mode>2"
16775 [(use (match_operand:MODEF 0 "register_operand" ""))
16776 (use (match_operand:MODEF 1 "register_operand" ""))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779 || TARGET_MIX_SSE_I387)
16780 && flag_unsafe_math_optimizations"
16782 rtx op0 = gen_reg_rtx (XFmode);
16784 rtx one = gen_reg_rtx (<MODE>mode);
16785 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16787 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16788 operands[1], op2));
16789 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16793 (define_insn "*fpatanxf3_i387"
16794 [(set (match_operand:XF 0 "register_operand" "=f")
16795 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16796 (match_operand:XF 2 "register_operand" "u")]
16798 (clobber (match_scratch:XF 3 "=2"))]
16799 "TARGET_USE_FANCY_MATH_387
16800 && flag_unsafe_math_optimizations"
16802 [(set_attr "type" "fpspc")
16803 (set_attr "mode" "XF")])
16805 (define_insn "fpatan_extend<mode>xf3_i387"
16806 [(set (match_operand:XF 0 "register_operand" "=f")
16807 (unspec:XF [(float_extend:XF
16808 (match_operand:MODEF 1 "register_operand" "0"))
16810 (match_operand:MODEF 2 "register_operand" "u"))]
16812 (clobber (match_scratch:XF 3 "=2"))]
16813 "TARGET_USE_FANCY_MATH_387
16814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16815 || TARGET_MIX_SSE_I387)
16816 && flag_unsafe_math_optimizations"
16818 [(set_attr "type" "fpspc")
16819 (set_attr "mode" "XF")])
16821 (define_expand "atan2xf3"
16822 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16823 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16824 (match_operand:XF 1 "register_operand" "")]
16826 (clobber (match_scratch:XF 3 ""))])]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations"
16831 (define_expand "atan2<mode>3"
16832 [(use (match_operand:MODEF 0 "register_operand" ""))
16833 (use (match_operand:MODEF 1 "register_operand" ""))
16834 (use (match_operand:MODEF 2 "register_operand" ""))]
16835 "TARGET_USE_FANCY_MATH_387
16836 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16837 || TARGET_MIX_SSE_I387)
16838 && flag_unsafe_math_optimizations"
16840 rtx op0 = gen_reg_rtx (XFmode);
16842 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16843 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16847 (define_expand "atanxf2"
16848 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16849 (unspec:XF [(match_dup 2)
16850 (match_operand:XF 1 "register_operand" "")]
16852 (clobber (match_scratch:XF 3 ""))])]
16853 "TARGET_USE_FANCY_MATH_387
16854 && flag_unsafe_math_optimizations"
16856 operands[2] = gen_reg_rtx (XFmode);
16857 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16860 (define_expand "atan<mode>2"
16861 [(use (match_operand:MODEF 0 "register_operand" ""))
16862 (use (match_operand:MODEF 1 "register_operand" ""))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865 || TARGET_MIX_SSE_I387)
16866 && flag_unsafe_math_optimizations"
16868 rtx op0 = gen_reg_rtx (XFmode);
16870 rtx op2 = gen_reg_rtx (<MODE>mode);
16871 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16873 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16878 (define_expand "asinxf2"
16879 [(set (match_dup 2)
16880 (mult:XF (match_operand:XF 1 "register_operand" "")
16882 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16883 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16884 (parallel [(set (match_operand:XF 0 "register_operand" "")
16885 (unspec:XF [(match_dup 5) (match_dup 1)]
16887 (clobber (match_scratch:XF 6 ""))])]
16888 "TARGET_USE_FANCY_MATH_387
16889 && flag_unsafe_math_optimizations"
16893 if (optimize_insn_for_size_p ())
16896 for (i = 2; i < 6; i++)
16897 operands[i] = gen_reg_rtx (XFmode);
16899 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16902 (define_expand "asin<mode>2"
16903 [(use (match_operand:MODEF 0 "register_operand" ""))
16904 (use (match_operand:MODEF 1 "general_operand" ""))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16907 || TARGET_MIX_SSE_I387)
16908 && flag_unsafe_math_optimizations"
16910 rtx op0 = gen_reg_rtx (XFmode);
16911 rtx op1 = gen_reg_rtx (XFmode);
16913 if (optimize_insn_for_size_p ())
16916 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16917 emit_insn (gen_asinxf2 (op0, op1));
16918 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16922 (define_expand "acosxf2"
16923 [(set (match_dup 2)
16924 (mult:XF (match_operand:XF 1 "register_operand" "")
16926 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16927 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16928 (parallel [(set (match_operand:XF 0 "register_operand" "")
16929 (unspec:XF [(match_dup 1) (match_dup 5)]
16931 (clobber (match_scratch:XF 6 ""))])]
16932 "TARGET_USE_FANCY_MATH_387
16933 && flag_unsafe_math_optimizations"
16937 if (optimize_insn_for_size_p ())
16940 for (i = 2; i < 6; i++)
16941 operands[i] = gen_reg_rtx (XFmode);
16943 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16946 (define_expand "acos<mode>2"
16947 [(use (match_operand:MODEF 0 "register_operand" ""))
16948 (use (match_operand:MODEF 1 "general_operand" ""))]
16949 "TARGET_USE_FANCY_MATH_387
16950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16951 || TARGET_MIX_SSE_I387)
16952 && flag_unsafe_math_optimizations"
16954 rtx op0 = gen_reg_rtx (XFmode);
16955 rtx op1 = gen_reg_rtx (XFmode);
16957 if (optimize_insn_for_size_p ())
16960 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16961 emit_insn (gen_acosxf2 (op0, op1));
16962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16966 (define_insn "fyl2xxf3_i387"
16967 [(set (match_operand:XF 0 "register_operand" "=f")
16968 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16969 (match_operand:XF 2 "register_operand" "u")]
16971 (clobber (match_scratch:XF 3 "=2"))]
16972 "TARGET_USE_FANCY_MATH_387
16973 && flag_unsafe_math_optimizations"
16975 [(set_attr "type" "fpspc")
16976 (set_attr "mode" "XF")])
16978 (define_insn "fyl2x_extend<mode>xf3_i387"
16979 [(set (match_operand:XF 0 "register_operand" "=f")
16980 (unspec:XF [(float_extend:XF
16981 (match_operand:MODEF 1 "register_operand" "0"))
16982 (match_operand:XF 2 "register_operand" "u")]
16984 (clobber (match_scratch:XF 3 "=2"))]
16985 "TARGET_USE_FANCY_MATH_387
16986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16987 || TARGET_MIX_SSE_I387)
16988 && flag_unsafe_math_optimizations"
16990 [(set_attr "type" "fpspc")
16991 (set_attr "mode" "XF")])
16993 (define_expand "logxf2"
16994 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16995 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16996 (match_dup 2)] UNSPEC_FYL2X))
16997 (clobber (match_scratch:XF 3 ""))])]
16998 "TARGET_USE_FANCY_MATH_387
16999 && flag_unsafe_math_optimizations"
17001 operands[2] = gen_reg_rtx (XFmode);
17002 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17005 (define_expand "log<mode>2"
17006 [(use (match_operand:MODEF 0 "register_operand" ""))
17007 (use (match_operand:MODEF 1 "register_operand" ""))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010 || TARGET_MIX_SSE_I387)
17011 && flag_unsafe_math_optimizations"
17013 rtx op0 = gen_reg_rtx (XFmode);
17015 rtx op2 = gen_reg_rtx (XFmode);
17016 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17018 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17019 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17023 (define_expand "log10xf2"
17024 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17025 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17026 (match_dup 2)] UNSPEC_FYL2X))
17027 (clobber (match_scratch:XF 3 ""))])]
17028 "TARGET_USE_FANCY_MATH_387
17029 && flag_unsafe_math_optimizations"
17031 operands[2] = gen_reg_rtx (XFmode);
17032 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17035 (define_expand "log10<mode>2"
17036 [(use (match_operand:MODEF 0 "register_operand" ""))
17037 (use (match_operand:MODEF 1 "register_operand" ""))]
17038 "TARGET_USE_FANCY_MATH_387
17039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17040 || TARGET_MIX_SSE_I387)
17041 && flag_unsafe_math_optimizations"
17043 rtx op0 = gen_reg_rtx (XFmode);
17045 rtx op2 = gen_reg_rtx (XFmode);
17046 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17048 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17053 (define_expand "log2xf2"
17054 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17055 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17056 (match_dup 2)] UNSPEC_FYL2X))
17057 (clobber (match_scratch:XF 3 ""))])]
17058 "TARGET_USE_FANCY_MATH_387
17059 && flag_unsafe_math_optimizations"
17061 operands[2] = gen_reg_rtx (XFmode);
17062 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17065 (define_expand "log2<mode>2"
17066 [(use (match_operand:MODEF 0 "register_operand" ""))
17067 (use (match_operand:MODEF 1 "register_operand" ""))]
17068 "TARGET_USE_FANCY_MATH_387
17069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17070 || TARGET_MIX_SSE_I387)
17071 && flag_unsafe_math_optimizations"
17073 rtx op0 = gen_reg_rtx (XFmode);
17075 rtx op2 = gen_reg_rtx (XFmode);
17076 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17078 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17083 (define_insn "fyl2xp1xf3_i387"
17084 [(set (match_operand:XF 0 "register_operand" "=f")
17085 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17086 (match_operand:XF 2 "register_operand" "u")]
17088 (clobber (match_scratch:XF 3 "=2"))]
17089 "TARGET_USE_FANCY_MATH_387
17090 && flag_unsafe_math_optimizations"
17092 [(set_attr "type" "fpspc")
17093 (set_attr "mode" "XF")])
17095 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17096 [(set (match_operand:XF 0 "register_operand" "=f")
17097 (unspec:XF [(float_extend:XF
17098 (match_operand:MODEF 1 "register_operand" "0"))
17099 (match_operand:XF 2 "register_operand" "u")]
17101 (clobber (match_scratch:XF 3 "=2"))]
17102 "TARGET_USE_FANCY_MATH_387
17103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17104 || TARGET_MIX_SSE_I387)
17105 && flag_unsafe_math_optimizations"
17107 [(set_attr "type" "fpspc")
17108 (set_attr "mode" "XF")])
17110 (define_expand "log1pxf2"
17111 [(use (match_operand:XF 0 "register_operand" ""))
17112 (use (match_operand:XF 1 "register_operand" ""))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && flag_unsafe_math_optimizations"
17116 if (optimize_insn_for_size_p ())
17119 ix86_emit_i387_log1p (operands[0], operands[1]);
17123 (define_expand "log1p<mode>2"
17124 [(use (match_operand:MODEF 0 "register_operand" ""))
17125 (use (match_operand:MODEF 1 "register_operand" ""))]
17126 "TARGET_USE_FANCY_MATH_387
17127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17128 || TARGET_MIX_SSE_I387)
17129 && flag_unsafe_math_optimizations"
17133 if (optimize_insn_for_size_p ())
17136 op0 = gen_reg_rtx (XFmode);
17138 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17140 ix86_emit_i387_log1p (op0, operands[1]);
17141 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17145 (define_insn "fxtractxf3_i387"
17146 [(set (match_operand:XF 0 "register_operand" "=f")
17147 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17148 UNSPEC_XTRACT_FRACT))
17149 (set (match_operand:XF 1 "register_operand" "=u")
17150 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && flag_unsafe_math_optimizations"
17154 [(set_attr "type" "fpspc")
17155 (set_attr "mode" "XF")])
17157 (define_insn "fxtract_extend<mode>xf3_i387"
17158 [(set (match_operand:XF 0 "register_operand" "=f")
17159 (unspec:XF [(float_extend:XF
17160 (match_operand:MODEF 2 "register_operand" "0"))]
17161 UNSPEC_XTRACT_FRACT))
17162 (set (match_operand:XF 1 "register_operand" "=u")
17163 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17164 "TARGET_USE_FANCY_MATH_387
17165 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17166 || TARGET_MIX_SSE_I387)
17167 && flag_unsafe_math_optimizations"
17169 [(set_attr "type" "fpspc")
17170 (set_attr "mode" "XF")])
17172 (define_expand "logbxf2"
17173 [(parallel [(set (match_dup 2)
17174 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17175 UNSPEC_XTRACT_FRACT))
17176 (set (match_operand:XF 0 "register_operand" "")
17177 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17178 "TARGET_USE_FANCY_MATH_387
17179 && flag_unsafe_math_optimizations"
17181 operands[2] = gen_reg_rtx (XFmode);
17184 (define_expand "logb<mode>2"
17185 [(use (match_operand:MODEF 0 "register_operand" ""))
17186 (use (match_operand:MODEF 1 "register_operand" ""))]
17187 "TARGET_USE_FANCY_MATH_387
17188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17189 || TARGET_MIX_SSE_I387)
17190 && flag_unsafe_math_optimizations"
17192 rtx op0 = gen_reg_rtx (XFmode);
17193 rtx op1 = gen_reg_rtx (XFmode);
17195 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17200 (define_expand "ilogbxf2"
17201 [(use (match_operand:SI 0 "register_operand" ""))
17202 (use (match_operand:XF 1 "register_operand" ""))]
17203 "TARGET_USE_FANCY_MATH_387
17204 && flag_unsafe_math_optimizations"
17208 if (optimize_insn_for_size_p ())
17211 op0 = gen_reg_rtx (XFmode);
17212 op1 = gen_reg_rtx (XFmode);
17214 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17215 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17219 (define_expand "ilogb<mode>2"
17220 [(use (match_operand:SI 0 "register_operand" ""))
17221 (use (match_operand:MODEF 1 "register_operand" ""))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224 || TARGET_MIX_SSE_I387)
17225 && flag_unsafe_math_optimizations"
17229 if (optimize_insn_for_size_p ())
17232 op0 = gen_reg_rtx (XFmode);
17233 op1 = gen_reg_rtx (XFmode);
17235 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17236 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17240 (define_insn "*f2xm1xf2_i387"
17241 [(set (match_operand:XF 0 "register_operand" "=f")
17242 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17244 "TARGET_USE_FANCY_MATH_387
17245 && flag_unsafe_math_optimizations"
17247 [(set_attr "type" "fpspc")
17248 (set_attr "mode" "XF")])
17250 (define_insn "*fscalexf4_i387"
17251 [(set (match_operand:XF 0 "register_operand" "=f")
17252 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17253 (match_operand:XF 3 "register_operand" "1")]
17254 UNSPEC_FSCALE_FRACT))
17255 (set (match_operand:XF 1 "register_operand" "=u")
17256 (unspec:XF [(match_dup 2) (match_dup 3)]
17257 UNSPEC_FSCALE_EXP))]
17258 "TARGET_USE_FANCY_MATH_387
17259 && flag_unsafe_math_optimizations"
17261 [(set_attr "type" "fpspc")
17262 (set_attr "mode" "XF")])
17264 (define_expand "expNcorexf3"
17265 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17266 (match_operand:XF 2 "register_operand" "")))
17267 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17268 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17269 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17270 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17271 (parallel [(set (match_operand:XF 0 "register_operand" "")
17272 (unspec:XF [(match_dup 8) (match_dup 4)]
17273 UNSPEC_FSCALE_FRACT))
17275 (unspec:XF [(match_dup 8) (match_dup 4)]
17276 UNSPEC_FSCALE_EXP))])]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations"
17282 if (optimize_insn_for_size_p ())
17285 for (i = 3; i < 10; i++)
17286 operands[i] = gen_reg_rtx (XFmode);
17288 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17291 (define_expand "expxf2"
17292 [(use (match_operand:XF 0 "register_operand" ""))
17293 (use (match_operand:XF 1 "register_operand" ""))]
17294 "TARGET_USE_FANCY_MATH_387
17295 && flag_unsafe_math_optimizations"
17299 if (optimize_insn_for_size_p ())
17302 op2 = gen_reg_rtx (XFmode);
17303 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17305 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17309 (define_expand "exp<mode>2"
17310 [(use (match_operand:MODEF 0 "register_operand" ""))
17311 (use (match_operand:MODEF 1 "general_operand" ""))]
17312 "TARGET_USE_FANCY_MATH_387
17313 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17314 || TARGET_MIX_SSE_I387)
17315 && flag_unsafe_math_optimizations"
17319 if (optimize_insn_for_size_p ())
17322 op0 = gen_reg_rtx (XFmode);
17323 op1 = gen_reg_rtx (XFmode);
17325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17326 emit_insn (gen_expxf2 (op0, op1));
17327 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17331 (define_expand "exp10xf2"
17332 [(use (match_operand:XF 0 "register_operand" ""))
17333 (use (match_operand:XF 1 "register_operand" ""))]
17334 "TARGET_USE_FANCY_MATH_387
17335 && flag_unsafe_math_optimizations"
17339 if (optimize_insn_for_size_p ())
17342 op2 = gen_reg_rtx (XFmode);
17343 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17345 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17349 (define_expand "exp10<mode>2"
17350 [(use (match_operand:MODEF 0 "register_operand" ""))
17351 (use (match_operand:MODEF 1 "general_operand" ""))]
17352 "TARGET_USE_FANCY_MATH_387
17353 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17354 || TARGET_MIX_SSE_I387)
17355 && flag_unsafe_math_optimizations"
17359 if (optimize_insn_for_size_p ())
17362 op0 = gen_reg_rtx (XFmode);
17363 op1 = gen_reg_rtx (XFmode);
17365 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17366 emit_insn (gen_exp10xf2 (op0, op1));
17367 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17371 (define_expand "exp2xf2"
17372 [(use (match_operand:XF 0 "register_operand" ""))
17373 (use (match_operand:XF 1 "register_operand" ""))]
17374 "TARGET_USE_FANCY_MATH_387
17375 && flag_unsafe_math_optimizations"
17379 if (optimize_insn_for_size_p ())
17382 op2 = gen_reg_rtx (XFmode);
17383 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17385 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17389 (define_expand "exp2<mode>2"
17390 [(use (match_operand:MODEF 0 "register_operand" ""))
17391 (use (match_operand:MODEF 1 "general_operand" ""))]
17392 "TARGET_USE_FANCY_MATH_387
17393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17394 || TARGET_MIX_SSE_I387)
17395 && flag_unsafe_math_optimizations"
17399 if (optimize_insn_for_size_p ())
17402 op0 = gen_reg_rtx (XFmode);
17403 op1 = gen_reg_rtx (XFmode);
17405 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17406 emit_insn (gen_exp2xf2 (op0, op1));
17407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17411 (define_expand "expm1xf2"
17412 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17414 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17415 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17416 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17417 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17418 (parallel [(set (match_dup 7)
17419 (unspec:XF [(match_dup 6) (match_dup 4)]
17420 UNSPEC_FSCALE_FRACT))
17422 (unspec:XF [(match_dup 6) (match_dup 4)]
17423 UNSPEC_FSCALE_EXP))])
17424 (parallel [(set (match_dup 10)
17425 (unspec:XF [(match_dup 9) (match_dup 8)]
17426 UNSPEC_FSCALE_FRACT))
17427 (set (match_dup 11)
17428 (unspec:XF [(match_dup 9) (match_dup 8)]
17429 UNSPEC_FSCALE_EXP))])
17430 (set (match_dup 12) (minus:XF (match_dup 10)
17431 (float_extend:XF (match_dup 13))))
17432 (set (match_operand:XF 0 "register_operand" "")
17433 (plus:XF (match_dup 12) (match_dup 7)))]
17434 "TARGET_USE_FANCY_MATH_387
17435 && flag_unsafe_math_optimizations"
17439 if (optimize_insn_for_size_p ())
17442 for (i = 2; i < 13; i++)
17443 operands[i] = gen_reg_rtx (XFmode);
17446 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17448 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17451 (define_expand "expm1<mode>2"
17452 [(use (match_operand:MODEF 0 "register_operand" ""))
17453 (use (match_operand:MODEF 1 "general_operand" ""))]
17454 "TARGET_USE_FANCY_MATH_387
17455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17456 || TARGET_MIX_SSE_I387)
17457 && flag_unsafe_math_optimizations"
17461 if (optimize_insn_for_size_p ())
17464 op0 = gen_reg_rtx (XFmode);
17465 op1 = gen_reg_rtx (XFmode);
17467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17468 emit_insn (gen_expm1xf2 (op0, op1));
17469 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17473 (define_expand "ldexpxf3"
17474 [(set (match_dup 3)
17475 (float:XF (match_operand:SI 2 "register_operand" "")))
17476 (parallel [(set (match_operand:XF 0 " register_operand" "")
17477 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17479 UNSPEC_FSCALE_FRACT))
17481 (unspec:XF [(match_dup 1) (match_dup 3)]
17482 UNSPEC_FSCALE_EXP))])]
17483 "TARGET_USE_FANCY_MATH_387
17484 && flag_unsafe_math_optimizations"
17486 if (optimize_insn_for_size_p ())
17489 operands[3] = gen_reg_rtx (XFmode);
17490 operands[4] = gen_reg_rtx (XFmode);
17493 (define_expand "ldexp<mode>3"
17494 [(use (match_operand:MODEF 0 "register_operand" ""))
17495 (use (match_operand:MODEF 1 "general_operand" ""))
17496 (use (match_operand:SI 2 "register_operand" ""))]
17497 "TARGET_USE_FANCY_MATH_387
17498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17499 || TARGET_MIX_SSE_I387)
17500 && flag_unsafe_math_optimizations"
17504 if (optimize_insn_for_size_p ())
17507 op0 = gen_reg_rtx (XFmode);
17508 op1 = gen_reg_rtx (XFmode);
17510 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17511 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17512 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17516 (define_expand "scalbxf3"
17517 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17518 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17519 (match_operand:XF 2 "register_operand" "")]
17520 UNSPEC_FSCALE_FRACT))
17522 (unspec:XF [(match_dup 1) (match_dup 2)]
17523 UNSPEC_FSCALE_EXP))])]
17524 "TARGET_USE_FANCY_MATH_387
17525 && flag_unsafe_math_optimizations"
17527 if (optimize_insn_for_size_p ())
17530 operands[3] = gen_reg_rtx (XFmode);
17533 (define_expand "scalb<mode>3"
17534 [(use (match_operand:MODEF 0 "register_operand" ""))
17535 (use (match_operand:MODEF 1 "general_operand" ""))
17536 (use (match_operand:MODEF 2 "general_operand" ""))]
17537 "TARGET_USE_FANCY_MATH_387
17538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17539 || TARGET_MIX_SSE_I387)
17540 && flag_unsafe_math_optimizations"
17544 if (optimize_insn_for_size_p ())
17547 op0 = gen_reg_rtx (XFmode);
17548 op1 = gen_reg_rtx (XFmode);
17549 op2 = gen_reg_rtx (XFmode);
17551 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17552 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17553 emit_insn (gen_scalbxf3 (op0, op1, op2));
17554 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17558 (define_expand "significandxf2"
17559 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17560 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17561 UNSPEC_XTRACT_FRACT))
17563 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17564 "TARGET_USE_FANCY_MATH_387
17565 && flag_unsafe_math_optimizations"
17567 operands[2] = gen_reg_rtx (XFmode);
17570 (define_expand "significand<mode>2"
17571 [(use (match_operand:MODEF 0 "register_operand" ""))
17572 (use (match_operand:MODEF 1 "register_operand" ""))]
17573 "TARGET_USE_FANCY_MATH_387
17574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17575 || TARGET_MIX_SSE_I387)
17576 && flag_unsafe_math_optimizations"
17578 rtx op0 = gen_reg_rtx (XFmode);
17579 rtx op1 = gen_reg_rtx (XFmode);
17581 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17582 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17587 (define_insn "sse4_1_round<mode>2"
17588 [(set (match_operand:MODEF 0 "register_operand" "=x")
17589 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17590 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17593 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17594 [(set_attr "type" "ssecvt")
17595 (set_attr "prefix_extra" "1")
17596 (set_attr "prefix" "maybe_vex")
17597 (set_attr "mode" "<MODE>")])
17599 (define_insn "rintxf2"
17600 [(set (match_operand:XF 0 "register_operand" "=f")
17601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17603 "TARGET_USE_FANCY_MATH_387
17604 && flag_unsafe_math_optimizations"
17606 [(set_attr "type" "fpspc")
17607 (set_attr "mode" "XF")])
17609 (define_expand "rint<mode>2"
17610 [(use (match_operand:MODEF 0 "register_operand" ""))
17611 (use (match_operand:MODEF 1 "register_operand" ""))]
17612 "(TARGET_USE_FANCY_MATH_387
17613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614 || TARGET_MIX_SSE_I387)
17615 && flag_unsafe_math_optimizations)
17616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17617 && !flag_trapping_math)"
17619 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17620 && !flag_trapping_math)
17622 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17625 emit_insn (gen_sse4_1_round<mode>2
17626 (operands[0], operands[1], GEN_INT (0x04)));
17628 ix86_expand_rint (operand0, operand1);
17632 rtx op0 = gen_reg_rtx (XFmode);
17633 rtx op1 = gen_reg_rtx (XFmode);
17635 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17636 emit_insn (gen_rintxf2 (op0, op1));
17638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17643 (define_expand "round<mode>2"
17644 [(match_operand:MODEF 0 "register_operand" "")
17645 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17646 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17647 && !flag_trapping_math && !flag_rounding_math"
17649 if (optimize_insn_for_size_p ())
17651 if (TARGET_64BIT || (<MODE>mode != DFmode))
17652 ix86_expand_round (operand0, operand1);
17654 ix86_expand_rounddf_32 (operand0, operand1);
17658 (define_insn_and_split "*fistdi2_1"
17659 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17660 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17662 "TARGET_USE_FANCY_MATH_387
17663 && can_create_pseudo_p ()"
17668 if (memory_operand (operands[0], VOIDmode))
17669 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17672 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17673 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17678 [(set_attr "type" "fpspc")
17679 (set_attr "mode" "DI")])
17681 (define_insn "fistdi2"
17682 [(set (match_operand:DI 0 "memory_operand" "=m")
17683 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17685 (clobber (match_scratch:XF 2 "=&1f"))]
17686 "TARGET_USE_FANCY_MATH_387"
17687 "* return output_fix_trunc (insn, operands, 0);"
17688 [(set_attr "type" "fpspc")
17689 (set_attr "mode" "DI")])
17691 (define_insn "fistdi2_with_temp"
17692 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17693 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17695 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17696 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17697 "TARGET_USE_FANCY_MATH_387"
17699 [(set_attr "type" "fpspc")
17700 (set_attr "mode" "DI")])
17703 [(set (match_operand:DI 0 "register_operand" "")
17704 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17706 (clobber (match_operand:DI 2 "memory_operand" ""))
17707 (clobber (match_scratch 3 ""))]
17709 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17710 (clobber (match_dup 3))])
17711 (set (match_dup 0) (match_dup 2))]
17715 [(set (match_operand:DI 0 "memory_operand" "")
17716 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17718 (clobber (match_operand:DI 2 "memory_operand" ""))
17719 (clobber (match_scratch 3 ""))]
17721 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17722 (clobber (match_dup 3))])]
17725 (define_insn_and_split "*fist<mode>2_1"
17726 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17729 "TARGET_USE_FANCY_MATH_387
17730 && can_create_pseudo_p ()"
17735 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17736 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17740 [(set_attr "type" "fpspc")
17741 (set_attr "mode" "<MODE>")])
17743 (define_insn "fist<mode>2"
17744 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17745 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17747 "TARGET_USE_FANCY_MATH_387"
17748 "* return output_fix_trunc (insn, operands, 0);"
17749 [(set_attr "type" "fpspc")
17750 (set_attr "mode" "<MODE>")])
17752 (define_insn "fist<mode>2_with_temp"
17753 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17754 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17756 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17757 "TARGET_USE_FANCY_MATH_387"
17759 [(set_attr "type" "fpspc")
17760 (set_attr "mode" "<MODE>")])
17763 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17764 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17766 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17768 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17769 (set (match_dup 0) (match_dup 2))]
17773 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17776 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17778 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17781 (define_expand "lrintxf<mode>2"
17782 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17783 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17785 "TARGET_USE_FANCY_MATH_387"
17788 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17789 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17790 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17791 UNSPEC_FIX_NOTRUNC))]
17792 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17793 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17796 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17797 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17798 (match_operand:MODEF 1 "register_operand" "")]
17799 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17800 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17801 && !flag_trapping_math && !flag_rounding_math"
17803 if (optimize_insn_for_size_p ())
17805 ix86_expand_lround (operand0, operand1);
17809 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17810 (define_insn_and_split "frndintxf2_floor"
17811 [(set (match_operand:XF 0 "register_operand" "")
17812 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17813 UNSPEC_FRNDINT_FLOOR))
17814 (clobber (reg:CC FLAGS_REG))]
17815 "TARGET_USE_FANCY_MATH_387
17816 && flag_unsafe_math_optimizations
17817 && can_create_pseudo_p ()"
17822 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17824 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17825 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17827 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17828 operands[2], operands[3]));
17831 [(set_attr "type" "frndint")
17832 (set_attr "i387_cw" "floor")
17833 (set_attr "mode" "XF")])
17835 (define_insn "frndintxf2_floor_i387"
17836 [(set (match_operand:XF 0 "register_operand" "=f")
17837 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17838 UNSPEC_FRNDINT_FLOOR))
17839 (use (match_operand:HI 2 "memory_operand" "m"))
17840 (use (match_operand:HI 3 "memory_operand" "m"))]
17841 "TARGET_USE_FANCY_MATH_387
17842 && flag_unsafe_math_optimizations"
17843 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17844 [(set_attr "type" "frndint")
17845 (set_attr "i387_cw" "floor")
17846 (set_attr "mode" "XF")])
17848 (define_expand "floorxf2"
17849 [(use (match_operand:XF 0 "register_operand" ""))
17850 (use (match_operand:XF 1 "register_operand" ""))]
17851 "TARGET_USE_FANCY_MATH_387
17852 && flag_unsafe_math_optimizations"
17854 if (optimize_insn_for_size_p ())
17856 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17860 (define_expand "floor<mode>2"
17861 [(use (match_operand:MODEF 0 "register_operand" ""))
17862 (use (match_operand:MODEF 1 "register_operand" ""))]
17863 "(TARGET_USE_FANCY_MATH_387
17864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17865 || TARGET_MIX_SSE_I387)
17866 && flag_unsafe_math_optimizations)
17867 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17868 && !flag_trapping_math)"
17870 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17871 && !flag_trapping_math
17872 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17874 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17877 emit_insn (gen_sse4_1_round<mode>2
17878 (operands[0], operands[1], GEN_INT (0x01)));
17879 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17880 ix86_expand_floorceil (operand0, operand1, true);
17882 ix86_expand_floorceildf_32 (operand0, operand1, true);
17888 if (optimize_insn_for_size_p ())
17891 op0 = gen_reg_rtx (XFmode);
17892 op1 = gen_reg_rtx (XFmode);
17893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17894 emit_insn (gen_frndintxf2_floor (op0, op1));
17896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17901 (define_insn_and_split "*fist<mode>2_floor_1"
17902 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17903 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17904 UNSPEC_FIST_FLOOR))
17905 (clobber (reg:CC FLAGS_REG))]
17906 "TARGET_USE_FANCY_MATH_387
17907 && flag_unsafe_math_optimizations
17908 && can_create_pseudo_p ()"
17913 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17915 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17916 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17917 if (memory_operand (operands[0], VOIDmode))
17918 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17919 operands[2], operands[3]));
17922 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17923 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17924 operands[2], operands[3],
17929 [(set_attr "type" "fistp")
17930 (set_attr "i387_cw" "floor")
17931 (set_attr "mode" "<MODE>")])
17933 (define_insn "fistdi2_floor"
17934 [(set (match_operand:DI 0 "memory_operand" "=m")
17935 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17936 UNSPEC_FIST_FLOOR))
17937 (use (match_operand:HI 2 "memory_operand" "m"))
17938 (use (match_operand:HI 3 "memory_operand" "m"))
17939 (clobber (match_scratch:XF 4 "=&1f"))]
17940 "TARGET_USE_FANCY_MATH_387
17941 && flag_unsafe_math_optimizations"
17942 "* return output_fix_trunc (insn, operands, 0);"
17943 [(set_attr "type" "fistp")
17944 (set_attr "i387_cw" "floor")
17945 (set_attr "mode" "DI")])
17947 (define_insn "fistdi2_floor_with_temp"
17948 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17949 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17950 UNSPEC_FIST_FLOOR))
17951 (use (match_operand:HI 2 "memory_operand" "m,m"))
17952 (use (match_operand:HI 3 "memory_operand" "m,m"))
17953 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17954 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17955 "TARGET_USE_FANCY_MATH_387
17956 && flag_unsafe_math_optimizations"
17958 [(set_attr "type" "fistp")
17959 (set_attr "i387_cw" "floor")
17960 (set_attr "mode" "DI")])
17963 [(set (match_operand:DI 0 "register_operand" "")
17964 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17965 UNSPEC_FIST_FLOOR))
17966 (use (match_operand:HI 2 "memory_operand" ""))
17967 (use (match_operand:HI 3 "memory_operand" ""))
17968 (clobber (match_operand:DI 4 "memory_operand" ""))
17969 (clobber (match_scratch 5 ""))]
17971 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17972 (use (match_dup 2))
17973 (use (match_dup 3))
17974 (clobber (match_dup 5))])
17975 (set (match_dup 0) (match_dup 4))]
17979 [(set (match_operand:DI 0 "memory_operand" "")
17980 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17981 UNSPEC_FIST_FLOOR))
17982 (use (match_operand:HI 2 "memory_operand" ""))
17983 (use (match_operand:HI 3 "memory_operand" ""))
17984 (clobber (match_operand:DI 4 "memory_operand" ""))
17985 (clobber (match_scratch 5 ""))]
17987 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17988 (use (match_dup 2))
17989 (use (match_dup 3))
17990 (clobber (match_dup 5))])]
17993 (define_insn "fist<mode>2_floor"
17994 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17995 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17996 UNSPEC_FIST_FLOOR))
17997 (use (match_operand:HI 2 "memory_operand" "m"))
17998 (use (match_operand:HI 3 "memory_operand" "m"))]
17999 "TARGET_USE_FANCY_MATH_387
18000 && flag_unsafe_math_optimizations"
18001 "* return output_fix_trunc (insn, operands, 0);"
18002 [(set_attr "type" "fistp")
18003 (set_attr "i387_cw" "floor")
18004 (set_attr "mode" "<MODE>")])
18006 (define_insn "fist<mode>2_floor_with_temp"
18007 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18008 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18009 UNSPEC_FIST_FLOOR))
18010 (use (match_operand:HI 2 "memory_operand" "m,m"))
18011 (use (match_operand:HI 3 "memory_operand" "m,m"))
18012 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18013 "TARGET_USE_FANCY_MATH_387
18014 && flag_unsafe_math_optimizations"
18016 [(set_attr "type" "fistp")
18017 (set_attr "i387_cw" "floor")
18018 (set_attr "mode" "<MODE>")])
18021 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18022 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18023 UNSPEC_FIST_FLOOR))
18024 (use (match_operand:HI 2 "memory_operand" ""))
18025 (use (match_operand:HI 3 "memory_operand" ""))
18026 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18028 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18029 UNSPEC_FIST_FLOOR))
18030 (use (match_dup 2))
18031 (use (match_dup 3))])
18032 (set (match_dup 0) (match_dup 4))]
18036 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18037 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18038 UNSPEC_FIST_FLOOR))
18039 (use (match_operand:HI 2 "memory_operand" ""))
18040 (use (match_operand:HI 3 "memory_operand" ""))
18041 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18043 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18044 UNSPEC_FIST_FLOOR))
18045 (use (match_dup 2))
18046 (use (match_dup 3))])]
18049 (define_expand "lfloorxf<mode>2"
18050 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18051 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18052 UNSPEC_FIST_FLOOR))
18053 (clobber (reg:CC FLAGS_REG))])]
18054 "TARGET_USE_FANCY_MATH_387
18055 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18056 && flag_unsafe_math_optimizations"
18059 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
18060 [(match_operand:SWI48 0 "nonimmediate_operand" "")
18061 (match_operand:MODEF 1 "register_operand" "")]
18062 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18063 && !flag_trapping_math"
18065 if (TARGET_64BIT && optimize_insn_for_size_p ())
18067 ix86_expand_lfloorceil (operand0, operand1, true);
18071 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18072 (define_insn_and_split "frndintxf2_ceil"
18073 [(set (match_operand:XF 0 "register_operand" "")
18074 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18075 UNSPEC_FRNDINT_CEIL))
18076 (clobber (reg:CC FLAGS_REG))]
18077 "TARGET_USE_FANCY_MATH_387
18078 && flag_unsafe_math_optimizations
18079 && can_create_pseudo_p ()"
18084 ix86_optimize_mode_switching[I387_CEIL] = 1;
18086 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18087 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18089 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18090 operands[2], operands[3]));
18093 [(set_attr "type" "frndint")
18094 (set_attr "i387_cw" "ceil")
18095 (set_attr "mode" "XF")])
18097 (define_insn "frndintxf2_ceil_i387"
18098 [(set (match_operand:XF 0 "register_operand" "=f")
18099 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18100 UNSPEC_FRNDINT_CEIL))
18101 (use (match_operand:HI 2 "memory_operand" "m"))
18102 (use (match_operand:HI 3 "memory_operand" "m"))]
18103 "TARGET_USE_FANCY_MATH_387
18104 && flag_unsafe_math_optimizations"
18105 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18106 [(set_attr "type" "frndint")
18107 (set_attr "i387_cw" "ceil")
18108 (set_attr "mode" "XF")])
18110 (define_expand "ceilxf2"
18111 [(use (match_operand:XF 0 "register_operand" ""))
18112 (use (match_operand:XF 1 "register_operand" ""))]
18113 "TARGET_USE_FANCY_MATH_387
18114 && flag_unsafe_math_optimizations"
18116 if (optimize_insn_for_size_p ())
18118 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18122 (define_expand "ceil<mode>2"
18123 [(use (match_operand:MODEF 0 "register_operand" ""))
18124 (use (match_operand:MODEF 1 "register_operand" ""))]
18125 "(TARGET_USE_FANCY_MATH_387
18126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18127 || TARGET_MIX_SSE_I387)
18128 && flag_unsafe_math_optimizations)
18129 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18130 && !flag_trapping_math)"
18132 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18133 && !flag_trapping_math
18134 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18137 emit_insn (gen_sse4_1_round<mode>2
18138 (operands[0], operands[1], GEN_INT (0x02)));
18139 else if (optimize_insn_for_size_p ())
18141 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18142 ix86_expand_floorceil (operand0, operand1, false);
18144 ix86_expand_floorceildf_32 (operand0, operand1, false);
18150 if (optimize_insn_for_size_p ())
18153 op0 = gen_reg_rtx (XFmode);
18154 op1 = gen_reg_rtx (XFmode);
18155 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18156 emit_insn (gen_frndintxf2_ceil (op0, op1));
18158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18163 (define_insn_and_split "*fist<mode>2_ceil_1"
18164 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18165 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18167 (clobber (reg:CC FLAGS_REG))]
18168 "TARGET_USE_FANCY_MATH_387
18169 && flag_unsafe_math_optimizations
18170 && can_create_pseudo_p ()"
18175 ix86_optimize_mode_switching[I387_CEIL] = 1;
18177 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18178 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18179 if (memory_operand (operands[0], VOIDmode))
18180 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18181 operands[2], operands[3]));
18184 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18185 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18186 operands[2], operands[3],
18191 [(set_attr "type" "fistp")
18192 (set_attr "i387_cw" "ceil")
18193 (set_attr "mode" "<MODE>")])
18195 (define_insn "fistdi2_ceil"
18196 [(set (match_operand:DI 0 "memory_operand" "=m")
18197 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18199 (use (match_operand:HI 2 "memory_operand" "m"))
18200 (use (match_operand:HI 3 "memory_operand" "m"))
18201 (clobber (match_scratch:XF 4 "=&1f"))]
18202 "TARGET_USE_FANCY_MATH_387
18203 && flag_unsafe_math_optimizations"
18204 "* return output_fix_trunc (insn, operands, 0);"
18205 [(set_attr "type" "fistp")
18206 (set_attr "i387_cw" "ceil")
18207 (set_attr "mode" "DI")])
18209 (define_insn "fistdi2_ceil_with_temp"
18210 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18211 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18213 (use (match_operand:HI 2 "memory_operand" "m,m"))
18214 (use (match_operand:HI 3 "memory_operand" "m,m"))
18215 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18216 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18217 "TARGET_USE_FANCY_MATH_387
18218 && flag_unsafe_math_optimizations"
18220 [(set_attr "type" "fistp")
18221 (set_attr "i387_cw" "ceil")
18222 (set_attr "mode" "DI")])
18225 [(set (match_operand:DI 0 "register_operand" "")
18226 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18228 (use (match_operand:HI 2 "memory_operand" ""))
18229 (use (match_operand:HI 3 "memory_operand" ""))
18230 (clobber (match_operand:DI 4 "memory_operand" ""))
18231 (clobber (match_scratch 5 ""))]
18233 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18234 (use (match_dup 2))
18235 (use (match_dup 3))
18236 (clobber (match_dup 5))])
18237 (set (match_dup 0) (match_dup 4))]
18241 [(set (match_operand:DI 0 "memory_operand" "")
18242 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18244 (use (match_operand:HI 2 "memory_operand" ""))
18245 (use (match_operand:HI 3 "memory_operand" ""))
18246 (clobber (match_operand:DI 4 "memory_operand" ""))
18247 (clobber (match_scratch 5 ""))]
18249 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18250 (use (match_dup 2))
18251 (use (match_dup 3))
18252 (clobber (match_dup 5))])]
18255 (define_insn "fist<mode>2_ceil"
18256 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18257 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18259 (use (match_operand:HI 2 "memory_operand" "m"))
18260 (use (match_operand:HI 3 "memory_operand" "m"))]
18261 "TARGET_USE_FANCY_MATH_387
18262 && flag_unsafe_math_optimizations"
18263 "* return output_fix_trunc (insn, operands, 0);"
18264 [(set_attr "type" "fistp")
18265 (set_attr "i387_cw" "ceil")
18266 (set_attr "mode" "<MODE>")])
18268 (define_insn "fist<mode>2_ceil_with_temp"
18269 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18270 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18272 (use (match_operand:HI 2 "memory_operand" "m,m"))
18273 (use (match_operand:HI 3 "memory_operand" "m,m"))
18274 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18275 "TARGET_USE_FANCY_MATH_387
18276 && flag_unsafe_math_optimizations"
18278 [(set_attr "type" "fistp")
18279 (set_attr "i387_cw" "ceil")
18280 (set_attr "mode" "<MODE>")])
18283 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18284 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18286 (use (match_operand:HI 2 "memory_operand" ""))
18287 (use (match_operand:HI 3 "memory_operand" ""))
18288 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18290 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18292 (use (match_dup 2))
18293 (use (match_dup 3))])
18294 (set (match_dup 0) (match_dup 4))]
18298 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18299 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18301 (use (match_operand:HI 2 "memory_operand" ""))
18302 (use (match_operand:HI 3 "memory_operand" ""))
18303 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18305 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18307 (use (match_dup 2))
18308 (use (match_dup 3))])]
18311 (define_expand "lceilxf<mode>2"
18312 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18313 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18315 (clobber (reg:CC FLAGS_REG))])]
18316 "TARGET_USE_FANCY_MATH_387
18317 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18318 && flag_unsafe_math_optimizations"
18321 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
18322 [(match_operand:SWI48 0 "nonimmediate_operand" "")
18323 (match_operand:MODEF 1 "register_operand" "")]
18324 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18325 && !flag_trapping_math"
18327 ix86_expand_lfloorceil (operand0, operand1, false);
18331 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18332 (define_insn_and_split "frndintxf2_trunc"
18333 [(set (match_operand:XF 0 "register_operand" "")
18334 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18335 UNSPEC_FRNDINT_TRUNC))
18336 (clobber (reg:CC FLAGS_REG))]
18337 "TARGET_USE_FANCY_MATH_387
18338 && flag_unsafe_math_optimizations
18339 && can_create_pseudo_p ()"
18344 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18346 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18347 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18349 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18350 operands[2], operands[3]));
18353 [(set_attr "type" "frndint")
18354 (set_attr "i387_cw" "trunc")
18355 (set_attr "mode" "XF")])
18357 (define_insn "frndintxf2_trunc_i387"
18358 [(set (match_operand:XF 0 "register_operand" "=f")
18359 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18360 UNSPEC_FRNDINT_TRUNC))
18361 (use (match_operand:HI 2 "memory_operand" "m"))
18362 (use (match_operand:HI 3 "memory_operand" "m"))]
18363 "TARGET_USE_FANCY_MATH_387
18364 && flag_unsafe_math_optimizations"
18365 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18366 [(set_attr "type" "frndint")
18367 (set_attr "i387_cw" "trunc")
18368 (set_attr "mode" "XF")])
18370 (define_expand "btruncxf2"
18371 [(use (match_operand:XF 0 "register_operand" ""))
18372 (use (match_operand:XF 1 "register_operand" ""))]
18373 "TARGET_USE_FANCY_MATH_387
18374 && flag_unsafe_math_optimizations"
18376 if (optimize_insn_for_size_p ())
18378 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18382 (define_expand "btrunc<mode>2"
18383 [(use (match_operand:MODEF 0 "register_operand" ""))
18384 (use (match_operand:MODEF 1 "register_operand" ""))]
18385 "(TARGET_USE_FANCY_MATH_387
18386 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18387 || TARGET_MIX_SSE_I387)
18388 && flag_unsafe_math_optimizations)
18389 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18390 && !flag_trapping_math)"
18392 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18393 && !flag_trapping_math
18394 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18397 emit_insn (gen_sse4_1_round<mode>2
18398 (operands[0], operands[1], GEN_INT (0x03)));
18399 else if (optimize_insn_for_size_p ())
18401 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18402 ix86_expand_trunc (operand0, operand1);
18404 ix86_expand_truncdf_32 (operand0, operand1);
18410 if (optimize_insn_for_size_p ())
18413 op0 = gen_reg_rtx (XFmode);
18414 op1 = gen_reg_rtx (XFmode);
18415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18416 emit_insn (gen_frndintxf2_trunc (op0, op1));
18418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18423 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18424 (define_insn_and_split "frndintxf2_mask_pm"
18425 [(set (match_operand:XF 0 "register_operand" "")
18426 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18427 UNSPEC_FRNDINT_MASK_PM))
18428 (clobber (reg:CC FLAGS_REG))]
18429 "TARGET_USE_FANCY_MATH_387
18430 && flag_unsafe_math_optimizations
18431 && can_create_pseudo_p ()"
18436 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18438 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18439 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18441 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18442 operands[2], operands[3]));
18445 [(set_attr "type" "frndint")
18446 (set_attr "i387_cw" "mask_pm")
18447 (set_attr "mode" "XF")])
18449 (define_insn "frndintxf2_mask_pm_i387"
18450 [(set (match_operand:XF 0 "register_operand" "=f")
18451 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18452 UNSPEC_FRNDINT_MASK_PM))
18453 (use (match_operand:HI 2 "memory_operand" "m"))
18454 (use (match_operand:HI 3 "memory_operand" "m"))]
18455 "TARGET_USE_FANCY_MATH_387
18456 && flag_unsafe_math_optimizations"
18457 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18458 [(set_attr "type" "frndint")
18459 (set_attr "i387_cw" "mask_pm")
18460 (set_attr "mode" "XF")])
18462 (define_expand "nearbyintxf2"
18463 [(use (match_operand:XF 0 "register_operand" ""))
18464 (use (match_operand:XF 1 "register_operand" ""))]
18465 "TARGET_USE_FANCY_MATH_387
18466 && flag_unsafe_math_optimizations"
18468 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18473 (define_expand "nearbyint<mode>2"
18474 [(use (match_operand:MODEF 0 "register_operand" ""))
18475 (use (match_operand:MODEF 1 "register_operand" ""))]
18476 "TARGET_USE_FANCY_MATH_387
18477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18478 || TARGET_MIX_SSE_I387)
18479 && flag_unsafe_math_optimizations"
18481 rtx op0 = gen_reg_rtx (XFmode);
18482 rtx op1 = gen_reg_rtx (XFmode);
18484 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18485 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18491 (define_insn "fxam<mode>2_i387"
18492 [(set (match_operand:HI 0 "register_operand" "=a")
18494 [(match_operand:X87MODEF 1 "register_operand" "f")]
18496 "TARGET_USE_FANCY_MATH_387"
18497 "fxam\n\tfnstsw\t%0"
18498 [(set_attr "type" "multi")
18499 (set_attr "length" "4")
18500 (set_attr "unit" "i387")
18501 (set_attr "mode" "<MODE>")])
18503 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18504 [(set (match_operand:HI 0 "register_operand" "")
18506 [(match_operand:MODEF 1 "memory_operand" "")]
18508 "TARGET_USE_FANCY_MATH_387
18509 && can_create_pseudo_p ()"
18512 [(set (match_dup 2)(match_dup 1))
18514 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18516 operands[2] = gen_reg_rtx (<MODE>mode);
18518 MEM_VOLATILE_P (operands[1]) = 1;
18520 [(set_attr "type" "multi")
18521 (set_attr "unit" "i387")
18522 (set_attr "mode" "<MODE>")])
18524 (define_expand "isinfxf2"
18525 [(use (match_operand:SI 0 "register_operand" ""))
18526 (use (match_operand:XF 1 "register_operand" ""))]
18527 "TARGET_USE_FANCY_MATH_387
18528 && TARGET_C99_FUNCTIONS"
18530 rtx mask = GEN_INT (0x45);
18531 rtx val = GEN_INT (0x05);
18535 rtx scratch = gen_reg_rtx (HImode);
18536 rtx res = gen_reg_rtx (QImode);
18538 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18540 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18541 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18542 cond = gen_rtx_fmt_ee (EQ, QImode,
18543 gen_rtx_REG (CCmode, FLAGS_REG),
18545 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18546 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18550 (define_expand "isinf<mode>2"
18551 [(use (match_operand:SI 0 "register_operand" ""))
18552 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18553 "TARGET_USE_FANCY_MATH_387
18554 && TARGET_C99_FUNCTIONS
18555 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18557 rtx mask = GEN_INT (0x45);
18558 rtx val = GEN_INT (0x05);
18562 rtx scratch = gen_reg_rtx (HImode);
18563 rtx res = gen_reg_rtx (QImode);
18565 /* Remove excess precision by forcing value through memory. */
18566 if (memory_operand (operands[1], VOIDmode))
18567 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18570 enum ix86_stack_slot slot = (virtuals_instantiated
18573 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18575 emit_move_insn (temp, operands[1]);
18576 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18579 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18580 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18581 cond = gen_rtx_fmt_ee (EQ, QImode,
18582 gen_rtx_REG (CCmode, FLAGS_REG),
18584 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18585 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18589 (define_expand "signbit<mode>2"
18590 [(use (match_operand:SI 0 "register_operand" ""))
18591 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18592 "TARGET_USE_FANCY_MATH_387
18593 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18595 rtx mask = GEN_INT (0x0200);
18597 rtx scratch = gen_reg_rtx (HImode);
18599 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18600 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18604 ;; Block operation instructions
18607 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18610 [(set_attr "length" "1")
18611 (set_attr "length_immediate" "0")
18612 (set_attr "modrm" "0")])
18614 (define_expand "movmemsi"
18615 [(use (match_operand:BLK 0 "memory_operand" ""))
18616 (use (match_operand:BLK 1 "memory_operand" ""))
18617 (use (match_operand:SI 2 "nonmemory_operand" ""))
18618 (use (match_operand:SI 3 "const_int_operand" ""))
18619 (use (match_operand:SI 4 "const_int_operand" ""))
18620 (use (match_operand:SI 5 "const_int_operand" ""))]
18623 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18624 operands[4], operands[5]))
18630 (define_expand "movmemdi"
18631 [(use (match_operand:BLK 0 "memory_operand" ""))
18632 (use (match_operand:BLK 1 "memory_operand" ""))
18633 (use (match_operand:DI 2 "nonmemory_operand" ""))
18634 (use (match_operand:DI 3 "const_int_operand" ""))
18635 (use (match_operand:SI 4 "const_int_operand" ""))
18636 (use (match_operand:SI 5 "const_int_operand" ""))]
18639 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18640 operands[4], operands[5]))
18646 ;; Most CPUs don't like single string operations
18647 ;; Handle this case here to simplify previous expander.
18649 (define_expand "strmov"
18650 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18651 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18652 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18653 (clobber (reg:CC FLAGS_REG))])
18654 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18655 (clobber (reg:CC FLAGS_REG))])]
18658 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18660 /* If .md ever supports :P for Pmode, these can be directly
18661 in the pattern above. */
18662 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18663 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18665 /* Can't use this if the user has appropriated esi or edi. */
18666 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18667 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18669 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18670 operands[2], operands[3],
18671 operands[5], operands[6]));
18675 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18678 (define_expand "strmov_singleop"
18679 [(parallel [(set (match_operand 1 "memory_operand" "")
18680 (match_operand 3 "memory_operand" ""))
18681 (set (match_operand 0 "register_operand" "")
18682 (match_operand 4 "" ""))
18683 (set (match_operand 2 "register_operand" "")
18684 (match_operand 5 "" ""))])]
18686 "ix86_current_function_needs_cld = 1;")
18688 (define_insn "*strmovdi_rex_1"
18689 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18690 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18691 (set (match_operand:DI 0 "register_operand" "=D")
18692 (plus:DI (match_dup 2)
18694 (set (match_operand:DI 1 "register_operand" "=S")
18695 (plus:DI (match_dup 3)
18699 [(set_attr "type" "str")
18700 (set_attr "mode" "DI")
18701 (set_attr "memory" "both")])
18703 (define_insn "*strmovsi_1"
18704 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18705 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18706 (set (match_operand:SI 0 "register_operand" "=D")
18707 (plus:SI (match_dup 2)
18709 (set (match_operand:SI 1 "register_operand" "=S")
18710 (plus:SI (match_dup 3)
18714 [(set_attr "type" "str")
18715 (set_attr "mode" "SI")
18716 (set_attr "memory" "both")])
18718 (define_insn "*strmovsi_rex_1"
18719 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18720 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18721 (set (match_operand:DI 0 "register_operand" "=D")
18722 (plus:DI (match_dup 2)
18724 (set (match_operand:DI 1 "register_operand" "=S")
18725 (plus:DI (match_dup 3)
18729 [(set_attr "type" "str")
18730 (set_attr "mode" "SI")
18731 (set_attr "memory" "both")])
18733 (define_insn "*strmovhi_1"
18734 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18735 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18736 (set (match_operand:SI 0 "register_operand" "=D")
18737 (plus:SI (match_dup 2)
18739 (set (match_operand:SI 1 "register_operand" "=S")
18740 (plus:SI (match_dup 3)
18744 [(set_attr "type" "str")
18745 (set_attr "memory" "both")
18746 (set_attr "mode" "HI")])
18748 (define_insn "*strmovhi_rex_1"
18749 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18750 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18751 (set (match_operand:DI 0 "register_operand" "=D")
18752 (plus:DI (match_dup 2)
18754 (set (match_operand:DI 1 "register_operand" "=S")
18755 (plus:DI (match_dup 3)
18759 [(set_attr "type" "str")
18760 (set_attr "memory" "both")
18761 (set_attr "mode" "HI")])
18763 (define_insn "*strmovqi_1"
18764 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18765 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18766 (set (match_operand:SI 0 "register_operand" "=D")
18767 (plus:SI (match_dup 2)
18769 (set (match_operand:SI 1 "register_operand" "=S")
18770 (plus:SI (match_dup 3)
18774 [(set_attr "type" "str")
18775 (set_attr "memory" "both")
18776 (set_attr "mode" "QI")])
18778 (define_insn "*strmovqi_rex_1"
18779 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18780 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18781 (set (match_operand:DI 0 "register_operand" "=D")
18782 (plus:DI (match_dup 2)
18784 (set (match_operand:DI 1 "register_operand" "=S")
18785 (plus:DI (match_dup 3)
18789 [(set_attr "type" "str")
18790 (set_attr "memory" "both")
18791 (set_attr "prefix_rex" "0")
18792 (set_attr "mode" "QI")])
18794 (define_expand "rep_mov"
18795 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18796 (set (match_operand 0 "register_operand" "")
18797 (match_operand 5 "" ""))
18798 (set (match_operand 2 "register_operand" "")
18799 (match_operand 6 "" ""))
18800 (set (match_operand 1 "memory_operand" "")
18801 (match_operand 3 "memory_operand" ""))
18802 (use (match_dup 4))])]
18804 "ix86_current_function_needs_cld = 1;")
18806 (define_insn "*rep_movdi_rex64"
18807 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18808 (set (match_operand:DI 0 "register_operand" "=D")
18809 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18811 (match_operand:DI 3 "register_operand" "0")))
18812 (set (match_operand:DI 1 "register_operand" "=S")
18813 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18814 (match_operand:DI 4 "register_operand" "1")))
18815 (set (mem:BLK (match_dup 3))
18816 (mem:BLK (match_dup 4)))
18817 (use (match_dup 5))]
18820 [(set_attr "type" "str")
18821 (set_attr "prefix_rep" "1")
18822 (set_attr "memory" "both")
18823 (set_attr "mode" "DI")])
18825 (define_insn "*rep_movsi"
18826 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18827 (set (match_operand:SI 0 "register_operand" "=D")
18828 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18830 (match_operand:SI 3 "register_operand" "0")))
18831 (set (match_operand:SI 1 "register_operand" "=S")
18832 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18833 (match_operand:SI 4 "register_operand" "1")))
18834 (set (mem:BLK (match_dup 3))
18835 (mem:BLK (match_dup 4)))
18836 (use (match_dup 5))]
18839 [(set_attr "type" "str")
18840 (set_attr "prefix_rep" "1")
18841 (set_attr "memory" "both")
18842 (set_attr "mode" "SI")])
18844 (define_insn "*rep_movsi_rex64"
18845 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18846 (set (match_operand:DI 0 "register_operand" "=D")
18847 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18849 (match_operand:DI 3 "register_operand" "0")))
18850 (set (match_operand:DI 1 "register_operand" "=S")
18851 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18852 (match_operand:DI 4 "register_operand" "1")))
18853 (set (mem:BLK (match_dup 3))
18854 (mem:BLK (match_dup 4)))
18855 (use (match_dup 5))]
18858 [(set_attr "type" "str")
18859 (set_attr "prefix_rep" "1")
18860 (set_attr "memory" "both")
18861 (set_attr "mode" "SI")])
18863 (define_insn "*rep_movqi"
18864 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18865 (set (match_operand:SI 0 "register_operand" "=D")
18866 (plus:SI (match_operand:SI 3 "register_operand" "0")
18867 (match_operand:SI 5 "register_operand" "2")))
18868 (set (match_operand:SI 1 "register_operand" "=S")
18869 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18870 (set (mem:BLK (match_dup 3))
18871 (mem:BLK (match_dup 4)))
18872 (use (match_dup 5))]
18875 [(set_attr "type" "str")
18876 (set_attr "prefix_rep" "1")
18877 (set_attr "memory" "both")
18878 (set_attr "mode" "SI")])
18880 (define_insn "*rep_movqi_rex64"
18881 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18882 (set (match_operand:DI 0 "register_operand" "=D")
18883 (plus:DI (match_operand:DI 3 "register_operand" "0")
18884 (match_operand:DI 5 "register_operand" "2")))
18885 (set (match_operand:DI 1 "register_operand" "=S")
18886 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18887 (set (mem:BLK (match_dup 3))
18888 (mem:BLK (match_dup 4)))
18889 (use (match_dup 5))]
18892 [(set_attr "type" "str")
18893 (set_attr "prefix_rep" "1")
18894 (set_attr "memory" "both")
18895 (set_attr "mode" "SI")])
18897 (define_expand "setmemsi"
18898 [(use (match_operand:BLK 0 "memory_operand" ""))
18899 (use (match_operand:SI 1 "nonmemory_operand" ""))
18900 (use (match_operand 2 "const_int_operand" ""))
18901 (use (match_operand 3 "const_int_operand" ""))
18902 (use (match_operand:SI 4 "const_int_operand" ""))
18903 (use (match_operand:SI 5 "const_int_operand" ""))]
18906 if (ix86_expand_setmem (operands[0], operands[1],
18907 operands[2], operands[3],
18908 operands[4], operands[5]))
18914 (define_expand "setmemdi"
18915 [(use (match_operand:BLK 0 "memory_operand" ""))
18916 (use (match_operand:DI 1 "nonmemory_operand" ""))
18917 (use (match_operand 2 "const_int_operand" ""))
18918 (use (match_operand 3 "const_int_operand" ""))
18919 (use (match_operand 4 "const_int_operand" ""))
18920 (use (match_operand 5 "const_int_operand" ""))]
18923 if (ix86_expand_setmem (operands[0], operands[1],
18924 operands[2], operands[3],
18925 operands[4], operands[5]))
18931 ;; Most CPUs don't like single string operations
18932 ;; Handle this case here to simplify previous expander.
18934 (define_expand "strset"
18935 [(set (match_operand 1 "memory_operand" "")
18936 (match_operand 2 "register_operand" ""))
18937 (parallel [(set (match_operand 0 "register_operand" "")
18939 (clobber (reg:CC FLAGS_REG))])]
18942 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18943 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18945 /* If .md ever supports :P for Pmode, this can be directly
18946 in the pattern above. */
18947 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18948 GEN_INT (GET_MODE_SIZE (GET_MODE
18950 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18952 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18958 (define_expand "strset_singleop"
18959 [(parallel [(set (match_operand 1 "memory_operand" "")
18960 (match_operand 2 "register_operand" ""))
18961 (set (match_operand 0 "register_operand" "")
18962 (match_operand 3 "" ""))])]
18964 "ix86_current_function_needs_cld = 1;")
18966 (define_insn "*strsetdi_rex_1"
18967 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18968 (match_operand:DI 2 "register_operand" "a"))
18969 (set (match_operand:DI 0 "register_operand" "=D")
18970 (plus:DI (match_dup 1)
18974 [(set_attr "type" "str")
18975 (set_attr "memory" "store")
18976 (set_attr "mode" "DI")])
18978 (define_insn "*strsetsi_1"
18979 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18980 (match_operand:SI 2 "register_operand" "a"))
18981 (set (match_operand:SI 0 "register_operand" "=D")
18982 (plus:SI (match_dup 1)
18986 [(set_attr "type" "str")
18987 (set_attr "memory" "store")
18988 (set_attr "mode" "SI")])
18990 (define_insn "*strsetsi_rex_1"
18991 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18992 (match_operand:SI 2 "register_operand" "a"))
18993 (set (match_operand:DI 0 "register_operand" "=D")
18994 (plus:DI (match_dup 1)
18998 [(set_attr "type" "str")
18999 (set_attr "memory" "store")
19000 (set_attr "mode" "SI")])
19002 (define_insn "*strsethi_1"
19003 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19004 (match_operand:HI 2 "register_operand" "a"))
19005 (set (match_operand:SI 0 "register_operand" "=D")
19006 (plus:SI (match_dup 1)
19010 [(set_attr "type" "str")
19011 (set_attr "memory" "store")
19012 (set_attr "mode" "HI")])
19014 (define_insn "*strsethi_rex_1"
19015 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19016 (match_operand:HI 2 "register_operand" "a"))
19017 (set (match_operand:DI 0 "register_operand" "=D")
19018 (plus:DI (match_dup 1)
19022 [(set_attr "type" "str")
19023 (set_attr "memory" "store")
19024 (set_attr "mode" "HI")])
19026 (define_insn "*strsetqi_1"
19027 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19028 (match_operand:QI 2 "register_operand" "a"))
19029 (set (match_operand:SI 0 "register_operand" "=D")
19030 (plus:SI (match_dup 1)
19034 [(set_attr "type" "str")
19035 (set_attr "memory" "store")
19036 (set_attr "mode" "QI")])
19038 (define_insn "*strsetqi_rex_1"
19039 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19040 (match_operand:QI 2 "register_operand" "a"))
19041 (set (match_operand:DI 0 "register_operand" "=D")
19042 (plus:DI (match_dup 1)
19046 [(set_attr "type" "str")
19047 (set_attr "memory" "store")
19048 (set_attr "prefix_rex" "0")
19049 (set_attr "mode" "QI")])
19051 (define_expand "rep_stos"
19052 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19053 (set (match_operand 0 "register_operand" "")
19054 (match_operand 4 "" ""))
19055 (set (match_operand 2 "memory_operand" "") (const_int 0))
19056 (use (match_operand 3 "register_operand" ""))
19057 (use (match_dup 1))])]
19059 "ix86_current_function_needs_cld = 1;")
19061 (define_insn "*rep_stosdi_rex64"
19062 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19063 (set (match_operand:DI 0 "register_operand" "=D")
19064 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19066 (match_operand:DI 3 "register_operand" "0")))
19067 (set (mem:BLK (match_dup 3))
19069 (use (match_operand:DI 2 "register_operand" "a"))
19070 (use (match_dup 4))]
19073 [(set_attr "type" "str")
19074 (set_attr "prefix_rep" "1")
19075 (set_attr "memory" "store")
19076 (set_attr "mode" "DI")])
19078 (define_insn "*rep_stossi"
19079 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19080 (set (match_operand:SI 0 "register_operand" "=D")
19081 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19083 (match_operand:SI 3 "register_operand" "0")))
19084 (set (mem:BLK (match_dup 3))
19086 (use (match_operand:SI 2 "register_operand" "a"))
19087 (use (match_dup 4))]
19090 [(set_attr "type" "str")
19091 (set_attr "prefix_rep" "1")
19092 (set_attr "memory" "store")
19093 (set_attr "mode" "SI")])
19095 (define_insn "*rep_stossi_rex64"
19096 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19097 (set (match_operand:DI 0 "register_operand" "=D")
19098 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19100 (match_operand:DI 3 "register_operand" "0")))
19101 (set (mem:BLK (match_dup 3))
19103 (use (match_operand:SI 2 "register_operand" "a"))
19104 (use (match_dup 4))]
19107 [(set_attr "type" "str")
19108 (set_attr "prefix_rep" "1")
19109 (set_attr "memory" "store")
19110 (set_attr "mode" "SI")])
19112 (define_insn "*rep_stosqi"
19113 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19114 (set (match_operand:SI 0 "register_operand" "=D")
19115 (plus:SI (match_operand:SI 3 "register_operand" "0")
19116 (match_operand:SI 4 "register_operand" "1")))
19117 (set (mem:BLK (match_dup 3))
19119 (use (match_operand:QI 2 "register_operand" "a"))
19120 (use (match_dup 4))]
19123 [(set_attr "type" "str")
19124 (set_attr "prefix_rep" "1")
19125 (set_attr "memory" "store")
19126 (set_attr "mode" "QI")])
19128 (define_insn "*rep_stosqi_rex64"
19129 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19130 (set (match_operand:DI 0 "register_operand" "=D")
19131 (plus:DI (match_operand:DI 3 "register_operand" "0")
19132 (match_operand:DI 4 "register_operand" "1")))
19133 (set (mem:BLK (match_dup 3))
19135 (use (match_operand:QI 2 "register_operand" "a"))
19136 (use (match_dup 4))]
19139 [(set_attr "type" "str")
19140 (set_attr "prefix_rep" "1")
19141 (set_attr "memory" "store")
19142 (set_attr "prefix_rex" "0")
19143 (set_attr "mode" "QI")])
19145 (define_expand "cmpstrnsi"
19146 [(set (match_operand:SI 0 "register_operand" "")
19147 (compare:SI (match_operand:BLK 1 "general_operand" "")
19148 (match_operand:BLK 2 "general_operand" "")))
19149 (use (match_operand 3 "general_operand" ""))
19150 (use (match_operand 4 "immediate_operand" ""))]
19153 rtx addr1, addr2, out, outlow, count, countreg, align;
19155 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19158 /* Can't use this if the user has appropriated esi or edi. */
19159 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19164 out = gen_reg_rtx (SImode);
19166 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19167 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19168 if (addr1 != XEXP (operands[1], 0))
19169 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19170 if (addr2 != XEXP (operands[2], 0))
19171 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19173 count = operands[3];
19174 countreg = ix86_zero_extend_to_Pmode (count);
19176 /* %%% Iff we are testing strict equality, we can use known alignment
19177 to good advantage. This may be possible with combine, particularly
19178 once cc0 is dead. */
19179 align = operands[4];
19181 if (CONST_INT_P (count))
19183 if (INTVAL (count) == 0)
19185 emit_move_insn (operands[0], const0_rtx);
19188 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19189 operands[1], operands[2]));
19194 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19196 emit_insn (gen_cmpsi_1 (countreg, countreg));
19197 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19198 operands[1], operands[2]));
19201 outlow = gen_lowpart (QImode, out);
19202 emit_insn (gen_cmpintqi (outlow));
19203 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19205 if (operands[0] != out)
19206 emit_move_insn (operands[0], out);
19211 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19213 (define_expand "cmpintqi"
19214 [(set (match_dup 1)
19215 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19217 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19218 (parallel [(set (match_operand:QI 0 "register_operand" "")
19219 (minus:QI (match_dup 1)
19221 (clobber (reg:CC FLAGS_REG))])]
19223 "operands[1] = gen_reg_rtx (QImode);
19224 operands[2] = gen_reg_rtx (QImode);")
19226 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19227 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19229 (define_expand "cmpstrnqi_nz_1"
19230 [(parallel [(set (reg:CC FLAGS_REG)
19231 (compare:CC (match_operand 4 "memory_operand" "")
19232 (match_operand 5 "memory_operand" "")))
19233 (use (match_operand 2 "register_operand" ""))
19234 (use (match_operand:SI 3 "immediate_operand" ""))
19235 (clobber (match_operand 0 "register_operand" ""))
19236 (clobber (match_operand 1 "register_operand" ""))
19237 (clobber (match_dup 2))])]
19239 "ix86_current_function_needs_cld = 1;")
19241 (define_insn "*cmpstrnqi_nz_1"
19242 [(set (reg:CC FLAGS_REG)
19243 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19244 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19245 (use (match_operand:SI 6 "register_operand" "2"))
19246 (use (match_operand:SI 3 "immediate_operand" "i"))
19247 (clobber (match_operand:SI 0 "register_operand" "=S"))
19248 (clobber (match_operand:SI 1 "register_operand" "=D"))
19249 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19252 [(set_attr "type" "str")
19253 (set_attr "mode" "QI")
19254 (set_attr "prefix_rep" "1")])
19256 (define_insn "*cmpstrnqi_nz_rex_1"
19257 [(set (reg:CC FLAGS_REG)
19258 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19259 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19260 (use (match_operand:DI 6 "register_operand" "2"))
19261 (use (match_operand:SI 3 "immediate_operand" "i"))
19262 (clobber (match_operand:DI 0 "register_operand" "=S"))
19263 (clobber (match_operand:DI 1 "register_operand" "=D"))
19264 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19267 [(set_attr "type" "str")
19268 (set_attr "mode" "QI")
19269 (set_attr "prefix_rex" "0")
19270 (set_attr "prefix_rep" "1")])
19272 ;; The same, but the count is not known to not be zero.
19274 (define_expand "cmpstrnqi_1"
19275 [(parallel [(set (reg:CC FLAGS_REG)
19276 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19278 (compare:CC (match_operand 4 "memory_operand" "")
19279 (match_operand 5 "memory_operand" ""))
19281 (use (match_operand:SI 3 "immediate_operand" ""))
19282 (use (reg:CC FLAGS_REG))
19283 (clobber (match_operand 0 "register_operand" ""))
19284 (clobber (match_operand 1 "register_operand" ""))
19285 (clobber (match_dup 2))])]
19287 "ix86_current_function_needs_cld = 1;")
19289 (define_insn "*cmpstrnqi_1"
19290 [(set (reg:CC FLAGS_REG)
19291 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19293 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19294 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19296 (use (match_operand:SI 3 "immediate_operand" "i"))
19297 (use (reg:CC FLAGS_REG))
19298 (clobber (match_operand:SI 0 "register_operand" "=S"))
19299 (clobber (match_operand:SI 1 "register_operand" "=D"))
19300 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19303 [(set_attr "type" "str")
19304 (set_attr "mode" "QI")
19305 (set_attr "prefix_rep" "1")])
19307 (define_insn "*cmpstrnqi_rex_1"
19308 [(set (reg:CC FLAGS_REG)
19309 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19311 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19312 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19314 (use (match_operand:SI 3 "immediate_operand" "i"))
19315 (use (reg:CC FLAGS_REG))
19316 (clobber (match_operand:DI 0 "register_operand" "=S"))
19317 (clobber (match_operand:DI 1 "register_operand" "=D"))
19318 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19321 [(set_attr "type" "str")
19322 (set_attr "mode" "QI")
19323 (set_attr "prefix_rex" "0")
19324 (set_attr "prefix_rep" "1")])
19326 (define_expand "strlensi"
19327 [(set (match_operand:SI 0 "register_operand" "")
19328 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19329 (match_operand:QI 2 "immediate_operand" "")
19330 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19333 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19339 (define_expand "strlendi"
19340 [(set (match_operand:DI 0 "register_operand" "")
19341 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19342 (match_operand:QI 2 "immediate_operand" "")
19343 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19346 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19352 (define_expand "strlenqi_1"
19353 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19354 (clobber (match_operand 1 "register_operand" ""))
19355 (clobber (reg:CC FLAGS_REG))])]
19357 "ix86_current_function_needs_cld = 1;")
19359 (define_insn "*strlenqi_1"
19360 [(set (match_operand:SI 0 "register_operand" "=&c")
19361 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19362 (match_operand:QI 2 "register_operand" "a")
19363 (match_operand:SI 3 "immediate_operand" "i")
19364 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19365 (clobber (match_operand:SI 1 "register_operand" "=D"))
19366 (clobber (reg:CC FLAGS_REG))]
19369 [(set_attr "type" "str")
19370 (set_attr "mode" "QI")
19371 (set_attr "prefix_rep" "1")])
19373 (define_insn "*strlenqi_rex_1"
19374 [(set (match_operand:DI 0 "register_operand" "=&c")
19375 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19376 (match_operand:QI 2 "register_operand" "a")
19377 (match_operand:DI 3 "immediate_operand" "i")
19378 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19379 (clobber (match_operand:DI 1 "register_operand" "=D"))
19380 (clobber (reg:CC FLAGS_REG))]
19383 [(set_attr "type" "str")
19384 (set_attr "mode" "QI")
19385 (set_attr "prefix_rex" "0")
19386 (set_attr "prefix_rep" "1")])
19388 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19389 ;; handled in combine, but it is not currently up to the task.
19390 ;; When used for their truth value, the cmpstrn* expanders generate
19399 ;; The intermediate three instructions are unnecessary.
19401 ;; This one handles cmpstrn*_nz_1...
19404 (set (reg:CC FLAGS_REG)
19405 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19406 (mem:BLK (match_operand 5 "register_operand" ""))))
19407 (use (match_operand 6 "register_operand" ""))
19408 (use (match_operand:SI 3 "immediate_operand" ""))
19409 (clobber (match_operand 0 "register_operand" ""))
19410 (clobber (match_operand 1 "register_operand" ""))
19411 (clobber (match_operand 2 "register_operand" ""))])
19412 (set (match_operand:QI 7 "register_operand" "")
19413 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19414 (set (match_operand:QI 8 "register_operand" "")
19415 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19416 (set (reg FLAGS_REG)
19417 (compare (match_dup 7) (match_dup 8)))
19419 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19421 (set (reg:CC FLAGS_REG)
19422 (compare:CC (mem:BLK (match_dup 4))
19423 (mem:BLK (match_dup 5))))
19424 (use (match_dup 6))
19425 (use (match_dup 3))
19426 (clobber (match_dup 0))
19427 (clobber (match_dup 1))
19428 (clobber (match_dup 2))])]
19431 ;; ...and this one handles cmpstrn*_1.
19434 (set (reg:CC FLAGS_REG)
19435 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19437 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19438 (mem:BLK (match_operand 5 "register_operand" "")))
19440 (use (match_operand:SI 3 "immediate_operand" ""))
19441 (use (reg:CC FLAGS_REG))
19442 (clobber (match_operand 0 "register_operand" ""))
19443 (clobber (match_operand 1 "register_operand" ""))
19444 (clobber (match_operand 2 "register_operand" ""))])
19445 (set (match_operand:QI 7 "register_operand" "")
19446 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19447 (set (match_operand:QI 8 "register_operand" "")
19448 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19449 (set (reg FLAGS_REG)
19450 (compare (match_dup 7) (match_dup 8)))
19452 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19454 (set (reg:CC FLAGS_REG)
19455 (if_then_else:CC (ne (match_dup 6)
19457 (compare:CC (mem:BLK (match_dup 4))
19458 (mem:BLK (match_dup 5)))
19460 (use (match_dup 3))
19461 (use (reg:CC FLAGS_REG))
19462 (clobber (match_dup 0))
19463 (clobber (match_dup 1))
19464 (clobber (match_dup 2))])]
19469 ;; Conditional move instructions.
19471 (define_expand "movdicc"
19472 [(set (match_operand:DI 0 "register_operand" "")
19473 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19474 (match_operand:DI 2 "general_operand" "")
19475 (match_operand:DI 3 "general_operand" "")))]
19477 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19479 (define_insn "x86_movdicc_0_m1_rex64"
19480 [(set (match_operand:DI 0 "register_operand" "=r")
19481 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19484 (clobber (reg:CC FLAGS_REG))]
19487 ; Since we don't have the proper number of operands for an alu insn,
19488 ; fill in all the blanks.
19489 [(set_attr "type" "alu")
19490 (set_attr "use_carry" "1")
19491 (set_attr "pent_pair" "pu")
19492 (set_attr "memory" "none")
19493 (set_attr "imm_disp" "false")
19494 (set_attr "mode" "DI")
19495 (set_attr "length_immediate" "0")])
19497 (define_insn "*x86_movdicc_0_m1_se"
19498 [(set (match_operand:DI 0 "register_operand" "=r")
19499 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19502 (clobber (reg:CC FLAGS_REG))]
19505 [(set_attr "type" "alu")
19506 (set_attr "use_carry" "1")
19507 (set_attr "pent_pair" "pu")
19508 (set_attr "memory" "none")
19509 (set_attr "imm_disp" "false")
19510 (set_attr "mode" "DI")
19511 (set_attr "length_immediate" "0")])
19513 (define_insn "*movdicc_c_rex64"
19514 [(set (match_operand:DI 0 "register_operand" "=r,r")
19515 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19516 [(reg FLAGS_REG) (const_int 0)])
19517 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19518 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19519 "TARGET_64BIT && TARGET_CMOVE
19520 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19522 cmov%O2%C1\t{%2, %0|%0, %2}
19523 cmov%O2%c1\t{%3, %0|%0, %3}"
19524 [(set_attr "type" "icmov")
19525 (set_attr "mode" "DI")])
19527 (define_expand "movsicc"
19528 [(set (match_operand:SI 0 "register_operand" "")
19529 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19530 (match_operand:SI 2 "general_operand" "")
19531 (match_operand:SI 3 "general_operand" "")))]
19533 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19535 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19536 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19537 ;; So just document what we're doing explicitly.
19539 (define_insn "x86_movsicc_0_m1"
19540 [(set (match_operand:SI 0 "register_operand" "=r")
19541 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19544 (clobber (reg:CC FLAGS_REG))]
19547 ; Since we don't have the proper number of operands for an alu insn,
19548 ; fill in all the blanks.
19549 [(set_attr "type" "alu")
19550 (set_attr "use_carry" "1")
19551 (set_attr "pent_pair" "pu")
19552 (set_attr "memory" "none")
19553 (set_attr "imm_disp" "false")
19554 (set_attr "mode" "SI")
19555 (set_attr "length_immediate" "0")])
19557 (define_insn "*x86_movsicc_0_m1_se"
19558 [(set (match_operand:SI 0 "register_operand" "=r")
19559 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19562 (clobber (reg:CC FLAGS_REG))]
19565 [(set_attr "type" "alu")
19566 (set_attr "use_carry" "1")
19567 (set_attr "pent_pair" "pu")
19568 (set_attr "memory" "none")
19569 (set_attr "imm_disp" "false")
19570 (set_attr "mode" "SI")
19571 (set_attr "length_immediate" "0")])
19573 (define_insn "*movsicc_noc"
19574 [(set (match_operand:SI 0 "register_operand" "=r,r")
19575 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19576 [(reg FLAGS_REG) (const_int 0)])
19577 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19578 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19580 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19582 cmov%O2%C1\t{%2, %0|%0, %2}
19583 cmov%O2%c1\t{%3, %0|%0, %3}"
19584 [(set_attr "type" "icmov")
19585 (set_attr "mode" "SI")])
19587 (define_expand "movhicc"
19588 [(set (match_operand:HI 0 "register_operand" "")
19589 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19590 (match_operand:HI 2 "general_operand" "")
19591 (match_operand:HI 3 "general_operand" "")))]
19592 "TARGET_HIMODE_MATH"
19593 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19595 (define_insn "*movhicc_noc"
19596 [(set (match_operand:HI 0 "register_operand" "=r,r")
19597 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19598 [(reg FLAGS_REG) (const_int 0)])
19599 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19600 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19602 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19604 cmov%O2%C1\t{%2, %0|%0, %2}
19605 cmov%O2%c1\t{%3, %0|%0, %3}"
19606 [(set_attr "type" "icmov")
19607 (set_attr "mode" "HI")])
19609 (define_expand "movqicc"
19610 [(set (match_operand:QI 0 "register_operand" "")
19611 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19612 (match_operand:QI 2 "general_operand" "")
19613 (match_operand:QI 3 "general_operand" "")))]
19614 "TARGET_QIMODE_MATH"
19615 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19617 (define_insn_and_split "*movqicc_noc"
19618 [(set (match_operand:QI 0 "register_operand" "=r,r")
19619 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19620 [(match_operand 4 "flags_reg_operand" "")
19622 (match_operand:QI 2 "register_operand" "r,0")
19623 (match_operand:QI 3 "register_operand" "0,r")))]
19624 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19626 "&& reload_completed"
19627 [(set (match_dup 0)
19628 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19631 "operands[0] = gen_lowpart (SImode, operands[0]);
19632 operands[2] = gen_lowpart (SImode, operands[2]);
19633 operands[3] = gen_lowpart (SImode, operands[3]);"
19634 [(set_attr "type" "icmov")
19635 (set_attr "mode" "SI")])
19637 (define_expand "mov<mode>cc"
19638 [(set (match_operand:X87MODEF 0 "register_operand" "")
19639 (if_then_else:X87MODEF
19640 (match_operand 1 "ix86_fp_comparison_operator" "")
19641 (match_operand:X87MODEF 2 "register_operand" "")
19642 (match_operand:X87MODEF 3 "register_operand" "")))]
19643 "(TARGET_80387 && TARGET_CMOVE)
19644 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19645 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19647 (define_insn "*movsfcc_1_387"
19648 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19649 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19650 [(reg FLAGS_REG) (const_int 0)])
19651 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19652 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19653 "TARGET_80387 && TARGET_CMOVE
19654 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19656 fcmov%F1\t{%2, %0|%0, %2}
19657 fcmov%f1\t{%3, %0|%0, %3}
19658 cmov%O2%C1\t{%2, %0|%0, %2}
19659 cmov%O2%c1\t{%3, %0|%0, %3}"
19660 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19661 (set_attr "mode" "SF,SF,SI,SI")])
19663 (define_insn "*movdfcc_1"
19664 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19665 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19666 [(reg FLAGS_REG) (const_int 0)])
19667 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19668 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19669 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19670 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19672 fcmov%F1\t{%2, %0|%0, %2}
19673 fcmov%f1\t{%3, %0|%0, %3}
19676 [(set_attr "type" "fcmov,fcmov,multi,multi")
19677 (set_attr "mode" "DF")])
19679 (define_insn "*movdfcc_1_rex64"
19680 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19681 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19682 [(reg FLAGS_REG) (const_int 0)])
19683 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19684 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19685 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19686 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19688 fcmov%F1\t{%2, %0|%0, %2}
19689 fcmov%f1\t{%3, %0|%0, %3}
19690 cmov%O2%C1\t{%2, %0|%0, %2}
19691 cmov%O2%c1\t{%3, %0|%0, %3}"
19692 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19693 (set_attr "mode" "DF")])
19696 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19697 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19698 [(match_operand 4 "flags_reg_operand" "")
19700 (match_operand:DF 2 "nonimmediate_operand" "")
19701 (match_operand:DF 3 "nonimmediate_operand" "")))]
19702 "!TARGET_64BIT && reload_completed"
19703 [(set (match_dup 2)
19704 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19708 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19711 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19712 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19714 (define_insn "*movxfcc_1"
19715 [(set (match_operand:XF 0 "register_operand" "=f,f")
19716 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19717 [(reg FLAGS_REG) (const_int 0)])
19718 (match_operand:XF 2 "register_operand" "f,0")
19719 (match_operand:XF 3 "register_operand" "0,f")))]
19720 "TARGET_80387 && TARGET_CMOVE"
19722 fcmov%F1\t{%2, %0|%0, %2}
19723 fcmov%f1\t{%3, %0|%0, %3}"
19724 [(set_attr "type" "fcmov")
19725 (set_attr "mode" "XF")])
19727 ;; These versions of the min/max patterns are intentionally ignorant of
19728 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19729 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19730 ;; are undefined in this condition, we're certain this is correct.
19732 (define_insn "*avx_<code><mode>3"
19733 [(set (match_operand:MODEF 0 "register_operand" "=x")
19735 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19736 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19737 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19738 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19739 [(set_attr "type" "sseadd")
19740 (set_attr "prefix" "vex")
19741 (set_attr "mode" "<MODE>")])
19743 (define_insn "<code><mode>3"
19744 [(set (match_operand:MODEF 0 "register_operand" "=x")
19746 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19747 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19748 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19749 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19750 [(set_attr "type" "sseadd")
19751 (set_attr "mode" "<MODE>")])
19753 ;; These versions of the min/max patterns implement exactly the operations
19754 ;; min = (op1 < op2 ? op1 : op2)
19755 ;; max = (!(op1 < op2) ? op1 : op2)
19756 ;; Their operands are not commutative, and thus they may be used in the
19757 ;; presence of -0.0 and NaN.
19759 (define_insn "*avx_ieee_smin<mode>3"
19760 [(set (match_operand:MODEF 0 "register_operand" "=x")
19762 [(match_operand:MODEF 1 "register_operand" "x")
19763 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19765 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19766 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19767 [(set_attr "type" "sseadd")
19768 (set_attr "prefix" "vex")
19769 (set_attr "mode" "<MODE>")])
19771 (define_insn "*ieee_smin<mode>3"
19772 [(set (match_operand:MODEF 0 "register_operand" "=x")
19774 [(match_operand:MODEF 1 "register_operand" "0")
19775 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19777 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19778 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19779 [(set_attr "type" "sseadd")
19780 (set_attr "mode" "<MODE>")])
19782 (define_insn "*avx_ieee_smax<mode>3"
19783 [(set (match_operand:MODEF 0 "register_operand" "=x")
19785 [(match_operand:MODEF 1 "register_operand" "0")
19786 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19788 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19789 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19790 [(set_attr "type" "sseadd")
19791 (set_attr "prefix" "vex")
19792 (set_attr "mode" "<MODE>")])
19794 (define_insn "*ieee_smax<mode>3"
19795 [(set (match_operand:MODEF 0 "register_operand" "=x")
19797 [(match_operand:MODEF 1 "register_operand" "0")
19798 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19800 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19801 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19802 [(set_attr "type" "sseadd")
19803 (set_attr "mode" "<MODE>")])
19805 ;; Make two stack loads independent:
19807 ;; fld %st(0) -> fld bb
19808 ;; fmul bb fmul %st(1), %st
19810 ;; Actually we only match the last two instructions for simplicity.
19812 [(set (match_operand 0 "fp_register_operand" "")
19813 (match_operand 1 "fp_register_operand" ""))
19815 (match_operator 2 "binary_fp_operator"
19817 (match_operand 3 "memory_operand" "")]))]
19818 "REGNO (operands[0]) != REGNO (operands[1])"
19819 [(set (match_dup 0) (match_dup 3))
19820 (set (match_dup 0) (match_dup 4))]
19822 ;; The % modifier is not operational anymore in peephole2's, so we have to
19823 ;; swap the operands manually in the case of addition and multiplication.
19824 "if (COMMUTATIVE_ARITH_P (operands[2]))
19825 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19826 operands[0], operands[1]);
19828 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19829 operands[1], operands[0]);")
19831 ;; Conditional addition patterns
19832 (define_expand "add<mode>cc"
19833 [(match_operand:SWI 0 "register_operand" "")
19834 (match_operand 1 "comparison_operator" "")
19835 (match_operand:SWI 2 "register_operand" "")
19836 (match_operand:SWI 3 "const_int_operand" "")]
19838 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19841 ;; Misc patterns (?)
19843 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19844 ;; Otherwise there will be nothing to keep
19846 ;; [(set (reg ebp) (reg esp))]
19847 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19848 ;; (clobber (eflags)]
19849 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19851 ;; in proper program order.
19852 (define_insn "pro_epilogue_adjust_stack_1"
19853 [(set (match_operand:SI 0 "register_operand" "=r,r")
19854 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19855 (match_operand:SI 2 "immediate_operand" "i,i")))
19856 (clobber (reg:CC FLAGS_REG))
19857 (clobber (mem:BLK (scratch)))]
19860 switch (get_attr_type (insn))
19863 return "mov{l}\t{%1, %0|%0, %1}";
19866 if (CONST_INT_P (operands[2])
19867 && (INTVAL (operands[2]) == 128
19868 || (INTVAL (operands[2]) < 0
19869 && INTVAL (operands[2]) != -128)))
19871 operands[2] = GEN_INT (-INTVAL (operands[2]));
19872 return "sub{l}\t{%2, %0|%0, %2}";
19874 return "add{l}\t{%2, %0|%0, %2}";
19877 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19878 return "lea{l}\t{%a2, %0|%0, %a2}";
19881 gcc_unreachable ();
19884 [(set (attr "type")
19885 (cond [(and (eq_attr "alternative" "0")
19886 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19887 (const_string "alu")
19888 (match_operand:SI 2 "const0_operand" "")
19889 (const_string "imov")
19891 (const_string "lea")))
19892 (set (attr "length_immediate")
19893 (cond [(eq_attr "type" "imov")
19895 (and (eq_attr "type" "alu")
19896 (match_operand 2 "const128_operand" ""))
19899 (const_string "*")))
19900 (set_attr "mode" "SI")])
19902 (define_insn "pro_epilogue_adjust_stack_rex64"
19903 [(set (match_operand:DI 0 "register_operand" "=r,r")
19904 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19905 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19906 (clobber (reg:CC FLAGS_REG))
19907 (clobber (mem:BLK (scratch)))]
19910 switch (get_attr_type (insn))
19913 return "mov{q}\t{%1, %0|%0, %1}";
19916 if (CONST_INT_P (operands[2])
19917 /* Avoid overflows. */
19918 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19919 && (INTVAL (operands[2]) == 128
19920 || (INTVAL (operands[2]) < 0
19921 && INTVAL (operands[2]) != -128)))
19923 operands[2] = GEN_INT (-INTVAL (operands[2]));
19924 return "sub{q}\t{%2, %0|%0, %2}";
19926 return "add{q}\t{%2, %0|%0, %2}";
19929 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19930 return "lea{q}\t{%a2, %0|%0, %a2}";
19933 gcc_unreachable ();
19936 [(set (attr "type")
19937 (cond [(and (eq_attr "alternative" "0")
19938 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19939 (const_string "alu")
19940 (match_operand:DI 2 "const0_operand" "")
19941 (const_string "imov")
19943 (const_string "lea")))
19944 (set (attr "length_immediate")
19945 (cond [(eq_attr "type" "imov")
19947 (and (eq_attr "type" "alu")
19948 (match_operand 2 "const128_operand" ""))
19951 (const_string "*")))
19952 (set_attr "mode" "DI")])
19954 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19955 [(set (match_operand:DI 0 "register_operand" "=r,r")
19956 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19957 (match_operand:DI 3 "immediate_operand" "i,i")))
19958 (use (match_operand:DI 2 "register_operand" "r,r"))
19959 (clobber (reg:CC FLAGS_REG))
19960 (clobber (mem:BLK (scratch)))]
19963 switch (get_attr_type (insn))
19966 return "add{q}\t{%2, %0|%0, %2}";
19969 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19970 return "lea{q}\t{%a2, %0|%0, %a2}";
19973 gcc_unreachable ();
19976 [(set_attr "type" "alu,lea")
19977 (set_attr "mode" "DI")])
19979 (define_insn "allocate_stack_worker_32"
19980 [(set (match_operand:SI 0 "register_operand" "=a")
19981 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19982 UNSPECV_STACK_PROBE))
19983 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19984 (clobber (reg:CC FLAGS_REG))]
19985 "!TARGET_64BIT && TARGET_STACK_PROBE"
19987 [(set_attr "type" "multi")
19988 (set_attr "length" "5")])
19990 (define_insn "allocate_stack_worker_64"
19991 [(set (match_operand:DI 0 "register_operand" "=a")
19992 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19993 UNSPECV_STACK_PROBE))
19994 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19995 (clobber (reg:DI R10_REG))
19996 (clobber (reg:DI R11_REG))
19997 (clobber (reg:CC FLAGS_REG))]
19998 "TARGET_64BIT && TARGET_STACK_PROBE"
20000 [(set_attr "type" "multi")
20001 (set_attr "length" "5")])
20003 (define_expand "allocate_stack"
20004 [(match_operand 0 "register_operand" "")
20005 (match_operand 1 "general_operand" "")]
20006 "TARGET_STACK_PROBE"
20010 #ifndef CHECK_STACK_LIMIT
20011 #define CHECK_STACK_LIMIT 0
20014 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20015 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20017 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20018 stack_pointer_rtx, 0, OPTAB_DIRECT);
20019 if (x != stack_pointer_rtx)
20020 emit_move_insn (stack_pointer_rtx, x);
20024 x = copy_to_mode_reg (Pmode, operands[1]);
20026 x = gen_allocate_stack_worker_64 (x, x);
20028 x = gen_allocate_stack_worker_32 (x, x);
20032 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20036 (define_expand "builtin_setjmp_receiver"
20037 [(label_ref (match_operand 0 "" ""))]
20038 "!TARGET_64BIT && flag_pic"
20044 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20045 rtx label_rtx = gen_label_rtx ();
20046 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20047 xops[0] = xops[1] = picreg;
20048 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20049 ix86_expand_binary_operator (MINUS, SImode, xops);
20053 emit_insn (gen_set_got (pic_offset_table_rtx));
20057 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20060 [(set (match_operand 0 "register_operand" "")
20061 (match_operator 3 "promotable_binary_operator"
20062 [(match_operand 1 "register_operand" "")
20063 (match_operand 2 "aligned_operand" "")]))
20064 (clobber (reg:CC FLAGS_REG))]
20065 "! TARGET_PARTIAL_REG_STALL && reload_completed
20066 && ((GET_MODE (operands[0]) == HImode
20067 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20068 /* ??? next two lines just !satisfies_constraint_K (...) */
20069 || !CONST_INT_P (operands[2])
20070 || satisfies_constraint_K (operands[2])))
20071 || (GET_MODE (operands[0]) == QImode
20072 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20073 [(parallel [(set (match_dup 0)
20074 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20075 (clobber (reg:CC FLAGS_REG))])]
20076 "operands[0] = gen_lowpart (SImode, operands[0]);
20077 operands[1] = gen_lowpart (SImode, operands[1]);
20078 if (GET_CODE (operands[3]) != ASHIFT)
20079 operands[2] = gen_lowpart (SImode, operands[2]);
20080 PUT_MODE (operands[3], SImode);")
20082 ; Promote the QImode tests, as i386 has encoding of the AND
20083 ; instruction with 32-bit sign-extended immediate and thus the
20084 ; instruction size is unchanged, except in the %eax case for
20085 ; which it is increased by one byte, hence the ! optimize_size.
20087 [(set (match_operand 0 "flags_reg_operand" "")
20088 (match_operator 2 "compare_operator"
20089 [(and (match_operand 3 "aligned_operand" "")
20090 (match_operand 4 "const_int_operand" ""))
20092 (set (match_operand 1 "register_operand" "")
20093 (and (match_dup 3) (match_dup 4)))]
20094 "! TARGET_PARTIAL_REG_STALL && reload_completed
20095 && optimize_insn_for_speed_p ()
20096 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20097 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20098 /* Ensure that the operand will remain sign-extended immediate. */
20099 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20100 [(parallel [(set (match_dup 0)
20101 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20104 (and:SI (match_dup 3) (match_dup 4)))])]
20107 = gen_int_mode (INTVAL (operands[4])
20108 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20109 operands[1] = gen_lowpart (SImode, operands[1]);
20110 operands[3] = gen_lowpart (SImode, operands[3]);
20113 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20114 ; the TEST instruction with 32-bit sign-extended immediate and thus
20115 ; the instruction size would at least double, which is not what we
20116 ; want even with ! optimize_size.
20118 [(set (match_operand 0 "flags_reg_operand" "")
20119 (match_operator 1 "compare_operator"
20120 [(and (match_operand:HI 2 "aligned_operand" "")
20121 (match_operand:HI 3 "const_int_operand" ""))
20123 "! TARGET_PARTIAL_REG_STALL && reload_completed
20124 && ! TARGET_FAST_PREFIX
20125 && optimize_insn_for_speed_p ()
20126 /* Ensure that the operand will remain sign-extended immediate. */
20127 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20128 [(set (match_dup 0)
20129 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20133 = gen_int_mode (INTVAL (operands[3])
20134 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20135 operands[2] = gen_lowpart (SImode, operands[2]);
20139 [(set (match_operand 0 "register_operand" "")
20140 (neg (match_operand 1 "register_operand" "")))
20141 (clobber (reg:CC FLAGS_REG))]
20142 "! TARGET_PARTIAL_REG_STALL && reload_completed
20143 && (GET_MODE (operands[0]) == HImode
20144 || (GET_MODE (operands[0]) == QImode
20145 && (TARGET_PROMOTE_QImode
20146 || optimize_insn_for_size_p ())))"
20147 [(parallel [(set (match_dup 0)
20148 (neg:SI (match_dup 1)))
20149 (clobber (reg:CC FLAGS_REG))])]
20150 "operands[0] = gen_lowpart (SImode, operands[0]);
20151 operands[1] = gen_lowpart (SImode, operands[1]);")
20154 [(set (match_operand 0 "register_operand" "")
20155 (not (match_operand 1 "register_operand" "")))]
20156 "! TARGET_PARTIAL_REG_STALL && reload_completed
20157 && (GET_MODE (operands[0]) == HImode
20158 || (GET_MODE (operands[0]) == QImode
20159 && (TARGET_PROMOTE_QImode
20160 || optimize_insn_for_size_p ())))"
20161 [(set (match_dup 0)
20162 (not:SI (match_dup 1)))]
20163 "operands[0] = gen_lowpart (SImode, operands[0]);
20164 operands[1] = gen_lowpart (SImode, operands[1]);")
20167 [(set (match_operand 0 "register_operand" "")
20168 (if_then_else (match_operator 1 "comparison_operator"
20169 [(reg FLAGS_REG) (const_int 0)])
20170 (match_operand 2 "register_operand" "")
20171 (match_operand 3 "register_operand" "")))]
20172 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20173 && (GET_MODE (operands[0]) == HImode
20174 || (GET_MODE (operands[0]) == QImode
20175 && (TARGET_PROMOTE_QImode
20176 || optimize_insn_for_size_p ())))"
20177 [(set (match_dup 0)
20178 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20179 "operands[0] = gen_lowpart (SImode, operands[0]);
20180 operands[2] = gen_lowpart (SImode, operands[2]);
20181 operands[3] = gen_lowpart (SImode, operands[3]);")
20184 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20185 ;; transform a complex memory operation into two memory to register operations.
20187 ;; Don't push memory operands
20189 [(set (match_operand:SI 0 "push_operand" "")
20190 (match_operand:SI 1 "memory_operand" ""))
20191 (match_scratch:SI 2 "r")]
20192 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20193 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20194 [(set (match_dup 2) (match_dup 1))
20195 (set (match_dup 0) (match_dup 2))]
20199 [(set (match_operand:DI 0 "push_operand" "")
20200 (match_operand:DI 1 "memory_operand" ""))
20201 (match_scratch:DI 2 "r")]
20202 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20203 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20204 [(set (match_dup 2) (match_dup 1))
20205 (set (match_dup 0) (match_dup 2))]
20208 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20211 [(set (match_operand:SF 0 "push_operand" "")
20212 (match_operand:SF 1 "memory_operand" ""))
20213 (match_scratch:SF 2 "r")]
20214 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20215 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20216 [(set (match_dup 2) (match_dup 1))
20217 (set (match_dup 0) (match_dup 2))]
20221 [(set (match_operand:HI 0 "push_operand" "")
20222 (match_operand:HI 1 "memory_operand" ""))
20223 (match_scratch:HI 2 "r")]
20224 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20225 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20226 [(set (match_dup 2) (match_dup 1))
20227 (set (match_dup 0) (match_dup 2))]
20231 [(set (match_operand:QI 0 "push_operand" "")
20232 (match_operand:QI 1 "memory_operand" ""))
20233 (match_scratch:QI 2 "q")]
20234 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20235 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20236 [(set (match_dup 2) (match_dup 1))
20237 (set (match_dup 0) (match_dup 2))]
20240 ;; Don't move an immediate directly to memory when the instruction
20243 [(match_scratch:SI 1 "r")
20244 (set (match_operand:SI 0 "memory_operand" "")
20246 "optimize_insn_for_speed_p ()
20247 && ! TARGET_USE_MOV0
20248 && TARGET_SPLIT_LONG_MOVES
20249 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20250 && peep2_regno_dead_p (0, FLAGS_REG)"
20251 [(parallel [(set (match_dup 1) (const_int 0))
20252 (clobber (reg:CC FLAGS_REG))])
20253 (set (match_dup 0) (match_dup 1))]
20257 [(match_scratch:HI 1 "r")
20258 (set (match_operand:HI 0 "memory_operand" "")
20260 "optimize_insn_for_speed_p ()
20261 && ! TARGET_USE_MOV0
20262 && TARGET_SPLIT_LONG_MOVES
20263 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20264 && peep2_regno_dead_p (0, FLAGS_REG)"
20265 [(parallel [(set (match_dup 2) (const_int 0))
20266 (clobber (reg:CC FLAGS_REG))])
20267 (set (match_dup 0) (match_dup 1))]
20268 "operands[2] = gen_lowpart (SImode, operands[1]);")
20271 [(match_scratch:QI 1 "q")
20272 (set (match_operand:QI 0 "memory_operand" "")
20274 "optimize_insn_for_speed_p ()
20275 && ! TARGET_USE_MOV0
20276 && TARGET_SPLIT_LONG_MOVES
20277 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20278 && peep2_regno_dead_p (0, FLAGS_REG)"
20279 [(parallel [(set (match_dup 2) (const_int 0))
20280 (clobber (reg:CC FLAGS_REG))])
20281 (set (match_dup 0) (match_dup 1))]
20282 "operands[2] = gen_lowpart (SImode, operands[1]);")
20285 [(match_scratch:SI 2 "r")
20286 (set (match_operand:SI 0 "memory_operand" "")
20287 (match_operand:SI 1 "immediate_operand" ""))]
20288 "optimize_insn_for_speed_p ()
20289 && TARGET_SPLIT_LONG_MOVES
20290 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20291 [(set (match_dup 2) (match_dup 1))
20292 (set (match_dup 0) (match_dup 2))]
20296 [(match_scratch:HI 2 "r")
20297 (set (match_operand:HI 0 "memory_operand" "")
20298 (match_operand:HI 1 "immediate_operand" ""))]
20299 "optimize_insn_for_speed_p ()
20300 && TARGET_SPLIT_LONG_MOVES
20301 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20302 [(set (match_dup 2) (match_dup 1))
20303 (set (match_dup 0) (match_dup 2))]
20307 [(match_scratch:QI 2 "q")
20308 (set (match_operand:QI 0 "memory_operand" "")
20309 (match_operand:QI 1 "immediate_operand" ""))]
20310 "optimize_insn_for_speed_p ()
20311 && TARGET_SPLIT_LONG_MOVES
20312 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20313 [(set (match_dup 2) (match_dup 1))
20314 (set (match_dup 0) (match_dup 2))]
20317 ;; Don't compare memory with zero, load and use a test instead.
20319 [(set (match_operand 0 "flags_reg_operand" "")
20320 (match_operator 1 "compare_operator"
20321 [(match_operand:SI 2 "memory_operand" "")
20323 (match_scratch:SI 3 "r")]
20324 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20325 [(set (match_dup 3) (match_dup 2))
20326 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20329 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20330 ;; Don't split NOTs with a displacement operand, because resulting XOR
20331 ;; will not be pairable anyway.
20333 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20334 ;; represented using a modRM byte. The XOR replacement is long decoded,
20335 ;; so this split helps here as well.
20337 ;; Note: Can't do this as a regular split because we can't get proper
20338 ;; lifetime information then.
20341 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20342 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20343 "optimize_insn_for_speed_p ()
20344 && ((TARGET_NOT_UNPAIRABLE
20345 && (!MEM_P (operands[0])
20346 || !memory_displacement_operand (operands[0], SImode)))
20347 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20348 && peep2_regno_dead_p (0, FLAGS_REG)"
20349 [(parallel [(set (match_dup 0)
20350 (xor:SI (match_dup 1) (const_int -1)))
20351 (clobber (reg:CC FLAGS_REG))])]
20355 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20356 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20357 "optimize_insn_for_speed_p ()
20358 && ((TARGET_NOT_UNPAIRABLE
20359 && (!MEM_P (operands[0])
20360 || !memory_displacement_operand (operands[0], HImode)))
20361 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20362 && peep2_regno_dead_p (0, FLAGS_REG)"
20363 [(parallel [(set (match_dup 0)
20364 (xor:HI (match_dup 1) (const_int -1)))
20365 (clobber (reg:CC FLAGS_REG))])]
20369 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20370 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20371 "optimize_insn_for_speed_p ()
20372 && ((TARGET_NOT_UNPAIRABLE
20373 && (!MEM_P (operands[0])
20374 || !memory_displacement_operand (operands[0], QImode)))
20375 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20376 && peep2_regno_dead_p (0, FLAGS_REG)"
20377 [(parallel [(set (match_dup 0)
20378 (xor:QI (match_dup 1) (const_int -1)))
20379 (clobber (reg:CC FLAGS_REG))])]
20382 ;; Non pairable "test imm, reg" instructions can be translated to
20383 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20384 ;; byte opcode instead of two, have a short form for byte operands),
20385 ;; so do it for other CPUs as well. Given that the value was dead,
20386 ;; this should not create any new dependencies. Pass on the sub-word
20387 ;; versions if we're concerned about partial register stalls.
20390 [(set (match_operand 0 "flags_reg_operand" "")
20391 (match_operator 1 "compare_operator"
20392 [(and:SI (match_operand:SI 2 "register_operand" "")
20393 (match_operand:SI 3 "immediate_operand" ""))
20395 "ix86_match_ccmode (insn, CCNOmode)
20396 && (true_regnum (operands[2]) != AX_REG
20397 || satisfies_constraint_K (operands[3]))
20398 && peep2_reg_dead_p (1, operands[2])"
20400 [(set (match_dup 0)
20401 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20404 (and:SI (match_dup 2) (match_dup 3)))])]
20407 ;; We don't need to handle HImode case, because it will be promoted to SImode
20408 ;; on ! TARGET_PARTIAL_REG_STALL
20411 [(set (match_operand 0 "flags_reg_operand" "")
20412 (match_operator 1 "compare_operator"
20413 [(and:QI (match_operand:QI 2 "register_operand" "")
20414 (match_operand:QI 3 "immediate_operand" ""))
20416 "! TARGET_PARTIAL_REG_STALL
20417 && ix86_match_ccmode (insn, CCNOmode)
20418 && true_regnum (operands[2]) != AX_REG
20419 && peep2_reg_dead_p (1, operands[2])"
20421 [(set (match_dup 0)
20422 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20425 (and:QI (match_dup 2) (match_dup 3)))])]
20429 [(set (match_operand 0 "flags_reg_operand" "")
20430 (match_operator 1 "compare_operator"
20433 (match_operand 2 "ext_register_operand" "")
20436 (match_operand 3 "const_int_operand" ""))
20438 "! TARGET_PARTIAL_REG_STALL
20439 && ix86_match_ccmode (insn, CCNOmode)
20440 && true_regnum (operands[2]) != AX_REG
20441 && peep2_reg_dead_p (1, operands[2])"
20442 [(parallel [(set (match_dup 0)
20451 (set (zero_extract:SI (match_dup 2)
20462 ;; Don't do logical operations with memory inputs.
20464 [(match_scratch:SI 2 "r")
20465 (parallel [(set (match_operand:SI 0 "register_operand" "")
20466 (match_operator:SI 3 "arith_or_logical_operator"
20468 (match_operand:SI 1 "memory_operand" "")]))
20469 (clobber (reg:CC FLAGS_REG))])]
20470 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20471 [(set (match_dup 2) (match_dup 1))
20472 (parallel [(set (match_dup 0)
20473 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20474 (clobber (reg:CC FLAGS_REG))])]
20478 [(match_scratch:SI 2 "r")
20479 (parallel [(set (match_operand:SI 0 "register_operand" "")
20480 (match_operator:SI 3 "arith_or_logical_operator"
20481 [(match_operand:SI 1 "memory_operand" "")
20483 (clobber (reg:CC FLAGS_REG))])]
20484 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20485 [(set (match_dup 2) (match_dup 1))
20486 (parallel [(set (match_dup 0)
20487 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20488 (clobber (reg:CC FLAGS_REG))])]
20491 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20492 ;; refers to the destination of the load!
20495 [(set (match_operand:SI 0 "register_operand" "")
20496 (match_operand:SI 1 "register_operand" ""))
20497 (parallel [(set (match_dup 0)
20498 (match_operator:SI 3 "commutative_operator"
20500 (match_operand:SI 2 "memory_operand" "")]))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "REGNO (operands[0]) != REGNO (operands[1])
20503 && GENERAL_REGNO_P (REGNO (operands[0]))
20504 && GENERAL_REGNO_P (REGNO (operands[1]))"
20505 [(set (match_dup 0) (match_dup 4))
20506 (parallel [(set (match_dup 0)
20507 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20508 (clobber (reg:CC FLAGS_REG))])]
20509 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20512 [(set (match_operand 0 "register_operand" "")
20513 (match_operand 1 "register_operand" ""))
20515 (match_operator 3 "commutative_operator"
20517 (match_operand 2 "memory_operand" "")]))]
20518 "REGNO (operands[0]) != REGNO (operands[1])
20519 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20520 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20521 [(set (match_dup 0) (match_dup 2))
20523 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20526 ; Don't do logical operations with memory outputs
20528 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20529 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20530 ; the same decoder scheduling characteristics as the original.
20533 [(match_scratch:SI 2 "r")
20534 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20535 (match_operator:SI 3 "arith_or_logical_operator"
20537 (match_operand:SI 1 "nonmemory_operand" "")]))
20538 (clobber (reg:CC FLAGS_REG))])]
20539 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20540 [(set (match_dup 2) (match_dup 0))
20541 (parallel [(set (match_dup 2)
20542 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20543 (clobber (reg:CC FLAGS_REG))])
20544 (set (match_dup 0) (match_dup 2))]
20548 [(match_scratch:SI 2 "r")
20549 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20550 (match_operator:SI 3 "arith_or_logical_operator"
20551 [(match_operand:SI 1 "nonmemory_operand" "")
20553 (clobber (reg:CC FLAGS_REG))])]
20554 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20555 [(set (match_dup 2) (match_dup 0))
20556 (parallel [(set (match_dup 2)
20557 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20558 (clobber (reg:CC FLAGS_REG))])
20559 (set (match_dup 0) (match_dup 2))]
20562 ;; Attempt to always use XOR for zeroing registers.
20564 [(set (match_operand 0 "register_operand" "")
20565 (match_operand 1 "const0_operand" ""))]
20566 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20567 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20568 && GENERAL_REG_P (operands[0])
20569 && peep2_regno_dead_p (0, FLAGS_REG)"
20570 [(parallel [(set (match_dup 0) (const_int 0))
20571 (clobber (reg:CC FLAGS_REG))])]
20573 operands[0] = gen_lowpart (word_mode, operands[0]);
20577 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20579 "(GET_MODE (operands[0]) == QImode
20580 || GET_MODE (operands[0]) == HImode)
20581 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20582 && peep2_regno_dead_p (0, FLAGS_REG)"
20583 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20584 (clobber (reg:CC FLAGS_REG))])])
20586 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20588 [(set (match_operand 0 "register_operand" "")
20590 "(GET_MODE (operands[0]) == HImode
20591 || GET_MODE (operands[0]) == SImode
20592 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20593 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20594 && peep2_regno_dead_p (0, FLAGS_REG)"
20595 [(parallel [(set (match_dup 0) (const_int -1))
20596 (clobber (reg:CC FLAGS_REG))])]
20597 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20600 ;; Attempt to convert simple leas to adds. These can be created by
20603 [(set (match_operand:SI 0 "register_operand" "")
20604 (plus:SI (match_dup 0)
20605 (match_operand:SI 1 "nonmemory_operand" "")))]
20606 "peep2_regno_dead_p (0, FLAGS_REG)"
20607 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20608 (clobber (reg:CC FLAGS_REG))])]
20612 [(set (match_operand:SI 0 "register_operand" "")
20613 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20614 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20615 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20616 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20617 (clobber (reg:CC FLAGS_REG))])]
20618 "operands[2] = gen_lowpart (SImode, operands[2]);")
20621 [(set (match_operand:DI 0 "register_operand" "")
20622 (plus:DI (match_dup 0)
20623 (match_operand:DI 1 "x86_64_general_operand" "")))]
20624 "peep2_regno_dead_p (0, FLAGS_REG)"
20625 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20626 (clobber (reg:CC FLAGS_REG))])]
20630 [(set (match_operand:SI 0 "register_operand" "")
20631 (mult:SI (match_dup 0)
20632 (match_operand:SI 1 "const_int_operand" "")))]
20633 "exact_log2 (INTVAL (operands[1])) >= 0
20634 && peep2_regno_dead_p (0, FLAGS_REG)"
20635 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20636 (clobber (reg:CC FLAGS_REG))])]
20637 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20640 [(set (match_operand:DI 0 "register_operand" "")
20641 (mult:DI (match_dup 0)
20642 (match_operand:DI 1 "const_int_operand" "")))]
20643 "exact_log2 (INTVAL (operands[1])) >= 0
20644 && peep2_regno_dead_p (0, FLAGS_REG)"
20645 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20646 (clobber (reg:CC FLAGS_REG))])]
20647 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20650 [(set (match_operand:SI 0 "register_operand" "")
20651 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20652 (match_operand:DI 2 "const_int_operand" "")) 0))]
20653 "exact_log2 (INTVAL (operands[2])) >= 0
20654 && REGNO (operands[0]) == REGNO (operands[1])
20655 && peep2_regno_dead_p (0, FLAGS_REG)"
20656 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20657 (clobber (reg:CC FLAGS_REG))])]
20658 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20660 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20661 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20662 ;; many CPUs it is also faster, since special hardware to avoid esp
20663 ;; dependencies is present.
20665 ;; While some of these conversions may be done using splitters, we use peepholes
20666 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20668 ;; Convert prologue esp subtractions to push.
20669 ;; We need register to push. In order to keep verify_flow_info happy we have
20671 ;; - use scratch and clobber it in order to avoid dependencies
20672 ;; - use already live register
20673 ;; We can't use the second way right now, since there is no reliable way how to
20674 ;; verify that given register is live. First choice will also most likely in
20675 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20676 ;; call clobbered registers are dead. We may want to use base pointer as an
20677 ;; alternative when no register is available later.
20680 [(match_scratch:SI 0 "r")
20681 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20682 (clobber (reg:CC FLAGS_REG))
20683 (clobber (mem:BLK (scratch)))])]
20684 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20685 [(clobber (match_dup 0))
20686 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20687 (clobber (mem:BLK (scratch)))])])
20690 [(match_scratch:SI 0 "r")
20691 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20692 (clobber (reg:CC FLAGS_REG))
20693 (clobber (mem:BLK (scratch)))])]
20694 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20695 [(clobber (match_dup 0))
20696 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20697 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20698 (clobber (mem:BLK (scratch)))])])
20700 ;; Convert esp subtractions to push.
20702 [(match_scratch:SI 0 "r")
20703 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20704 (clobber (reg:CC FLAGS_REG))])]
20705 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20706 [(clobber (match_dup 0))
20707 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20710 [(match_scratch:SI 0 "r")
20711 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20712 (clobber (reg:CC FLAGS_REG))])]
20713 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20714 [(clobber (match_dup 0))
20715 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20716 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20718 ;; Convert epilogue deallocator to pop.
20720 [(match_scratch:SI 0 "r")
20721 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20722 (clobber (reg:CC FLAGS_REG))
20723 (clobber (mem:BLK (scratch)))])]
20724 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20725 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20726 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20727 (clobber (mem:BLK (scratch)))])]
20730 ;; Two pops case is tricky, since pop causes dependency on destination register.
20731 ;; We use two registers if available.
20733 [(match_scratch:SI 0 "r")
20734 (match_scratch:SI 1 "r")
20735 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20736 (clobber (reg:CC FLAGS_REG))
20737 (clobber (mem:BLK (scratch)))])]
20738 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20739 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20740 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20741 (clobber (mem:BLK (scratch)))])
20742 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20743 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20747 [(match_scratch:SI 0 "r")
20748 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20749 (clobber (reg:CC FLAGS_REG))
20750 (clobber (mem:BLK (scratch)))])]
20751 "optimize_insn_for_size_p ()"
20752 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20753 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20754 (clobber (mem:BLK (scratch)))])
20755 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20759 ;; Convert esp additions to pop.
20761 [(match_scratch:SI 0 "r")
20762 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20763 (clobber (reg:CC FLAGS_REG))])]
20765 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20766 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20769 ;; Two pops case is tricky, since pop causes dependency on destination register.
20770 ;; We use two registers if available.
20772 [(match_scratch:SI 0 "r")
20773 (match_scratch:SI 1 "r")
20774 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20775 (clobber (reg:CC FLAGS_REG))])]
20777 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20778 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20779 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20780 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20784 [(match_scratch:SI 0 "r")
20785 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20786 (clobber (reg:CC FLAGS_REG))])]
20787 "optimize_insn_for_size_p ()"
20788 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20789 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20790 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20791 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20794 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20795 ;; required and register dies. Similarly for 128 to -128.
20797 [(set (match_operand 0 "flags_reg_operand" "")
20798 (match_operator 1 "compare_operator"
20799 [(match_operand 2 "register_operand" "")
20800 (match_operand 3 "const_int_operand" "")]))]
20801 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20802 && incdec_operand (operands[3], GET_MODE (operands[3])))
20803 || (!TARGET_FUSE_CMP_AND_BRANCH
20804 && INTVAL (operands[3]) == 128))
20805 && ix86_match_ccmode (insn, CCGCmode)
20806 && peep2_reg_dead_p (1, operands[2])"
20807 [(parallel [(set (match_dup 0)
20808 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20809 (clobber (match_dup 2))])]
20813 [(match_scratch:DI 0 "r")
20814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20815 (clobber (reg:CC FLAGS_REG))
20816 (clobber (mem:BLK (scratch)))])]
20817 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20818 [(clobber (match_dup 0))
20819 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20820 (clobber (mem:BLK (scratch)))])])
20823 [(match_scratch:DI 0 "r")
20824 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20825 (clobber (reg:CC FLAGS_REG))
20826 (clobber (mem:BLK (scratch)))])]
20827 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20828 [(clobber (match_dup 0))
20829 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20830 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20831 (clobber (mem:BLK (scratch)))])])
20833 ;; Convert esp subtractions to push.
20835 [(match_scratch:DI 0 "r")
20836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20837 (clobber (reg:CC FLAGS_REG))])]
20838 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20839 [(clobber (match_dup 0))
20840 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20843 [(match_scratch:DI 0 "r")
20844 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20845 (clobber (reg:CC FLAGS_REG))])]
20846 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20847 [(clobber (match_dup 0))
20848 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20849 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20851 ;; Convert epilogue deallocator to pop.
20853 [(match_scratch:DI 0 "r")
20854 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20855 (clobber (reg:CC FLAGS_REG))
20856 (clobber (mem:BLK (scratch)))])]
20857 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20858 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20859 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20860 (clobber (mem:BLK (scratch)))])]
20863 ;; Two pops case is tricky, since pop causes dependency on destination register.
20864 ;; We use two registers if available.
20866 [(match_scratch:DI 0 "r")
20867 (match_scratch:DI 1 "r")
20868 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20869 (clobber (reg:CC FLAGS_REG))
20870 (clobber (mem:BLK (scratch)))])]
20871 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20872 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20873 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20874 (clobber (mem:BLK (scratch)))])
20875 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20880 [(match_scratch:DI 0 "r")
20881 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20882 (clobber (reg:CC FLAGS_REG))
20883 (clobber (mem:BLK (scratch)))])]
20884 "optimize_insn_for_size_p ()"
20885 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20886 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20887 (clobber (mem:BLK (scratch)))])
20888 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20892 ;; Convert esp additions to pop.
20894 [(match_scratch:DI 0 "r")
20895 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20896 (clobber (reg:CC FLAGS_REG))])]
20898 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20899 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20902 ;; Two pops case is tricky, since pop causes dependency on destination register.
20903 ;; We use two registers if available.
20905 [(match_scratch:DI 0 "r")
20906 (match_scratch:DI 1 "r")
20907 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20908 (clobber (reg:CC FLAGS_REG))])]
20910 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20911 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20912 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20913 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20917 [(match_scratch:DI 0 "r")
20918 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20919 (clobber (reg:CC FLAGS_REG))])]
20920 "optimize_insn_for_size_p ()"
20921 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20922 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20923 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20924 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20927 ;; Convert imul by three, five and nine into lea
20930 [(set (match_operand:SI 0 "register_operand" "")
20931 (mult:SI (match_operand:SI 1 "register_operand" "")
20932 (match_operand:SI 2 "const_int_operand" "")))
20933 (clobber (reg:CC FLAGS_REG))])]
20934 "INTVAL (operands[2]) == 3
20935 || INTVAL (operands[2]) == 5
20936 || INTVAL (operands[2]) == 9"
20937 [(set (match_dup 0)
20938 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20940 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20944 [(set (match_operand:SI 0 "register_operand" "")
20945 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20946 (match_operand:SI 2 "const_int_operand" "")))
20947 (clobber (reg:CC FLAGS_REG))])]
20948 "optimize_insn_for_speed_p ()
20949 && (INTVAL (operands[2]) == 3
20950 || INTVAL (operands[2]) == 5
20951 || INTVAL (operands[2]) == 9)"
20952 [(set (match_dup 0) (match_dup 1))
20954 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20956 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20960 [(set (match_operand:DI 0 "register_operand" "")
20961 (mult:DI (match_operand:DI 1 "register_operand" "")
20962 (match_operand:DI 2 "const_int_operand" "")))
20963 (clobber (reg:CC FLAGS_REG))])]
20965 && (INTVAL (operands[2]) == 3
20966 || INTVAL (operands[2]) == 5
20967 || INTVAL (operands[2]) == 9)"
20968 [(set (match_dup 0)
20969 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20971 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20975 [(set (match_operand:DI 0 "register_operand" "")
20976 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20977 (match_operand:DI 2 "const_int_operand" "")))
20978 (clobber (reg:CC FLAGS_REG))])]
20980 && optimize_insn_for_speed_p ()
20981 && (INTVAL (operands[2]) == 3
20982 || INTVAL (operands[2]) == 5
20983 || INTVAL (operands[2]) == 9)"
20984 [(set (match_dup 0) (match_dup 1))
20986 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20988 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20990 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20991 ;; imul $32bit_imm, reg, reg is direct decoded.
20993 [(match_scratch:DI 3 "r")
20994 (parallel [(set (match_operand:DI 0 "register_operand" "")
20995 (mult:DI (match_operand:DI 1 "memory_operand" "")
20996 (match_operand:DI 2 "immediate_operand" "")))
20997 (clobber (reg:CC FLAGS_REG))])]
20998 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20999 && !satisfies_constraint_K (operands[2])"
21000 [(set (match_dup 3) (match_dup 1))
21001 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21002 (clobber (reg:CC FLAGS_REG))])]
21006 [(match_scratch:SI 3 "r")
21007 (parallel [(set (match_operand:SI 0 "register_operand" "")
21008 (mult:SI (match_operand:SI 1 "memory_operand" "")
21009 (match_operand:SI 2 "immediate_operand" "")))
21010 (clobber (reg:CC FLAGS_REG))])]
21011 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21012 && !satisfies_constraint_K (operands[2])"
21013 [(set (match_dup 3) (match_dup 1))
21014 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21015 (clobber (reg:CC FLAGS_REG))])]
21019 [(match_scratch:SI 3 "r")
21020 (parallel [(set (match_operand:DI 0 "register_operand" "")
21022 (mult:SI (match_operand:SI 1 "memory_operand" "")
21023 (match_operand:SI 2 "immediate_operand" ""))))
21024 (clobber (reg:CC FLAGS_REG))])]
21025 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21026 && !satisfies_constraint_K (operands[2])"
21027 [(set (match_dup 3) (match_dup 1))
21028 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21029 (clobber (reg:CC FLAGS_REG))])]
21032 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21033 ;; Convert it into imul reg, reg
21034 ;; It would be better to force assembler to encode instruction using long
21035 ;; immediate, but there is apparently no way to do so.
21037 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21038 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21039 (match_operand:DI 2 "const_int_operand" "")))
21040 (clobber (reg:CC FLAGS_REG))])
21041 (match_scratch:DI 3 "r")]
21042 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21043 && satisfies_constraint_K (operands[2])"
21044 [(set (match_dup 3) (match_dup 2))
21045 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21046 (clobber (reg:CC FLAGS_REG))])]
21048 if (!rtx_equal_p (operands[0], operands[1]))
21049 emit_move_insn (operands[0], operands[1]);
21053 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21054 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21055 (match_operand:SI 2 "const_int_operand" "")))
21056 (clobber (reg:CC FLAGS_REG))])
21057 (match_scratch:SI 3 "r")]
21058 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21059 && satisfies_constraint_K (operands[2])"
21060 [(set (match_dup 3) (match_dup 2))
21061 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21062 (clobber (reg:CC FLAGS_REG))])]
21064 if (!rtx_equal_p (operands[0], operands[1]))
21065 emit_move_insn (operands[0], operands[1]);
21069 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21070 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21071 (match_operand:HI 2 "immediate_operand" "")))
21072 (clobber (reg:CC FLAGS_REG))])
21073 (match_scratch:HI 3 "r")]
21074 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21075 [(set (match_dup 3) (match_dup 2))
21076 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21077 (clobber (reg:CC FLAGS_REG))])]
21079 if (!rtx_equal_p (operands[0], operands[1]))
21080 emit_move_insn (operands[0], operands[1]);
21083 ;; After splitting up read-modify operations, array accesses with memory
21084 ;; operands might end up in form:
21086 ;; movl 4(%esp), %edx
21088 ;; instead of pre-splitting:
21090 ;; addl 4(%esp), %eax
21092 ;; movl 4(%esp), %edx
21093 ;; leal (%edx,%eax,4), %eax
21096 [(parallel [(set (match_operand 0 "register_operand" "")
21097 (ashift (match_operand 1 "register_operand" "")
21098 (match_operand 2 "const_int_operand" "")))
21099 (clobber (reg:CC FLAGS_REG))])
21100 (set (match_operand 3 "register_operand")
21101 (match_operand 4 "x86_64_general_operand" ""))
21102 (parallel [(set (match_operand 5 "register_operand" "")
21103 (plus (match_operand 6 "register_operand" "")
21104 (match_operand 7 "register_operand" "")))
21105 (clobber (reg:CC FLAGS_REG))])]
21106 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21107 /* Validate MODE for lea. */
21108 && ((!TARGET_PARTIAL_REG_STALL
21109 && (GET_MODE (operands[0]) == QImode
21110 || GET_MODE (operands[0]) == HImode))
21111 || GET_MODE (operands[0]) == SImode
21112 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21113 /* We reorder load and the shift. */
21114 && !rtx_equal_p (operands[1], operands[3])
21115 && !reg_overlap_mentioned_p (operands[0], operands[4])
21116 /* Last PLUS must consist of operand 0 and 3. */
21117 && !rtx_equal_p (operands[0], operands[3])
21118 && (rtx_equal_p (operands[3], operands[6])
21119 || rtx_equal_p (operands[3], operands[7]))
21120 && (rtx_equal_p (operands[0], operands[6])
21121 || rtx_equal_p (operands[0], operands[7]))
21122 /* The intermediate operand 0 must die or be same as output. */
21123 && (rtx_equal_p (operands[0], operands[5])
21124 || peep2_reg_dead_p (3, operands[0]))"
21125 [(set (match_dup 3) (match_dup 4))
21126 (set (match_dup 0) (match_dup 1))]
21128 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21129 int scale = 1 << INTVAL (operands[2]);
21130 rtx index = gen_lowpart (Pmode, operands[1]);
21131 rtx base = gen_lowpart (Pmode, operands[3]);
21132 rtx dest = gen_lowpart (mode, operands[5]);
21134 operands[1] = gen_rtx_PLUS (Pmode, base,
21135 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21137 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21138 operands[0] = dest;
21141 ;; Call-value patterns last so that the wildcard operand does not
21142 ;; disrupt insn-recog's switch tables.
21144 (define_insn "*call_value_pop_0"
21145 [(set (match_operand 0 "" "")
21146 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21147 (match_operand:SI 2 "" "")))
21148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21149 (match_operand:SI 3 "immediate_operand" "")))]
21152 if (SIBLING_CALL_P (insn))
21155 return "call\t%P1";
21157 [(set_attr "type" "callv")])
21159 (define_insn "*call_value_pop_1"
21160 [(set (match_operand 0 "" "")
21161 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21162 (match_operand:SI 2 "" "")))
21163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21164 (match_operand:SI 3 "immediate_operand" "i")))]
21165 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21167 if (constant_call_address_operand (operands[1], Pmode))
21168 return "call\t%P1";
21169 return "call\t%A1";
21171 [(set_attr "type" "callv")])
21173 (define_insn "*sibcall_value_pop_1"
21174 [(set (match_operand 0 "" "")
21175 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21176 (match_operand:SI 2 "" "")))
21177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21178 (match_operand:SI 3 "immediate_operand" "i,i")))]
21179 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21183 [(set_attr "type" "callv")])
21185 (define_insn "*call_value_0"
21186 [(set (match_operand 0 "" "")
21187 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21188 (match_operand:SI 2 "" "")))]
21191 if (SIBLING_CALL_P (insn))
21194 return "call\t%P1";
21196 [(set_attr "type" "callv")])
21198 (define_insn "*call_value_0_rex64"
21199 [(set (match_operand 0 "" "")
21200 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21201 (match_operand:DI 2 "const_int_operand" "")))]
21204 if (SIBLING_CALL_P (insn))
21207 return "call\t%P1";
21209 [(set_attr "type" "callv")])
21211 (define_insn "*call_value_0_rex64_ms_sysv"
21212 [(set (match_operand 0 "" "")
21213 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21214 (match_operand:DI 2 "const_int_operand" "")))
21215 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21216 (clobber (reg:TI XMM6_REG))
21217 (clobber (reg:TI XMM7_REG))
21218 (clobber (reg:TI XMM8_REG))
21219 (clobber (reg:TI XMM9_REG))
21220 (clobber (reg:TI XMM10_REG))
21221 (clobber (reg:TI XMM11_REG))
21222 (clobber (reg:TI XMM12_REG))
21223 (clobber (reg:TI XMM13_REG))
21224 (clobber (reg:TI XMM14_REG))
21225 (clobber (reg:TI XMM15_REG))
21226 (clobber (reg:DI SI_REG))
21227 (clobber (reg:DI DI_REG))]
21228 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21230 if (SIBLING_CALL_P (insn))
21233 return "call\t%P1";
21235 [(set_attr "type" "callv")])
21237 (define_insn "*call_value_1"
21238 [(set (match_operand 0 "" "")
21239 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21240 (match_operand:SI 2 "" "")))]
21241 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21243 if (constant_call_address_operand (operands[1], Pmode))
21244 return "call\t%P1";
21245 return "call\t%A1";
21247 [(set_attr "type" "callv")])
21249 (define_insn "*sibcall_value_1"
21250 [(set (match_operand 0 "" "")
21251 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21252 (match_operand:SI 2 "" "")))]
21253 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21257 [(set_attr "type" "callv")])
21259 (define_insn "*call_value_1_rex64"
21260 [(set (match_operand 0 "" "")
21261 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21262 (match_operand:DI 2 "" "")))]
21263 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21264 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21266 if (constant_call_address_operand (operands[1], Pmode))
21267 return "call\t%P1";
21268 return "call\t%A1";
21270 [(set_attr "type" "callv")])
21272 (define_insn "*call_value_1_rex64_ms_sysv"
21273 [(set (match_operand 0 "" "")
21274 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21275 (match_operand:DI 2 "" "")))
21276 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21277 (clobber (reg:TI 27))
21278 (clobber (reg:TI 28))
21279 (clobber (reg:TI 45))
21280 (clobber (reg:TI 46))
21281 (clobber (reg:TI 47))
21282 (clobber (reg:TI 48))
21283 (clobber (reg:TI 49))
21284 (clobber (reg:TI 50))
21285 (clobber (reg:TI 51))
21286 (clobber (reg:TI 52))
21287 (clobber (reg:DI SI_REG))
21288 (clobber (reg:DI DI_REG))]
21289 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21291 if (constant_call_address_operand (operands[1], Pmode))
21292 return "call\t%P1";
21293 return "call\t%A1";
21295 [(set_attr "type" "callv")])
21297 (define_insn "*call_value_1_rex64_large"
21298 [(set (match_operand 0 "" "")
21299 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21300 (match_operand:DI 2 "" "")))]
21301 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21303 [(set_attr "type" "callv")])
21305 (define_insn "*sibcall_value_1_rex64"
21306 [(set (match_operand 0 "" "")
21307 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21308 (match_operand:DI 2 "" "")))]
21309 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21313 [(set_attr "type" "callv")])
21315 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21316 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21317 ;; caught for use by garbage collectors and the like. Using an insn that
21318 ;; maps to SIGILL makes it more likely the program will rightfully die.
21319 ;; Keeping with tradition, "6" is in honor of #UD.
21320 (define_insn "trap"
21321 [(trap_if (const_int 1) (const_int 6))]
21323 { return ASM_SHORT "0x0b0f"; }
21324 [(set_attr "length" "2")])
21326 (define_expand "sse_prologue_save"
21327 [(parallel [(set (match_operand:BLK 0 "" "")
21328 (unspec:BLK [(reg:DI 21)
21335 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21336 (use (match_operand:DI 1 "register_operand" ""))
21337 (use (match_operand:DI 2 "immediate_operand" ""))
21338 (use (label_ref:DI (match_operand 3 "" "")))])]
21342 (define_insn "*sse_prologue_save_insn"
21343 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21344 (match_operand:DI 4 "const_int_operand" "n")))
21345 (unspec:BLK [(reg:DI 21)
21352 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21353 (use (match_operand:DI 1 "register_operand" "r"))
21354 (use (match_operand:DI 2 "const_int_operand" "i"))
21355 (use (label_ref:DI (match_operand 3 "" "X")))]
21357 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21358 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21361 operands[0] = gen_rtx_MEM (Pmode,
21362 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21363 /* VEX instruction with a REX prefix will #UD. */
21364 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21365 gcc_unreachable ();
21367 output_asm_insn ("jmp\t%A1", operands);
21368 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21370 operands[4] = adjust_address (operands[0], DImode, i*16);
21371 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21372 PUT_MODE (operands[4], TImode);
21373 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21374 output_asm_insn ("rex", operands);
21375 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21377 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21378 CODE_LABEL_NUMBER (operands[3]));
21381 [(set_attr "type" "other")
21382 (set_attr "length_immediate" "0")
21383 (set_attr "length_address" "0")
21384 (set (attr "length")
21386 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21387 (const_string "34")
21388 (const_string "42")))
21389 (set_attr "memory" "store")
21390 (set_attr "modrm" "0")
21391 (set_attr "prefix" "maybe_vex")
21392 (set_attr "mode" "DI")])
21394 (define_expand "prefetch"
21395 [(prefetch (match_operand 0 "address_operand" "")
21396 (match_operand:SI 1 "const_int_operand" "")
21397 (match_operand:SI 2 "const_int_operand" ""))]
21398 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21400 int rw = INTVAL (operands[1]);
21401 int locality = INTVAL (operands[2]);
21403 gcc_assert (rw == 0 || rw == 1);
21404 gcc_assert (locality >= 0 && locality <= 3);
21405 gcc_assert (GET_MODE (operands[0]) == Pmode
21406 || GET_MODE (operands[0]) == VOIDmode);
21408 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21409 supported by SSE counterpart or the SSE prefetch is not available
21410 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21412 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21413 operands[2] = GEN_INT (3);
21415 operands[1] = const0_rtx;
21418 (define_insn "*prefetch_sse"
21419 [(prefetch (match_operand:SI 0 "address_operand" "p")
21421 (match_operand:SI 1 "const_int_operand" ""))]
21422 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21424 static const char * const patterns[4] = {
21425 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21428 int locality = INTVAL (operands[1]);
21429 gcc_assert (locality >= 0 && locality <= 3);
21431 return patterns[locality];
21433 [(set_attr "type" "sse")
21434 (set_attr "atom_sse_attr" "prefetch")
21435 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21436 (set_attr "memory" "none")])
21438 (define_insn "*prefetch_sse_rex"
21439 [(prefetch (match_operand:DI 0 "address_operand" "p")
21441 (match_operand:SI 1 "const_int_operand" ""))]
21442 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21444 static const char * const patterns[4] = {
21445 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21448 int locality = INTVAL (operands[1]);
21449 gcc_assert (locality >= 0 && locality <= 3);
21451 return patterns[locality];
21453 [(set_attr "type" "sse")
21454 (set_attr "atom_sse_attr" "prefetch")
21455 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21456 (set_attr "memory" "none")])
21458 (define_insn "*prefetch_3dnow"
21459 [(prefetch (match_operand:SI 0 "address_operand" "p")
21460 (match_operand:SI 1 "const_int_operand" "n")
21462 "TARGET_3DNOW && !TARGET_64BIT"
21464 if (INTVAL (operands[1]) == 0)
21465 return "prefetch\t%a0";
21467 return "prefetchw\t%a0";
21469 [(set_attr "type" "mmx")
21470 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21471 (set_attr "memory" "none")])
21473 (define_insn "*prefetch_3dnow_rex"
21474 [(prefetch (match_operand:DI 0 "address_operand" "p")
21475 (match_operand:SI 1 "const_int_operand" "n")
21477 "TARGET_3DNOW && TARGET_64BIT"
21479 if (INTVAL (operands[1]) == 0)
21480 return "prefetch\t%a0";
21482 return "prefetchw\t%a0";
21484 [(set_attr "type" "mmx")
21485 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21486 (set_attr "memory" "none")])
21488 (define_expand "stack_protect_set"
21489 [(match_operand 0 "memory_operand" "")
21490 (match_operand 1 "memory_operand" "")]
21493 #ifdef TARGET_THREAD_SSP_OFFSET
21495 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21496 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21498 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21499 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21502 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21504 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21509 (define_insn "stack_protect_set_si"
21510 [(set (match_operand:SI 0 "memory_operand" "=m")
21511 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21512 (set (match_scratch:SI 2 "=&r") (const_int 0))
21513 (clobber (reg:CC FLAGS_REG))]
21515 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21516 [(set_attr "type" "multi")])
21518 (define_insn "stack_protect_set_di"
21519 [(set (match_operand:DI 0 "memory_operand" "=m")
21520 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21521 (set (match_scratch:DI 2 "=&r") (const_int 0))
21522 (clobber (reg:CC FLAGS_REG))]
21524 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21525 [(set_attr "type" "multi")])
21527 (define_insn "stack_tls_protect_set_si"
21528 [(set (match_operand:SI 0 "memory_operand" "=m")
21529 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21530 (set (match_scratch:SI 2 "=&r") (const_int 0))
21531 (clobber (reg:CC FLAGS_REG))]
21533 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21534 [(set_attr "type" "multi")])
21536 (define_insn "stack_tls_protect_set_di"
21537 [(set (match_operand:DI 0 "memory_operand" "=m")
21538 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21539 (set (match_scratch:DI 2 "=&r") (const_int 0))
21540 (clobber (reg:CC FLAGS_REG))]
21543 /* The kernel uses a different segment register for performance reasons; a
21544 system call would not have to trash the userspace segment register,
21545 which would be expensive */
21546 if (ix86_cmodel != CM_KERNEL)
21547 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21549 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21551 [(set_attr "type" "multi")])
21553 (define_expand "stack_protect_test"
21554 [(match_operand 0 "memory_operand" "")
21555 (match_operand 1 "memory_operand" "")
21556 (match_operand 2 "" "")]
21559 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21561 #ifdef TARGET_THREAD_SSP_OFFSET
21563 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21564 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21566 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21567 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21570 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21572 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21575 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21576 flags, const0_rtx, operands[2]));
21580 (define_insn "stack_protect_test_si"
21581 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21582 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21583 (match_operand:SI 2 "memory_operand" "m")]
21585 (clobber (match_scratch:SI 3 "=&r"))]
21587 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21588 [(set_attr "type" "multi")])
21590 (define_insn "stack_protect_test_di"
21591 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21592 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21593 (match_operand:DI 2 "memory_operand" "m")]
21595 (clobber (match_scratch:DI 3 "=&r"))]
21597 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21598 [(set_attr "type" "multi")])
21600 (define_insn "stack_tls_protect_test_si"
21601 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21602 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21603 (match_operand:SI 2 "const_int_operand" "i")]
21604 UNSPEC_SP_TLS_TEST))
21605 (clobber (match_scratch:SI 3 "=r"))]
21607 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21608 [(set_attr "type" "multi")])
21610 (define_insn "stack_tls_protect_test_di"
21611 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21612 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21613 (match_operand:DI 2 "const_int_operand" "i")]
21614 UNSPEC_SP_TLS_TEST))
21615 (clobber (match_scratch:DI 3 "=r"))]
21618 /* The kernel uses a different segment register for performance reasons; a
21619 system call would not have to trash the userspace segment register,
21620 which would be expensive */
21621 if (ix86_cmodel != CM_KERNEL)
21622 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21624 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21626 [(set_attr "type" "multi")])
21628 (define_mode_iterator CRC32MODE [QI HI SI])
21629 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21630 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21632 (define_insn "sse4_2_crc32<mode>"
21633 [(set (match_operand:SI 0 "register_operand" "=r")
21635 [(match_operand:SI 1 "register_operand" "0")
21636 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21638 "TARGET_SSE4_2 || TARGET_CRC32"
21639 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21640 [(set_attr "type" "sselog1")
21641 (set_attr "prefix_rep" "1")
21642 (set_attr "prefix_extra" "1")
21643 (set (attr "prefix_data16")
21644 (if_then_else (match_operand:HI 2 "" "")
21646 (const_string "*")))
21647 (set (attr "prefix_rex")
21648 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21650 (const_string "*")))
21651 (set_attr "mode" "SI")])
21653 (define_insn "sse4_2_crc32di"
21654 [(set (match_operand:DI 0 "register_operand" "=r")
21656 [(match_operand:DI 1 "register_operand" "0")
21657 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21659 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21660 "crc32q\t{%2, %0|%0, %2}"
21661 [(set_attr "type" "sselog1")
21662 (set_attr "prefix_rep" "1")
21663 (set_attr "prefix_extra" "1")
21664 (set_attr "mode" "DI")])
21666 (define_expand "rdpmc"
21667 [(match_operand:DI 0 "register_operand" "")
21668 (match_operand:SI 1 "register_operand" "")]
21671 rtx reg = gen_reg_rtx (DImode);
21674 /* Force operand 1 into ECX. */
21675 rtx ecx = gen_rtx_REG (SImode, CX_REG);
21676 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21677 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21682 rtvec vec = rtvec_alloc (2);
21683 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21684 rtx upper = gen_reg_rtx (DImode);
21685 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21686 gen_rtvec (1, const0_rtx),
21688 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21689 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21691 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21692 NULL, 1, OPTAB_DIRECT);
21693 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21697 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21698 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21702 (define_insn "*rdpmc"
21703 [(set (match_operand:DI 0 "register_operand" "=A")
21704 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21708 [(set_attr "type" "other")
21709 (set_attr "length" "2")])
21711 (define_insn "*rdpmc_rex64"
21712 [(set (match_operand:DI 0 "register_operand" "=a")
21713 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21715 (set (match_operand:DI 1 "register_operand" "=d")
21716 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21719 [(set_attr "type" "other")
21720 (set_attr "length" "2")])
21722 (define_expand "rdtsc"
21723 [(set (match_operand:DI 0 "register_operand" "")
21724 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21729 rtvec vec = rtvec_alloc (2);
21730 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21731 rtx upper = gen_reg_rtx (DImode);
21732 rtx lower = gen_reg_rtx (DImode);
21733 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21734 gen_rtvec (1, const0_rtx),
21736 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21737 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21739 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21740 NULL, 1, OPTAB_DIRECT);
21741 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21743 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21748 (define_insn "*rdtsc"
21749 [(set (match_operand:DI 0 "register_operand" "=A")
21750 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21753 [(set_attr "type" "other")
21754 (set_attr "length" "2")])
21756 (define_insn "*rdtsc_rex64"
21757 [(set (match_operand:DI 0 "register_operand" "=a")
21758 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21759 (set (match_operand:DI 1 "register_operand" "=d")
21760 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21763 [(set_attr "type" "other")
21764 (set_attr "length" "2")])
21766 (define_expand "rdtscp"
21767 [(match_operand:DI 0 "register_operand" "")
21768 (match_operand:SI 1 "memory_operand" "")]
21771 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21772 gen_rtvec (1, const0_rtx),
21774 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21775 gen_rtvec (1, const0_rtx),
21777 rtx reg = gen_reg_rtx (DImode);
21778 rtx tmp = gen_reg_rtx (SImode);
21782 rtvec vec = rtvec_alloc (3);
21783 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21784 rtx upper = gen_reg_rtx (DImode);
21785 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21786 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21787 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21789 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21790 NULL, 1, OPTAB_DIRECT);
21791 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21796 rtvec vec = rtvec_alloc (2);
21797 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21798 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21799 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21802 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21803 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21807 (define_insn "*rdtscp"
21808 [(set (match_operand:DI 0 "register_operand" "=A")
21809 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21810 (set (match_operand:SI 1 "register_operand" "=c")
21811 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21814 [(set_attr "type" "other")
21815 (set_attr "length" "3")])
21817 (define_insn "*rdtscp_rex64"
21818 [(set (match_operand:DI 0 "register_operand" "=a")
21819 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21820 (set (match_operand:DI 1 "register_operand" "=d")
21821 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21822 (set (match_operand:SI 2 "register_operand" "=c")
21823 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21826 [(set_attr "type" "other")
21827 (set_attr "length" "3")])
21831 (include "sync.md")