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 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
61 (UNSPEC_MACHOPIC_OFFSET 10)
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
71 (UNSPEC_MEMORY_BLOCKAGE 18)
76 (UNSPEC_TLS_LD_BASE 22)
79 ; Other random patterns
88 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
89 (UNSPEC_TRUNC_NOOP 39)
91 ; For SSE/MMX support:
92 (UNSPEC_FIX_NOTRUNC 40)
109 (UNSPEC_MS_TO_SYSV_CALL 48)
111 ; Generic math support
113 (UNSPEC_IEEE_MIN 51) ; not commutative
114 (UNSPEC_IEEE_MAX 52) ; not commutative
129 (UNSPEC_FRNDINT_FLOOR 70)
130 (UNSPEC_FRNDINT_CEIL 71)
131 (UNSPEC_FRNDINT_TRUNC 72)
132 (UNSPEC_FRNDINT_MASK_PM 73)
133 (UNSPEC_FIST_FLOOR 74)
134 (UNSPEC_FIST_CEIL 75)
136 ; x87 Double output FP
137 (UNSPEC_SINCOS_COS 80)
138 (UNSPEC_SINCOS_SIN 81)
139 (UNSPEC_XTRACT_FRACT 84)
140 (UNSPEC_XTRACT_EXP 85)
141 (UNSPEC_FSCALE_FRACT 86)
142 (UNSPEC_FSCALE_EXP 87)
154 (UNSPEC_SP_TLS_SET 102)
155 (UNSPEC_SP_TLS_TEST 103)
165 (UNSPEC_INSERTQI 132)
170 (UNSPEC_INSERTPS 135)
172 (UNSPEC_MOVNTDQA 137)
174 (UNSPEC_PHMINPOSUW 139)
180 (UNSPEC_PCMPESTR 144)
181 (UNSPEC_PCMPISTR 145)
184 (UNSPEC_SSE5_INTRINSIC 150)
185 (UNSPEC_SSE5_UNSIGNED_CMP 151)
186 (UNSPEC_SSE5_TRUEFALSE 152)
187 (UNSPEC_SSE5_PERMUTE 153)
189 (UNSPEC_CVTPH2PS 155)
190 (UNSPEC_CVTPS2PH 156)
194 (UNSPEC_AESENCLAST 160)
196 (UNSPEC_AESDECLAST 162)
198 (UNSPEC_AESKEYGENASSIST 164)
206 (UNSPEC_VPERMIL2F128 168)
207 (UNSPEC_MASKLOAD 169)
208 (UNSPEC_MASKSTORE 170)
214 [(UNSPECV_BLOCKAGE 0)
215 (UNSPECV_STACK_PROBE 1)
227 (UNSPECV_PROLOGUE_USE 14)
229 (UNSPECV_VZEROALL 16)
230 (UNSPECV_VZEROUPPER 17)
233 ;; Constants to represent pcomtrue/pcomfalse variants
243 ;; Constants used in the SSE5 pperm instruction
245 [(PPERM_SRC 0x00) /* copy source */
246 (PPERM_INVERT 0x20) /* invert source */
247 (PPERM_REVERSE 0x40) /* bit reverse source */
248 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
249 (PPERM_ZERO 0x80) /* all 0's */
250 (PPERM_ONES 0xa0) /* all 1's */
251 (PPERM_SIGN 0xc0) /* propagate sign bit */
252 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
253 (PPERM_SRC1 0x00) /* use first source byte */
254 (PPERM_SRC2 0x10) /* use second source byte */
257 ;; 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,
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 (if_then_else (ior (eq_attr "mode" "HI")
402 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(and (eq_attr "mode" "DI")
423 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
425 (and (eq_attr "mode" "QI")
426 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
429 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
435 ;; There are also additional prefixes in SSSE3.
436 (define_attr "prefix_extra" "" (const_int 0))
438 ;; Prefix used: original, VEX or maybe VEX.
439 (define_attr "prefix" "orig,vex,maybe_vex"
440 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
442 (const_string "orig")))
444 ;; There is a 8bit immediate for VEX.
445 (define_attr "prefix_vex_imm8" "" (const_int 0))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 (define_attr "length_vex" ""
452 (if_then_else (eq_attr "prefix_0f" "1")
453 (if_then_else (eq_attr "prefix_vex_w" "1")
454 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
455 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
456 (if_then_else (eq_attr "prefix_vex_w" "1")
457 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
458 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
460 ;; Set when modrm byte is used.
461 (define_attr "modrm" ""
462 (cond [(eq_attr "type" "str,leave")
464 (eq_attr "unit" "i387")
466 (and (eq_attr "type" "incdec")
467 (ior (match_operand:SI 1 "register_operand" "")
468 (match_operand:HI 1 "register_operand" "")))
470 (and (eq_attr "type" "push")
471 (not (match_operand 1 "memory_operand" "")))
473 (and (eq_attr "type" "pop")
474 (not (match_operand 0 "memory_operand" "")))
476 (and (eq_attr "type" "imov")
477 (ior (and (match_operand 0 "register_operand" "")
478 (match_operand 1 "immediate_operand" ""))
479 (ior (and (match_operand 0 "ax_reg_operand" "")
480 (match_operand 1 "memory_displacement_only_operand" ""))
481 (and (match_operand 0 "memory_displacement_only_operand" "")
482 (match_operand 1 "ax_reg_operand" "")))))
484 (and (eq_attr "type" "call")
485 (match_operand 0 "constant_call_address_operand" ""))
487 (and (eq_attr "type" "callv")
488 (match_operand 1 "constant_call_address_operand" ""))
493 ;; The (bounding maximum) length of an instruction in bytes.
494 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
495 ;; Later we may want to split them and compute proper length as for
497 (define_attr "length" ""
498 (cond [(eq_attr "type" "other,multi,fistp,frndint")
500 (eq_attr "type" "fcmp")
502 (eq_attr "unit" "i387")
504 (plus (attr "prefix_data16")
505 (attr "length_address")))
506 (ior (eq_attr "prefix" "vex")
507 (and (eq_attr "prefix" "maybe_vex")
508 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
509 (plus (attr "length_vex")
510 (plus (attr "prefix_vex_imm8")
512 (attr "length_address"))))]
513 (plus (plus (attr "modrm")
514 (plus (attr "prefix_0f")
515 (plus (attr "prefix_rex")
516 (plus (attr "prefix_extra")
518 (plus (attr "prefix_rep")
519 (plus (attr "prefix_data16")
520 (plus (attr "length_immediate")
521 (attr "length_address")))))))
523 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
524 ;; `store' if there is a simple memory reference therein, or `unknown'
525 ;; if the instruction is complex.
527 (define_attr "memory" "none,load,store,both,unknown"
528 (cond [(eq_attr "type" "other,multi,str")
529 (const_string "unknown")
530 (eq_attr "type" "lea,fcmov,fpspc")
531 (const_string "none")
532 (eq_attr "type" "fistp,leave")
533 (const_string "both")
534 (eq_attr "type" "frndint")
535 (const_string "load")
536 (eq_attr "type" "push")
537 (if_then_else (match_operand 1 "memory_operand" "")
538 (const_string "both")
539 (const_string "store"))
540 (eq_attr "type" "pop")
541 (if_then_else (match_operand 0 "memory_operand" "")
542 (const_string "both")
543 (const_string "load"))
544 (eq_attr "type" "setcc")
545 (if_then_else (match_operand 0 "memory_operand" "")
546 (const_string "store")
547 (const_string "none"))
548 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
549 (if_then_else (ior (match_operand 0 "memory_operand" "")
550 (match_operand 1 "memory_operand" ""))
551 (const_string "load")
552 (const_string "none"))
553 (eq_attr "type" "ibr")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "load")
556 (const_string "none"))
557 (eq_attr "type" "call")
558 (if_then_else (match_operand 0 "constant_call_address_operand" "")
559 (const_string "none")
560 (const_string "load"))
561 (eq_attr "type" "callv")
562 (if_then_else (match_operand 1 "constant_call_address_operand" "")
563 (const_string "none")
564 (const_string "load"))
565 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
566 (match_operand 1 "memory_operand" ""))
567 (const_string "both")
568 (and (match_operand 0 "memory_operand" "")
569 (match_operand 1 "memory_operand" ""))
570 (const_string "both")
571 (match_operand 0 "memory_operand" "")
572 (const_string "store")
573 (match_operand 1 "memory_operand" "")
574 (const_string "load")
576 "!alu1,negnot,ishift1,
577 imov,imovx,icmp,test,bitmanip,
579 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
580 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
581 (match_operand 2 "memory_operand" ""))
582 (const_string "load")
583 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
584 (match_operand 3 "memory_operand" ""))
585 (const_string "load")
587 (const_string "none")))
589 ;; Indicates if an instruction has both an immediate and a displacement.
591 (define_attr "imm_disp" "false,true,unknown"
592 (cond [(eq_attr "type" "other,multi")
593 (const_string "unknown")
594 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
595 (and (match_operand 0 "memory_displacement_operand" "")
596 (match_operand 1 "immediate_operand" "")))
597 (const_string "true")
598 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
599 (and (match_operand 0 "memory_displacement_operand" "")
600 (match_operand 2 "immediate_operand" "")))
601 (const_string "true")
603 (const_string "false")))
605 ;; Indicates if an FP operation has an integer source.
607 (define_attr "fp_int_src" "false,true"
608 (const_string "false"))
610 ;; Defines rounding mode of an FP operation.
612 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
613 (const_string "any"))
615 ;; Describe a user's asm statement.
616 (define_asm_attributes
617 [(set_attr "length" "128")
618 (set_attr "type" "multi")])
620 ;; All integer comparison codes.
621 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
623 ;; All floating-point comparison codes.
624 (define_code_iterator fp_cond [unordered ordered
625 uneq unge ungt unle unlt ltgt ])
627 (define_code_iterator plusminus [plus minus])
629 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
631 ;; Base name for define_insn
632 (define_code_attr plusminus_insn
633 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
634 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
636 ;; Base name for insn mnemonic.
637 (define_code_attr plusminus_mnemonic
638 [(plus "add") (ss_plus "adds") (us_plus "addus")
639 (minus "sub") (ss_minus "subs") (us_minus "subus")])
641 ;; Mark commutative operators as such in constraints.
642 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
643 (minus "") (ss_minus "") (us_minus "")])
645 ;; Mapping of signed max and min
646 (define_code_iterator smaxmin [smax smin])
648 ;; Mapping of unsigned max and min
649 (define_code_iterator umaxmin [umax umin])
651 ;; Mapping of signed/unsigned max and min
652 (define_code_iterator maxmin [smax smin umax umin])
654 ;; Base name for integer and FP insn mnemonic
655 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
656 (umax "maxu") (umin "minu")])
657 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
659 ;; Mapping of parallel logic operators
660 (define_code_iterator plogic [and ior xor])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
665 ;; Mapping of abs neg operators
666 (define_code_iterator absneg [abs neg])
668 ;; Base name for x87 insn mnemonic.
669 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
671 ;; All single word integer modes.
672 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
674 ;; Single word integer modes without QImode.
675 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
677 ;; Instruction suffix for integer modes.
678 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
680 ;; Register class for integer modes.
681 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
683 ;; Immediate operand constraint for integer modes.
684 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
686 ;; General operand predicate for integer modes.
687 (define_mode_attr general_operand
688 [(QI "general_operand")
689 (HI "general_operand")
690 (SI "general_operand")
691 (DI "x86_64_general_operand")])
693 ;; SSE and x87 SFmode and DFmode floating point modes
694 (define_mode_iterator MODEF [SF DF])
696 ;; All x87 floating point modes
697 (define_mode_iterator X87MODEF [SF DF XF])
699 ;; All integer modes handled by x87 fisttp operator.
700 (define_mode_iterator X87MODEI [HI SI DI])
702 ;; All integer modes handled by integer x87 operators.
703 (define_mode_iterator X87MODEI12 [HI SI])
705 ;; All integer modes handled by SSE cvtts?2si* operators.
706 (define_mode_iterator SSEMODEI24 [SI DI])
708 ;; SSE asm suffix for floating point modes
709 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
711 ;; SSE vector mode corresponding to a scalar mode
712 (define_mode_attr ssevecmode
713 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
715 ;; Instruction suffix for REX 64bit operators.
716 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
718 ;; This mode iterator allows :P to be used for patterns that operate on
719 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
720 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
723 ;; Scheduling descriptions
725 (include "pentium.md")
728 (include "athlon.md")
732 ;; Operand and operator predicates and constraints
734 (include "predicates.md")
735 (include "constraints.md")
738 ;; Compare instructions.
740 ;; All compare insns have expanders that save the operands away without
741 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
742 ;; after the cmp) will actually emit the cmpM.
744 (define_expand "cmpti"
745 [(set (reg:CC FLAGS_REG)
746 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
747 (match_operand:TI 1 "x86_64_general_operand" "")))]
750 if (MEM_P (operands[0]) && MEM_P (operands[1]))
751 operands[0] = force_reg (TImode, operands[0]);
752 ix86_compare_op0 = operands[0];
753 ix86_compare_op1 = operands[1];
757 (define_expand "cmpdi"
758 [(set (reg:CC FLAGS_REG)
759 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
760 (match_operand:DI 1 "x86_64_general_operand" "")))]
763 if (MEM_P (operands[0]) && MEM_P (operands[1]))
764 operands[0] = force_reg (DImode, operands[0]);
765 ix86_compare_op0 = operands[0];
766 ix86_compare_op1 = operands[1];
770 (define_expand "cmpsi"
771 [(set (reg:CC FLAGS_REG)
772 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
773 (match_operand:SI 1 "general_operand" "")))]
776 if (MEM_P (operands[0]) && MEM_P (operands[1]))
777 operands[0] = force_reg (SImode, operands[0]);
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
783 (define_expand "cmphi"
784 [(set (reg:CC FLAGS_REG)
785 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
786 (match_operand:HI 1 "general_operand" "")))]
789 if (MEM_P (operands[0]) && MEM_P (operands[1]))
790 operands[0] = force_reg (HImode, operands[0]);
791 ix86_compare_op0 = operands[0];
792 ix86_compare_op1 = operands[1];
796 (define_expand "cmpqi"
797 [(set (reg:CC FLAGS_REG)
798 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
799 (match_operand:QI 1 "general_operand" "")))]
802 if (MEM_P (operands[0]) && MEM_P (operands[1]))
803 operands[0] = force_reg (QImode, operands[0]);
804 ix86_compare_op0 = operands[0];
805 ix86_compare_op1 = operands[1];
809 (define_insn "cmpdi_ccno_1_rex64"
810 [(set (reg FLAGS_REG)
811 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
812 (match_operand:DI 1 "const0_operand" "")))]
813 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
816 cmp{q}\t{%1, %0|%0, %1}"
817 [(set_attr "type" "test,icmp")
818 (set_attr "length_immediate" "0,1")
819 (set_attr "mode" "DI")])
821 (define_insn "*cmpdi_minus_1_rex64"
822 [(set (reg FLAGS_REG)
823 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
824 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
826 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
827 "cmp{q}\t{%1, %0|%0, %1}"
828 [(set_attr "type" "icmp")
829 (set_attr "mode" "DI")])
831 (define_expand "cmpdi_1_rex64"
832 [(set (reg:CC FLAGS_REG)
833 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
834 (match_operand:DI 1 "general_operand" "")))]
838 (define_insn "cmpdi_1_insn_rex64"
839 [(set (reg FLAGS_REG)
840 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
841 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
842 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
843 "cmp{q}\t{%1, %0|%0, %1}"
844 [(set_attr "type" "icmp")
845 (set_attr "mode" "DI")])
848 (define_insn "*cmpsi_ccno_1"
849 [(set (reg FLAGS_REG)
850 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
851 (match_operand:SI 1 "const0_operand" "")))]
852 "ix86_match_ccmode (insn, CCNOmode)"
855 cmp{l}\t{%1, %0|%0, %1}"
856 [(set_attr "type" "test,icmp")
857 (set_attr "length_immediate" "0,1")
858 (set_attr "mode" "SI")])
860 (define_insn "*cmpsi_minus_1"
861 [(set (reg FLAGS_REG)
862 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
863 (match_operand:SI 1 "general_operand" "ri,mr"))
865 "ix86_match_ccmode (insn, CCGOCmode)"
866 "cmp{l}\t{%1, %0|%0, %1}"
867 [(set_attr "type" "icmp")
868 (set_attr "mode" "SI")])
870 (define_expand "cmpsi_1"
871 [(set (reg:CC FLAGS_REG)
872 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
873 (match_operand:SI 1 "general_operand" "")))]
877 (define_insn "*cmpsi_1_insn"
878 [(set (reg FLAGS_REG)
879 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
880 (match_operand:SI 1 "general_operand" "ri,mr")))]
881 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
882 && ix86_match_ccmode (insn, CCmode)"
883 "cmp{l}\t{%1, %0|%0, %1}"
884 [(set_attr "type" "icmp")
885 (set_attr "mode" "SI")])
887 (define_insn "*cmphi_ccno_1"
888 [(set (reg FLAGS_REG)
889 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
890 (match_operand:HI 1 "const0_operand" "")))]
891 "ix86_match_ccmode (insn, CCNOmode)"
894 cmp{w}\t{%1, %0|%0, %1}"
895 [(set_attr "type" "test,icmp")
896 (set_attr "length_immediate" "0,1")
897 (set_attr "mode" "HI")])
899 (define_insn "*cmphi_minus_1"
900 [(set (reg FLAGS_REG)
901 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
902 (match_operand:HI 1 "general_operand" "rn,mr"))
904 "ix86_match_ccmode (insn, CCGOCmode)"
905 "cmp{w}\t{%1, %0|%0, %1}"
906 [(set_attr "type" "icmp")
907 (set_attr "mode" "HI")])
909 (define_insn "*cmphi_1"
910 [(set (reg FLAGS_REG)
911 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
912 (match_operand:HI 1 "general_operand" "rn,mr")))]
913 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
914 && ix86_match_ccmode (insn, CCmode)"
915 "cmp{w}\t{%1, %0|%0, %1}"
916 [(set_attr "type" "icmp")
917 (set_attr "mode" "HI")])
919 (define_insn "*cmpqi_ccno_1"
920 [(set (reg FLAGS_REG)
921 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
922 (match_operand:QI 1 "const0_operand" "")))]
923 "ix86_match_ccmode (insn, CCNOmode)"
926 cmp{b}\t{$0, %0|%0, 0}"
927 [(set_attr "type" "test,icmp")
928 (set_attr "length_immediate" "0,1")
929 (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_1"
932 [(set (reg FLAGS_REG)
933 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
934 (match_operand:QI 1 "general_operand" "qn,mq")))]
935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
936 && ix86_match_ccmode (insn, CCmode)"
937 "cmp{b}\t{%1, %0|%0, %1}"
938 [(set_attr "type" "icmp")
939 (set_attr "mode" "QI")])
941 (define_insn "*cmpqi_minus_1"
942 [(set (reg FLAGS_REG)
943 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
944 (match_operand:QI 1 "general_operand" "qn,mq"))
946 "ix86_match_ccmode (insn, CCGOCmode)"
947 "cmp{b}\t{%1, %0|%0, %1}"
948 [(set_attr "type" "icmp")
949 (set_attr "mode" "QI")])
951 (define_insn "*cmpqi_ext_1"
952 [(set (reg FLAGS_REG)
954 (match_operand:QI 0 "general_operand" "Qm")
957 (match_operand 1 "ext_register_operand" "Q")
960 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
961 "cmp{b}\t{%h1, %0|%0, %h1}"
962 [(set_attr "type" "icmp")
963 (set_attr "mode" "QI")])
965 (define_insn "*cmpqi_ext_1_rex64"
966 [(set (reg FLAGS_REG)
968 (match_operand:QI 0 "register_operand" "Q")
971 (match_operand 1 "ext_register_operand" "Q")
974 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
975 "cmp{b}\t{%h1, %0|%0, %h1}"
976 [(set_attr "type" "icmp")
977 (set_attr "mode" "QI")])
979 (define_insn "*cmpqi_ext_2"
980 [(set (reg FLAGS_REG)
984 (match_operand 0 "ext_register_operand" "Q")
987 (match_operand:QI 1 "const0_operand" "")))]
988 "ix86_match_ccmode (insn, CCNOmode)"
990 [(set_attr "type" "test")
991 (set_attr "length_immediate" "0")
992 (set_attr "mode" "QI")])
994 (define_expand "cmpqi_ext_3"
995 [(set (reg:CC FLAGS_REG)
999 (match_operand 0 "ext_register_operand" "")
1002 (match_operand:QI 1 "general_operand" "")))]
1006 (define_insn "cmpqi_ext_3_insn"
1007 [(set (reg FLAGS_REG)
1011 (match_operand 0 "ext_register_operand" "Q")
1014 (match_operand:QI 1 "general_operand" "Qmn")))]
1015 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016 "cmp{b}\t{%1, %h0|%h0, %1}"
1017 [(set_attr "type" "icmp")
1018 (set_attr "mode" "QI")])
1020 (define_insn "cmpqi_ext_3_insn_rex64"
1021 [(set (reg FLAGS_REG)
1025 (match_operand 0 "ext_register_operand" "Q")
1028 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1029 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1030 "cmp{b}\t{%1, %h0|%h0, %1}"
1031 [(set_attr "type" "icmp")
1032 (set_attr "mode" "QI")])
1034 (define_insn "*cmpqi_ext_4"
1035 [(set (reg FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "Q")
1044 (match_operand 1 "ext_register_operand" "Q")
1046 (const_int 8)) 0)))]
1047 "ix86_match_ccmode (insn, CCmode)"
1048 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "QI")])
1052 ;; These implement float point compares.
1053 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1054 ;; which would allow mix and match FP modes on the compares. Which is what
1055 ;; the old patterns did, but with many more of them.
1057 (define_expand "cmpxf"
1058 [(set (reg:CC FLAGS_REG)
1059 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1060 (match_operand:XF 1 "nonmemory_operand" "")))]
1063 ix86_compare_op0 = operands[0];
1064 ix86_compare_op1 = operands[1];
1068 (define_expand "cmp<mode>"
1069 [(set (reg:CC FLAGS_REG)
1070 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1071 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1072 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074 ix86_compare_op0 = operands[0];
1075 ix86_compare_op1 = operands[1];
1079 ;; FP compares, step 1:
1080 ;; Set the FP condition codes.
1082 ;; CCFPmode compare with exceptions
1083 ;; CCFPUmode compare with no exceptions
1085 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1086 ;; used to manage the reg stack popping would not be preserved.
1088 (define_insn "*cmpfp_0"
1089 [(set (match_operand:HI 0 "register_operand" "=a")
1092 (match_operand 1 "register_operand" "f")
1093 (match_operand 2 "const0_operand" ""))]
1095 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097 "* return output_fp_compare (insn, operands, 0, 0);"
1098 [(set_attr "type" "multi")
1099 (set_attr "unit" "i387")
1101 (cond [(match_operand:SF 1 "" "")
1103 (match_operand:DF 1 "" "")
1106 (const_string "XF")))])
1108 (define_insn_and_split "*cmpfp_0_cc"
1109 [(set (reg:CCFP FLAGS_REG)
1111 (match_operand 1 "register_operand" "f")
1112 (match_operand 2 "const0_operand" "")))
1113 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1115 && TARGET_SAHF && !TARGET_CMOVE
1116 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1118 "&& reload_completed"
1121 [(compare:CCFP (match_dup 1)(match_dup 2))]
1123 (set (reg:CC FLAGS_REG)
1124 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1126 [(set_attr "type" "multi")
1127 (set_attr "unit" "i387")
1129 (cond [(match_operand:SF 1 "" "")
1131 (match_operand:DF 1 "" "")
1134 (const_string "XF")))])
1136 (define_insn "*cmpfp_xf"
1137 [(set (match_operand:HI 0 "register_operand" "=a")
1140 (match_operand:XF 1 "register_operand" "f")
1141 (match_operand:XF 2 "register_operand" "f"))]
1144 "* return output_fp_compare (insn, operands, 0, 0);"
1145 [(set_attr "type" "multi")
1146 (set_attr "unit" "i387")
1147 (set_attr "mode" "XF")])
1149 (define_insn_and_split "*cmpfp_xf_cc"
1150 [(set (reg:CCFP FLAGS_REG)
1152 (match_operand:XF 1 "register_operand" "f")
1153 (match_operand:XF 2 "register_operand" "f")))
1154 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1156 && TARGET_SAHF && !TARGET_CMOVE"
1158 "&& reload_completed"
1161 [(compare:CCFP (match_dup 1)(match_dup 2))]
1163 (set (reg:CC FLAGS_REG)
1164 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1166 [(set_attr "type" "multi")
1167 (set_attr "unit" "i387")
1168 (set_attr "mode" "XF")])
1170 (define_insn "*cmpfp_<mode>"
1171 [(set (match_operand:HI 0 "register_operand" "=a")
1174 (match_operand:MODEF 1 "register_operand" "f")
1175 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1178 "* return output_fp_compare (insn, operands, 0, 0);"
1179 [(set_attr "type" "multi")
1180 (set_attr "unit" "i387")
1181 (set_attr "mode" "<MODE>")])
1183 (define_insn_and_split "*cmpfp_<mode>_cc"
1184 [(set (reg:CCFP FLAGS_REG)
1186 (match_operand:MODEF 1 "register_operand" "f")
1187 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1188 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1190 && TARGET_SAHF && !TARGET_CMOVE"
1192 "&& reload_completed"
1195 [(compare:CCFP (match_dup 1)(match_dup 2))]
1197 (set (reg:CC FLAGS_REG)
1198 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1200 [(set_attr "type" "multi")
1201 (set_attr "unit" "i387")
1202 (set_attr "mode" "<MODE>")])
1204 (define_insn "*cmpfp_u"
1205 [(set (match_operand:HI 0 "register_operand" "=a")
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "register_operand" "f"))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213 "* return output_fp_compare (insn, operands, 0, 1);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_u_cc"
1225 [(set (reg:CCFPU FLAGS_REG)
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "register_operand" "f")))
1229 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && TARGET_SAHF && !TARGET_CMOVE
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "&& reload_completed"
1237 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1239 (set (reg:CC FLAGS_REG)
1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1242 [(set_attr "type" "multi")
1243 (set_attr "unit" "i387")
1245 (cond [(match_operand:SF 1 "" "")
1247 (match_operand:DF 1 "" "")
1250 (const_string "XF")))])
1252 (define_insn "*cmpfp_<mode>"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operator 3 "float_operator"
1258 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1262 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1263 "* return output_fp_compare (insn, operands, 0, 0);"
1264 [(set_attr "type" "multi")
1265 (set_attr "unit" "i387")
1266 (set_attr "fp_int_src" "true")
1267 (set_attr "mode" "<MODE>")])
1269 (define_insn_and_split "*cmpfp_<mode>_cc"
1270 [(set (reg:CCFP FLAGS_REG)
1272 (match_operand 1 "register_operand" "f")
1273 (match_operator 3 "float_operator"
1274 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1275 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1276 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1277 && TARGET_SAHF && !TARGET_CMOVE
1278 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1279 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1281 "&& reload_completed"
1286 (match_op_dup 3 [(match_dup 2)]))]
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "fp_int_src" "true")
1294 (set_attr "mode" "<MODE>")])
1296 ;; FP compares, step 2
1297 ;; Move the fpsw to ax.
1299 (define_insn "x86_fnstsw_1"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1304 [(set_attr "length" "2")
1305 (set_attr "mode" "SI")
1306 (set_attr "unit" "i387")])
1308 ;; FP compares, step 3
1309 ;; Get ax into flags, general case.
1311 (define_insn "x86_sahf_1"
1312 [(set (reg:CC FLAGS_REG)
1313 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1317 #ifdef HAVE_AS_IX86_SAHF
1320 return ".byte\t0x9e";
1323 [(set_attr "length" "1")
1324 (set_attr "athlon_decode" "vector")
1325 (set_attr "amdfam10_decode" "direct")
1326 (set_attr "mode" "SI")])
1328 ;; Pentium Pro can do steps 1 through 3 in one go.
1329 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1330 (define_insn "*cmpfp_i_mixed"
1331 [(set (reg:CCFP FLAGS_REG)
1332 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1333 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1334 "TARGET_MIX_SSE_I387
1335 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1336 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1337 "* return output_fp_compare (insn, operands, 1, 0);"
1338 [(set_attr "type" "fcmp,ssecomi")
1339 (set_attr "prefix" "orig,maybe_vex")
1341 (if_then_else (match_operand:SF 1 "" "")
1343 (const_string "DF")))
1344 (set_attr "athlon_decode" "vector")
1345 (set_attr "amdfam10_decode" "direct")])
1347 (define_insn "*cmpfp_i_sse"
1348 [(set (reg:CCFP FLAGS_REG)
1349 (compare:CCFP (match_operand 0 "register_operand" "x")
1350 (match_operand 1 "nonimmediate_operand" "xm")))]
1352 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1353 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1354 "* return output_fp_compare (insn, operands, 1, 0);"
1355 [(set_attr "type" "ssecomi")
1356 (set_attr "prefix" "maybe_vex")
1358 (if_then_else (match_operand:SF 1 "" "")
1360 (const_string "DF")))
1361 (set_attr "athlon_decode" "vector")
1362 (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_i_i387"
1365 [(set (reg:CCFP FLAGS_REG)
1366 (compare:CCFP (match_operand 0 "register_operand" "f")
1367 (match_operand 1 "register_operand" "f")))]
1368 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1370 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1371 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372 "* return output_fp_compare (insn, operands, 1, 0);"
1373 [(set_attr "type" "fcmp")
1375 (cond [(match_operand:SF 1 "" "")
1377 (match_operand:DF 1 "" "")
1380 (const_string "XF")))
1381 (set_attr "athlon_decode" "vector")
1382 (set_attr "amdfam10_decode" "direct")])
1384 (define_insn "*cmpfp_iu_mixed"
1385 [(set (reg:CCFPU FLAGS_REG)
1386 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1387 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1388 "TARGET_MIX_SSE_I387
1389 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1390 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1391 "* return output_fp_compare (insn, operands, 1, 1);"
1392 [(set_attr "type" "fcmp,ssecomi")
1393 (set_attr "prefix" "orig,maybe_vex")
1395 (if_then_else (match_operand:SF 1 "" "")
1397 (const_string "DF")))
1398 (set_attr "athlon_decode" "vector")
1399 (set_attr "amdfam10_decode" "direct")])
1401 (define_insn "*cmpfp_iu_sse"
1402 [(set (reg:CCFPU FLAGS_REG)
1403 (compare:CCFPU (match_operand 0 "register_operand" "x")
1404 (match_operand 1 "nonimmediate_operand" "xm")))]
1406 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1407 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1408 "* return output_fp_compare (insn, operands, 1, 1);"
1409 [(set_attr "type" "ssecomi")
1410 (set_attr "prefix" "maybe_vex")
1412 (if_then_else (match_operand:SF 1 "" "")
1414 (const_string "DF")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_iu_387"
1419 [(set (reg:CCFPU FLAGS_REG)
1420 (compare:CCFPU (match_operand 0 "register_operand" "f")
1421 (match_operand 1 "register_operand" "f")))]
1422 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1424 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1425 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426 "* return output_fp_compare (insn, operands, 1, 1);"
1427 [(set_attr "type" "fcmp")
1429 (cond [(match_operand:SF 1 "" "")
1431 (match_operand:DF 1 "" "")
1434 (const_string "XF")))
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")])
1438 ;; Move instructions.
1440 ;; General case of fullword move.
1442 (define_expand "movsi"
1443 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1444 (match_operand:SI 1 "general_operand" ""))]
1446 "ix86_expand_move (SImode, operands); DONE;")
1448 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1451 ;; %%% We don't use a post-inc memory reference because x86 is not a
1452 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1453 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1454 ;; targets without our curiosities, and it is just as easy to represent
1455 ;; this differently.
1457 (define_insn "*pushsi2"
1458 [(set (match_operand:SI 0 "push_operand" "=<")
1459 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushsi2_rex64"
1467 [(set (match_operand:SI 0 "push_operand" "=X")
1468 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "SI")])
1474 (define_insn "*pushsi2_prologue"
1475 [(set (match_operand:SI 0 "push_operand" "=<")
1476 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1477 (clobber (mem:BLK (scratch)))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1483 (define_insn "*popsi1_epilogue"
1484 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1485 (mem:SI (reg:SI SP_REG)))
1486 (set (reg:SI SP_REG)
1487 (plus:SI (reg:SI SP_REG) (const_int 4)))
1488 (clobber (mem:BLK (scratch)))]
1491 [(set_attr "type" "pop")
1492 (set_attr "mode" "SI")])
1494 (define_insn "popsi1"
1495 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1496 (mem:SI (reg:SI SP_REG)))
1497 (set (reg:SI SP_REG)
1498 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1501 [(set_attr "type" "pop")
1502 (set_attr "mode" "SI")])
1504 (define_insn "*movsi_xor"
1505 [(set (match_operand:SI 0 "register_operand" "=r")
1506 (match_operand:SI 1 "const0_operand" ""))
1507 (clobber (reg:CC FLAGS_REG))]
1510 [(set_attr "type" "alu1")
1511 (set_attr "mode" "SI")
1512 (set_attr "length_immediate" "0")])
1514 (define_insn "*movsi_or"
1515 [(set (match_operand:SI 0 "register_operand" "=r")
1516 (match_operand:SI 1 "immediate_operand" "i"))
1517 (clobber (reg:CC FLAGS_REG))]
1519 && operands[1] == constm1_rtx"
1521 operands[1] = constm1_rtx;
1522 return "or{l}\t{%1, %0|%0, %1}";
1524 [(set_attr "type" "alu1")
1525 (set_attr "mode" "SI")
1526 (set_attr "length_immediate" "1")])
1528 (define_insn "*movsi_1"
1529 [(set (match_operand:SI 0 "nonimmediate_operand"
1530 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1531 (match_operand:SI 1 "general_operand"
1532 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1533 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1535 switch (get_attr_type (insn))
1538 if (get_attr_mode (insn) == MODE_TI)
1539 return "%vpxor\t%0, %d0";
1540 return "%vxorps\t%0, %d0";
1543 switch (get_attr_mode (insn))
1546 return "%vmovdqa\t{%1, %0|%0, %1}";
1548 return "%vmovaps\t{%1, %0|%0, %1}";
1550 return "%vmovd\t{%1, %0|%0, %1}";
1552 return "%vmovss\t{%1, %0|%0, %1}";
1558 return "pxor\t%0, %0";
1561 if (get_attr_mode (insn) == MODE_DI)
1562 return "movq\t{%1, %0|%0, %1}";
1563 return "movd\t{%1, %0|%0, %1}";
1566 return "lea{l}\t{%1, %0|%0, %1}";
1569 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1570 return "mov{l}\t{%1, %0|%0, %1}";
1574 (cond [(eq_attr "alternative" "2")
1575 (const_string "mmx")
1576 (eq_attr "alternative" "3,4,5")
1577 (const_string "mmxmov")
1578 (eq_attr "alternative" "6")
1579 (const_string "sselog1")
1580 (eq_attr "alternative" "7,8,9,10,11")
1581 (const_string "ssemov")
1582 (match_operand:DI 1 "pic_32bit_operand" "")
1583 (const_string "lea")
1585 (const_string "imov")))
1586 (set (attr "prefix")
1587 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1588 (const_string "orig")
1589 (const_string "maybe_vex")))
1591 (cond [(eq_attr "alternative" "2,3")
1593 (eq_attr "alternative" "6,7")
1595 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1596 (const_string "V4SF")
1597 (const_string "TI"))
1598 (and (eq_attr "alternative" "8,9,10,11")
1599 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1602 (const_string "SI")))])
1604 ;; Stores and loads of ax to arbitrary constant address.
1605 ;; We fake an second form of instruction to force reload to load address
1606 ;; into register when rax is not available
1607 (define_insn "*movabssi_1_rex64"
1608 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1609 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1610 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1612 movabs{l}\t{%1, %P0|%P0, %1}
1613 mov{l}\t{%1, %a0|%a0, %1}"
1614 [(set_attr "type" "imov")
1615 (set_attr "modrm" "0,*")
1616 (set_attr "length_address" "8,0")
1617 (set_attr "length_immediate" "0,*")
1618 (set_attr "memory" "store")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*movabssi_2_rex64"
1622 [(set (match_operand:SI 0 "register_operand" "=a,r")
1623 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1624 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1626 movabs{l}\t{%P1, %0|%0, %P1}
1627 mov{l}\t{%a1, %0|%0, %a1}"
1628 [(set_attr "type" "imov")
1629 (set_attr "modrm" "0,*")
1630 (set_attr "length_address" "8,0")
1631 (set_attr "length_immediate" "0")
1632 (set_attr "memory" "load")
1633 (set_attr "mode" "SI")])
1635 (define_insn "*swapsi"
1636 [(set (match_operand:SI 0 "register_operand" "+r")
1637 (match_operand:SI 1 "register_operand" "+r"))
1642 [(set_attr "type" "imov")
1643 (set_attr "mode" "SI")
1644 (set_attr "pent_pair" "np")
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "double")])
1648 (define_expand "movhi"
1649 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1650 (match_operand:HI 1 "general_operand" ""))]
1652 "ix86_expand_move (HImode, operands); DONE;")
1654 (define_insn "*pushhi2"
1655 [(set (match_operand:HI 0 "push_operand" "=X")
1656 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1659 [(set_attr "type" "push")
1660 (set_attr "mode" "SI")])
1662 ;; For 64BIT abi we always round up to 8 bytes.
1663 (define_insn "*pushhi2_rex64"
1664 [(set (match_operand:HI 0 "push_operand" "=X")
1665 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1668 [(set_attr "type" "push")
1669 (set_attr "mode" "DI")])
1671 (define_insn "*movhi_1"
1672 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1673 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1674 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1676 switch (get_attr_type (insn))
1679 /* movzwl is faster than movw on p2 due to partial word stalls,
1680 though not as fast as an aligned movl. */
1681 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1683 if (get_attr_mode (insn) == MODE_SI)
1684 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1686 return "mov{w}\t{%1, %0|%0, %1}";
1690 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1691 (const_string "imov")
1692 (and (eq_attr "alternative" "0")
1693 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1695 (eq (symbol_ref "TARGET_HIMODE_MATH")
1697 (const_string "imov")
1698 (and (eq_attr "alternative" "1,2")
1699 (match_operand:HI 1 "aligned_operand" ""))
1700 (const_string "imov")
1701 (and (ne (symbol_ref "TARGET_MOVX")
1703 (eq_attr "alternative" "0,2"))
1704 (const_string "imovx")
1706 (const_string "imov")))
1708 (cond [(eq_attr "type" "imovx")
1710 (and (eq_attr "alternative" "1,2")
1711 (match_operand:HI 1 "aligned_operand" ""))
1713 (and (eq_attr "alternative" "0")
1714 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1716 (eq (symbol_ref "TARGET_HIMODE_MATH")
1720 (const_string "HI")))])
1722 ;; Stores and loads of ax to arbitrary constant address.
1723 ;; We fake an second form of instruction to force reload to load address
1724 ;; into register when rax is not available
1725 (define_insn "*movabshi_1_rex64"
1726 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1727 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1728 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1730 movabs{w}\t{%1, %P0|%P0, %1}
1731 mov{w}\t{%1, %a0|%a0, %1}"
1732 [(set_attr "type" "imov")
1733 (set_attr "modrm" "0,*")
1734 (set_attr "length_address" "8,0")
1735 (set_attr "length_immediate" "0,*")
1736 (set_attr "memory" "store")
1737 (set_attr "mode" "HI")])
1739 (define_insn "*movabshi_2_rex64"
1740 [(set (match_operand:HI 0 "register_operand" "=a,r")
1741 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1742 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1744 movabs{w}\t{%P1, %0|%0, %P1}
1745 mov{w}\t{%a1, %0|%0, %a1}"
1746 [(set_attr "type" "imov")
1747 (set_attr "modrm" "0,*")
1748 (set_attr "length_address" "8,0")
1749 (set_attr "length_immediate" "0")
1750 (set_attr "memory" "load")
1751 (set_attr "mode" "HI")])
1753 (define_insn "*swaphi_1"
1754 [(set (match_operand:HI 0 "register_operand" "+r")
1755 (match_operand:HI 1 "register_operand" "+r"))
1758 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1760 [(set_attr "type" "imov")
1761 (set_attr "mode" "SI")
1762 (set_attr "pent_pair" "np")
1763 (set_attr "athlon_decode" "vector")
1764 (set_attr "amdfam10_decode" "double")])
1766 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1767 (define_insn "*swaphi_2"
1768 [(set (match_operand:HI 0 "register_operand" "+r")
1769 (match_operand:HI 1 "register_operand" "+r"))
1772 "TARGET_PARTIAL_REG_STALL"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "HI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")])
1779 (define_expand "movstricthi"
1780 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1781 (match_operand:HI 1 "general_operand" ""))]
1784 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1786 /* Don't generate memory->memory moves, go through a register */
1787 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1788 operands[1] = force_reg (HImode, operands[1]);
1791 (define_insn "*movstricthi_1"
1792 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1793 (match_operand:HI 1 "general_operand" "rn,m"))]
1794 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796 "mov{w}\t{%1, %0|%0, %1}"
1797 [(set_attr "type" "imov")
1798 (set_attr "mode" "HI")])
1800 (define_insn "*movstricthi_xor"
1801 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1802 (match_operand:HI 1 "const0_operand" ""))
1803 (clobber (reg:CC FLAGS_REG))]
1806 [(set_attr "type" "alu1")
1807 (set_attr "mode" "HI")
1808 (set_attr "length_immediate" "0")])
1810 (define_expand "movqi"
1811 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1812 (match_operand:QI 1 "general_operand" ""))]
1814 "ix86_expand_move (QImode, operands); DONE;")
1816 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1817 ;; "push a byte". But actually we use pushl, which has the effect
1818 ;; of rounding the amount pushed up to a word.
1820 (define_insn "*pushqi2"
1821 [(set (match_operand:QI 0 "push_operand" "=X")
1822 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1825 [(set_attr "type" "push")
1826 (set_attr "mode" "SI")])
1828 ;; For 64BIT abi we always round up to 8 bytes.
1829 (define_insn "*pushqi2_rex64"
1830 [(set (match_operand:QI 0 "push_operand" "=X")
1831 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1834 [(set_attr "type" "push")
1835 (set_attr "mode" "DI")])
1837 ;; Situation is quite tricky about when to choose full sized (SImode) move
1838 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1839 ;; partial register dependency machines (such as AMD Athlon), where QImode
1840 ;; moves issue extra dependency and for partial register stalls machines
1841 ;; that don't use QImode patterns (and QImode move cause stall on the next
1844 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1845 ;; register stall machines with, where we use QImode instructions, since
1846 ;; partial register stall can be caused there. Then we use movzx.
1847 (define_insn "*movqi_1"
1848 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1849 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1850 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 switch (get_attr_type (insn))
1855 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1856 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1858 if (get_attr_mode (insn) == MODE_SI)
1859 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1861 return "mov{b}\t{%1, %0|%0, %1}";
1865 (cond [(and (eq_attr "alternative" "5")
1866 (not (match_operand:QI 1 "aligned_operand" "")))
1867 (const_string "imovx")
1868 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1869 (const_string "imov")
1870 (and (eq_attr "alternative" "3")
1871 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1873 (eq (symbol_ref "TARGET_QIMODE_MATH")
1875 (const_string "imov")
1876 (eq_attr "alternative" "3,5")
1877 (const_string "imovx")
1878 (and (ne (symbol_ref "TARGET_MOVX")
1880 (eq_attr "alternative" "2"))
1881 (const_string "imovx")
1883 (const_string "imov")))
1885 (cond [(eq_attr "alternative" "3,4,5")
1887 (eq_attr "alternative" "6")
1889 (eq_attr "type" "imovx")
1891 (and (eq_attr "type" "imov")
1892 (and (eq_attr "alternative" "0,1")
1893 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1895 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1897 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1900 ;; Avoid partial register stalls when not using QImode arithmetic
1901 (and (eq_attr "type" "imov")
1902 (and (eq_attr "alternative" "0,1")
1903 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1905 (eq (symbol_ref "TARGET_QIMODE_MATH")
1909 (const_string "QI")))])
1911 (define_insn "*swapqi_1"
1912 [(set (match_operand:QI 0 "register_operand" "+r")
1913 (match_operand:QI 1 "register_operand" "+r"))
1916 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1918 [(set_attr "type" "imov")
1919 (set_attr "mode" "SI")
1920 (set_attr "pent_pair" "np")
1921 (set_attr "athlon_decode" "vector")
1922 (set_attr "amdfam10_decode" "vector")])
1924 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1925 (define_insn "*swapqi_2"
1926 [(set (match_operand:QI 0 "register_operand" "+q")
1927 (match_operand:QI 1 "register_operand" "+q"))
1930 "TARGET_PARTIAL_REG_STALL"
1932 [(set_attr "type" "imov")
1933 (set_attr "mode" "QI")
1934 (set_attr "pent_pair" "np")
1935 (set_attr "athlon_decode" "vector")])
1937 (define_expand "movstrictqi"
1938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1939 (match_operand:QI 1 "general_operand" ""))]
1942 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1944 /* Don't generate memory->memory moves, go through a register. */
1945 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1946 operands[1] = force_reg (QImode, operands[1]);
1949 (define_insn "*movstrictqi_1"
1950 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1951 (match_operand:QI 1 "general_operand" "*qn,m"))]
1952 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1953 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1954 "mov{b}\t{%1, %0|%0, %1}"
1955 [(set_attr "type" "imov")
1956 (set_attr "mode" "QI")])
1958 (define_insn "*movstrictqi_xor"
1959 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1960 (match_operand:QI 1 "const0_operand" ""))
1961 (clobber (reg:CC FLAGS_REG))]
1964 [(set_attr "type" "alu1")
1965 (set_attr "mode" "QI")
1966 (set_attr "length_immediate" "0")])
1968 (define_insn "*movsi_extv_1"
1969 [(set (match_operand:SI 0 "register_operand" "=R")
1970 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1974 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1975 [(set_attr "type" "imovx")
1976 (set_attr "mode" "SI")])
1978 (define_insn "*movhi_extv_1"
1979 [(set (match_operand:HI 0 "register_operand" "=R")
1980 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1984 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1985 [(set_attr "type" "imovx")
1986 (set_attr "mode" "SI")])
1988 (define_insn "*movqi_extv_1"
1989 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1990 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1995 switch (get_attr_type (insn))
1998 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2000 return "mov{b}\t{%h1, %0|%0, %h1}";
2004 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2005 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2006 (ne (symbol_ref "TARGET_MOVX")
2008 (const_string "imovx")
2009 (const_string "imov")))
2011 (if_then_else (eq_attr "type" "imovx")
2013 (const_string "QI")))])
2015 (define_insn "*movqi_extv_1_rex64"
2016 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2017 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2022 switch (get_attr_type (insn))
2025 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2027 return "mov{b}\t{%h1, %0|%0, %h1}";
2031 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2032 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2033 (ne (symbol_ref "TARGET_MOVX")
2035 (const_string "imovx")
2036 (const_string "imov")))
2038 (if_then_else (eq_attr "type" "imovx")
2040 (const_string "QI")))])
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsqi_1_rex64"
2046 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2048 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2050 movabs{b}\t{%1, %P0|%P0, %1}
2051 mov{b}\t{%1, %a0|%a0, %1}"
2052 [(set_attr "type" "imov")
2053 (set_attr "modrm" "0,*")
2054 (set_attr "length_address" "8,0")
2055 (set_attr "length_immediate" "0,*")
2056 (set_attr "memory" "store")
2057 (set_attr "mode" "QI")])
2059 (define_insn "*movabsqi_2_rex64"
2060 [(set (match_operand:QI 0 "register_operand" "=a,r")
2061 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2064 movabs{b}\t{%P1, %0|%0, %P1}
2065 mov{b}\t{%a1, %0|%0, %a1}"
2066 [(set_attr "type" "imov")
2067 (set_attr "modrm" "0,*")
2068 (set_attr "length_address" "8,0")
2069 (set_attr "length_immediate" "0")
2070 (set_attr "memory" "load")
2071 (set_attr "mode" "QI")])
2073 (define_insn "*movdi_extzv_1"
2074 [(set (match_operand:DI 0 "register_operand" "=R")
2075 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2079 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2080 [(set_attr "type" "imovx")
2081 (set_attr "mode" "DI")])
2083 (define_insn "*movsi_extzv_1"
2084 [(set (match_operand:SI 0 "register_operand" "=R")
2085 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2089 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2090 [(set_attr "type" "imovx")
2091 (set_attr "mode" "SI")])
2093 (define_insn "*movqi_extzv_2"
2094 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2095 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2100 switch (get_attr_type (insn))
2103 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2105 return "mov{b}\t{%h1, %0|%0, %h1}";
2109 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2110 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2111 (ne (symbol_ref "TARGET_MOVX")
2113 (const_string "imovx")
2114 (const_string "imov")))
2116 (if_then_else (eq_attr "type" "imovx")
2118 (const_string "QI")))])
2120 (define_insn "*movqi_extzv_2_rex64"
2121 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2122 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2127 switch (get_attr_type (insn))
2130 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2132 return "mov{b}\t{%h1, %0|%0, %h1}";
2136 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2137 (ne (symbol_ref "TARGET_MOVX")
2139 (const_string "imovx")
2140 (const_string "imov")))
2142 (if_then_else (eq_attr "type" "imovx")
2144 (const_string "QI")))])
2146 (define_insn "movsi_insv_1"
2147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2150 (match_operand:SI 1 "general_operand" "Qmn"))]
2152 "mov{b}\t{%b1, %h0|%h0, %b1}"
2153 [(set_attr "type" "imov")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movsi_insv_1_rex64"
2157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2160 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2162 "mov{b}\t{%b1, %h0|%h0, %b1}"
2163 [(set_attr "type" "imov")
2164 (set_attr "mode" "QI")])
2166 (define_insn "movdi_insv_1_rex64"
2167 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2170 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2172 "mov{b}\t{%b1, %h0|%h0, %b1}"
2173 [(set_attr "type" "imov")
2174 (set_attr "mode" "QI")])
2176 (define_insn "*movqi_insv_2"
2177 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2180 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2183 "mov{b}\t{%h1, %h0|%h0, %h1}"
2184 [(set_attr "type" "imov")
2185 (set_attr "mode" "QI")])
2187 (define_expand "movdi"
2188 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2191 "ix86_expand_move (DImode, operands); DONE;")
2193 (define_insn "*pushdi"
2194 [(set (match_operand:DI 0 "push_operand" "=<")
2195 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2199 (define_insn "*pushdi2_rex64"
2200 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2201 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2206 [(set_attr "type" "push,multi")
2207 (set_attr "mode" "DI")])
2209 ;; Convert impossible pushes of immediate to existing instructions.
2210 ;; First try to get scratch register and go through it. In case this
2211 ;; fails, push sign extended lower part first and then overwrite
2212 ;; upper part by 32bit move.
2214 [(match_scratch:DI 2 "r")
2215 (set (match_operand:DI 0 "push_operand" "")
2216 (match_operand:DI 1 "immediate_operand" ""))]
2217 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2218 && !x86_64_immediate_operand (operands[1], DImode)"
2219 [(set (match_dup 2) (match_dup 1))
2220 (set (match_dup 0) (match_dup 2))]
2223 ;; We need to define this as both peepholer and splitter for case
2224 ;; peephole2 pass is not run.
2225 ;; "&& 1" is needed to keep it from matching the previous pattern.
2227 [(set (match_operand:DI 0 "push_operand" "")
2228 (match_operand:DI 1 "immediate_operand" ""))]
2229 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2230 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2231 [(set (match_dup 0) (match_dup 1))
2232 (set (match_dup 2) (match_dup 3))]
2233 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2234 operands[1] = gen_lowpart (DImode, operands[2]);
2235 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2240 [(set (match_operand:DI 0 "push_operand" "")
2241 (match_operand:DI 1 "immediate_operand" ""))]
2242 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2243 ? epilogue_completed : reload_completed)
2244 && !symbolic_operand (operands[1], DImode)
2245 && !x86_64_immediate_operand (operands[1], DImode)"
2246 [(set (match_dup 0) (match_dup 1))
2247 (set (match_dup 2) (match_dup 3))]
2248 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2249 operands[1] = gen_lowpart (DImode, operands[2]);
2250 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2254 (define_insn "*pushdi2_prologue_rex64"
2255 [(set (match_operand:DI 0 "push_operand" "=<")
2256 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2257 (clobber (mem:BLK (scratch)))]
2260 [(set_attr "type" "push")
2261 (set_attr "mode" "DI")])
2263 (define_insn "*popdi1_epilogue_rex64"
2264 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2265 (mem:DI (reg:DI SP_REG)))
2266 (set (reg:DI SP_REG)
2267 (plus:DI (reg:DI SP_REG) (const_int 8)))
2268 (clobber (mem:BLK (scratch)))]
2271 [(set_attr "type" "pop")
2272 (set_attr "mode" "DI")])
2274 (define_insn "popdi1"
2275 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2276 (mem:DI (reg:DI SP_REG)))
2277 (set (reg:DI SP_REG)
2278 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2281 [(set_attr "type" "pop")
2282 (set_attr "mode" "DI")])
2284 (define_insn "*movdi_xor_rex64"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (match_operand:DI 1 "const0_operand" ""))
2287 (clobber (reg:CC FLAGS_REG))]
2289 && reload_completed"
2291 [(set_attr "type" "alu1")
2292 (set_attr "mode" "SI")
2293 (set_attr "length_immediate" "0")])
2295 (define_insn "*movdi_or_rex64"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (match_operand:DI 1 "const_int_operand" "i"))
2298 (clobber (reg:CC FLAGS_REG))]
2301 && operands[1] == constm1_rtx"
2303 operands[1] = constm1_rtx;
2304 return "or{q}\t{%1, %0|%0, %1}";
2306 [(set_attr "type" "alu1")
2307 (set_attr "mode" "DI")
2308 (set_attr "length_immediate" "1")])
2310 (define_insn "*movdi_2"
2311 [(set (match_operand:DI 0 "nonimmediate_operand"
2312 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2313 (match_operand:DI 1 "general_operand"
2314 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2315 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2320 movq\t{%1, %0|%0, %1}
2321 movq\t{%1, %0|%0, %1}
2323 %vmovq\t{%1, %0|%0, %1}
2324 %vmovdqa\t{%1, %0|%0, %1}
2325 %vmovq\t{%1, %0|%0, %1}
2327 movlps\t{%1, %0|%0, %1}
2328 movaps\t{%1, %0|%0, %1}
2329 movlps\t{%1, %0|%0, %1}"
2330 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2331 (set (attr "prefix")
2332 (if_then_else (eq_attr "alternative" "5,6,7,8")
2333 (const_string "vex")
2334 (const_string "orig")))
2335 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2338 [(set (match_operand:DI 0 "push_operand" "")
2339 (match_operand:DI 1 "general_operand" ""))]
2340 "!TARGET_64BIT && reload_completed
2341 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2343 "ix86_split_long_move (operands); DONE;")
2345 ;; %%% This multiword shite has got to go.
2347 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2348 (match_operand:DI 1 "general_operand" ""))]
2349 "!TARGET_64BIT && reload_completed
2350 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2351 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2353 "ix86_split_long_move (operands); DONE;")
2355 (define_insn "*movdi_1_rex64"
2356 [(set (match_operand:DI 0 "nonimmediate_operand"
2357 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2358 (match_operand:DI 1 "general_operand"
2359 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2360 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2362 switch (get_attr_type (insn))
2365 if (SSE_REG_P (operands[0]))
2366 return "movq2dq\t{%1, %0|%0, %1}";
2368 return "movdq2q\t{%1, %0|%0, %1}";
2373 if (get_attr_mode (insn) == MODE_TI)
2374 return "vmovdqa\t{%1, %0|%0, %1}";
2376 return "vmovq\t{%1, %0|%0, %1}";
2379 if (get_attr_mode (insn) == MODE_TI)
2380 return "movdqa\t{%1, %0|%0, %1}";
2384 /* Moves from and into integer register is done using movd
2385 opcode with REX prefix. */
2386 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2387 return "movd\t{%1, %0|%0, %1}";
2388 return "movq\t{%1, %0|%0, %1}";
2391 return "%vpxor\t%0, %d0";
2394 return "pxor\t%0, %0";
2400 return "lea{q}\t{%a1, %0|%0, %a1}";
2403 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2404 if (get_attr_mode (insn) == MODE_SI)
2405 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406 else if (which_alternative == 2)
2407 return "movabs{q}\t{%1, %0|%0, %1}";
2409 return "mov{q}\t{%1, %0|%0, %1}";
2413 (cond [(eq_attr "alternative" "5")
2414 (const_string "mmx")
2415 (eq_attr "alternative" "6,7,8,9,10")
2416 (const_string "mmxmov")
2417 (eq_attr "alternative" "11")
2418 (const_string "sselog1")
2419 (eq_attr "alternative" "12,13,14,15,16")
2420 (const_string "ssemov")
2421 (eq_attr "alternative" "17,18")
2422 (const_string "ssecvt")
2423 (eq_attr "alternative" "4")
2424 (const_string "multi")
2425 (match_operand:DI 1 "pic_32bit_operand" "")
2426 (const_string "lea")
2428 (const_string "imov")))
2429 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2430 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2431 (set (attr "prefix")
2432 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2433 (const_string "maybe_vex")
2434 (const_string "orig")))
2435 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabsdi_1_rex64"
2441 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2443 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2445 movabs{q}\t{%1, %P0|%P0, %1}
2446 mov{q}\t{%1, %a0|%a0, %1}"
2447 [(set_attr "type" "imov")
2448 (set_attr "modrm" "0,*")
2449 (set_attr "length_address" "8,0")
2450 (set_attr "length_immediate" "0,*")
2451 (set_attr "memory" "store")
2452 (set_attr "mode" "DI")])
2454 (define_insn "*movabsdi_2_rex64"
2455 [(set (match_operand:DI 0 "register_operand" "=a,r")
2456 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2459 movabs{q}\t{%P1, %0|%0, %P1}
2460 mov{q}\t{%a1, %0|%0, %a1}"
2461 [(set_attr "type" "imov")
2462 (set_attr "modrm" "0,*")
2463 (set_attr "length_address" "8,0")
2464 (set_attr "length_immediate" "0")
2465 (set_attr "memory" "load")
2466 (set_attr "mode" "DI")])
2468 ;; Convert impossible stores of immediate to existing instructions.
2469 ;; First try to get scratch register and go through it. In case this
2470 ;; fails, move by 32bit parts.
2472 [(match_scratch:DI 2 "r")
2473 (set (match_operand:DI 0 "memory_operand" "")
2474 (match_operand:DI 1 "immediate_operand" ""))]
2475 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2476 && !x86_64_immediate_operand (operands[1], DImode)"
2477 [(set (match_dup 2) (match_dup 1))
2478 (set (match_dup 0) (match_dup 2))]
2481 ;; We need to define this as both peepholer and splitter for case
2482 ;; peephole2 pass is not run.
2483 ;; "&& 1" is needed to keep it from matching the previous pattern.
2485 [(set (match_operand:DI 0 "memory_operand" "")
2486 (match_operand:DI 1 "immediate_operand" ""))]
2487 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2488 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2489 [(set (match_dup 2) (match_dup 3))
2490 (set (match_dup 4) (match_dup 5))]
2491 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2494 [(set (match_operand:DI 0 "memory_operand" "")
2495 (match_operand:DI 1 "immediate_operand" ""))]
2496 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2497 ? epilogue_completed : reload_completed)
2498 && !symbolic_operand (operands[1], DImode)
2499 && !x86_64_immediate_operand (operands[1], DImode)"
2500 [(set (match_dup 2) (match_dup 3))
2501 (set (match_dup 4) (match_dup 5))]
2502 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2504 (define_insn "*swapdi_rex64"
2505 [(set (match_operand:DI 0 "register_operand" "+r")
2506 (match_operand:DI 1 "register_operand" "+r"))
2511 [(set_attr "type" "imov")
2512 (set_attr "mode" "DI")
2513 (set_attr "pent_pair" "np")
2514 (set_attr "athlon_decode" "vector")
2515 (set_attr "amdfam10_decode" "double")])
2517 (define_expand "movoi"
2518 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2519 (match_operand:OI 1 "general_operand" ""))]
2521 "ix86_expand_move (OImode, operands); DONE;")
2523 (define_insn "*movoi_internal"
2524 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2525 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529 switch (which_alternative)
2532 return "vxorps\t%0, %0, %0";
2535 if (misaligned_operand (operands[0], OImode)
2536 || misaligned_operand (operands[1], OImode))
2537 return "vmovdqu\t{%1, %0|%0, %1}";
2539 return "vmovdqa\t{%1, %0|%0, %1}";
2544 [(set_attr "type" "sselog1,ssemov,ssemov")
2545 (set_attr "prefix" "vex")
2546 (set_attr "mode" "OI")])
2548 (define_expand "movti"
2549 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2550 (match_operand:TI 1 "nonimmediate_operand" ""))]
2551 "TARGET_SSE || TARGET_64BIT"
2554 ix86_expand_move (TImode, operands);
2555 else if (push_operand (operands[0], TImode))
2556 ix86_expand_push (TImode, operands[1]);
2558 ix86_expand_vector_move (TImode, operands);
2562 (define_insn "*movti_internal"
2563 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2564 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2565 "TARGET_SSE && !TARGET_64BIT
2566 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2568 switch (which_alternative)
2571 if (get_attr_mode (insn) == MODE_V4SF)
2572 return "%vxorps\t%0, %d0";
2574 return "%vpxor\t%0, %d0";
2577 /* TDmode values are passed as TImode on the stack. Moving them
2578 to stack may result in unaligned memory access. */
2579 if (misaligned_operand (operands[0], TImode)
2580 || misaligned_operand (operands[1], TImode))
2582 if (get_attr_mode (insn) == MODE_V4SF)
2583 return "%vmovups\t{%1, %0|%0, %1}";
2585 return "%vmovdqu\t{%1, %0|%0, %1}";
2589 if (get_attr_mode (insn) == MODE_V4SF)
2590 return "%vmovaps\t{%1, %0|%0, %1}";
2592 return "%vmovdqa\t{%1, %0|%0, %1}";
2598 [(set_attr "type" "sselog1,ssemov,ssemov")
2599 (set_attr "prefix" "maybe_vex")
2601 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2602 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2603 (const_string "V4SF")
2604 (and (eq_attr "alternative" "2")
2605 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2607 (const_string "V4SF")]
2608 (const_string "TI")))])
2610 (define_insn "*movti_rex64"
2611 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2612 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2616 switch (which_alternative)
2622 if (get_attr_mode (insn) == MODE_V4SF)
2623 return "%vxorps\t%0, %d0";
2625 return "%vpxor\t%0, %d0";
2628 /* TDmode values are passed as TImode on the stack. Moving them
2629 to stack may result in unaligned memory access. */
2630 if (misaligned_operand (operands[0], TImode)
2631 || misaligned_operand (operands[1], TImode))
2633 if (get_attr_mode (insn) == MODE_V4SF)
2634 return "%vmovups\t{%1, %0|%0, %1}";
2636 return "%vmovdqu\t{%1, %0|%0, %1}";
2640 if (get_attr_mode (insn) == MODE_V4SF)
2641 return "%vmovaps\t{%1, %0|%0, %1}";
2643 return "%vmovdqa\t{%1, %0|%0, %1}";
2649 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2650 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2652 (cond [(eq_attr "alternative" "2,3")
2654 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2656 (const_string "V4SF")
2657 (const_string "TI"))
2658 (eq_attr "alternative" "4")
2660 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2662 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2664 (const_string "V4SF")
2665 (const_string "TI"))]
2666 (const_string "DI")))])
2669 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2670 (match_operand:TI 1 "general_operand" ""))]
2671 "reload_completed && !SSE_REG_P (operands[0])
2672 && !SSE_REG_P (operands[1])"
2674 "ix86_split_long_move (operands); DONE;")
2676 ;; This expands to what emit_move_complex would generate if we didn't
2677 ;; have a movti pattern. Having this avoids problems with reload on
2678 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2679 ;; to have around all the time.
2680 (define_expand "movcdi"
2681 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2682 (match_operand:CDI 1 "general_operand" ""))]
2685 if (push_operand (operands[0], CDImode))
2686 emit_move_complex_push (CDImode, operands[0], operands[1]);
2688 emit_move_complex_parts (operands[0], operands[1]);
2692 (define_expand "movsf"
2693 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2694 (match_operand:SF 1 "general_operand" ""))]
2696 "ix86_expand_move (SFmode, operands); DONE;")
2698 (define_insn "*pushsf"
2699 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2700 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2703 /* Anything else should be already split before reg-stack. */
2704 gcc_assert (which_alternative == 1);
2705 return "push{l}\t%1";
2707 [(set_attr "type" "multi,push,multi")
2708 (set_attr "unit" "i387,*,*")
2709 (set_attr "mode" "SF,SI,SF")])
2711 (define_insn "*pushsf_rex64"
2712 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2713 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2716 /* Anything else should be already split before reg-stack. */
2717 gcc_assert (which_alternative == 1);
2718 return "push{q}\t%q1";
2720 [(set_attr "type" "multi,push,multi")
2721 (set_attr "unit" "i387,*,*")
2722 (set_attr "mode" "SF,DI,SF")])
2725 [(set (match_operand:SF 0 "push_operand" "")
2726 (match_operand:SF 1 "memory_operand" ""))]
2728 && MEM_P (operands[1])
2729 && (operands[2] = find_constant_src (insn))"
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:SF 0 "push_operand" "")
2737 (match_operand:SF 1 "any_fp_register_operand" ""))]
2739 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2740 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2743 [(set (match_operand:SF 0 "push_operand" "")
2744 (match_operand:SF 1 "any_fp_register_operand" ""))]
2746 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2749 (define_insn "*movsf_1"
2750 [(set (match_operand:SF 0 "nonimmediate_operand"
2751 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2752 (match_operand:SF 1 "general_operand"
2753 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2754 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2755 && (reload_in_progress || reload_completed
2756 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2757 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2758 && standard_80387_constant_p (operands[1]))
2759 || GET_CODE (operands[1]) != CONST_DOUBLE
2760 || memory_operand (operands[0], SFmode))"
2762 switch (which_alternative)
2766 return output_387_reg_move (insn, operands);
2769 return standard_80387_constant_opcode (operands[1]);
2773 return "mov{l}\t{%1, %0|%0, %1}";
2775 if (get_attr_mode (insn) == MODE_TI)
2776 return "%vpxor\t%0, %d0";
2778 return "%vxorps\t%0, %d0";
2780 if (get_attr_mode (insn) == MODE_V4SF)
2781 return "%vmovaps\t{%1, %0|%0, %1}";
2783 return "%vmovss\t{%1, %d0|%d0, %1}";
2786 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2787 : "vmovss\t{%1, %0|%0, %1}";
2789 return "movss\t{%1, %0|%0, %1}";
2791 return "%vmovss\t{%1, %0|%0, %1}";
2793 case 9: case 10: case 14: case 15:
2794 return "movd\t{%1, %0|%0, %1}";
2796 return "%vmovd\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2805 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2806 (set (attr "prefix")
2807 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2808 (const_string "maybe_vex")
2809 (const_string "orig")))
2811 (cond [(eq_attr "alternative" "3,4,9,10")
2813 (eq_attr "alternative" "5")
2815 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2817 (ne (symbol_ref "TARGET_SSE2")
2819 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2822 (const_string "V4SF"))
2823 /* For architectures resolving dependencies on
2824 whole SSE registers use APS move to break dependency
2825 chains, otherwise use short move to avoid extra work.
2827 Do the same for architectures resolving dependencies on
2828 the parts. While in DF mode it is better to always handle
2829 just register parts, the SF mode is different due to lack
2830 of instructions to load just part of the register. It is
2831 better to maintain the whole registers in single format
2832 to avoid problems on using packed logical operations. */
2833 (eq_attr "alternative" "6")
2835 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2837 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2839 (const_string "V4SF")
2840 (const_string "SF"))
2841 (eq_attr "alternative" "11")
2842 (const_string "DI")]
2843 (const_string "SF")))])
2845 (define_insn "*swapsf"
2846 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2847 (match_operand:SF 1 "fp_register_operand" "+f"))
2850 "reload_completed || TARGET_80387"
2852 if (STACK_TOP_P (operands[0]))
2857 [(set_attr "type" "fxch")
2858 (set_attr "mode" "SF")])
2860 (define_expand "movdf"
2861 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2862 (match_operand:DF 1 "general_operand" ""))]
2864 "ix86_expand_move (DFmode, operands); DONE;")
2866 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2867 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2868 ;; On the average, pushdf using integers can be still shorter. Allow this
2869 ;; pattern for optimize_size too.
2871 (define_insn "*pushdf_nointeger"
2872 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2873 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2874 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2876 /* This insn should be already split before reg-stack. */
2879 [(set_attr "type" "multi")
2880 (set_attr "unit" "i387,*,*,*")
2881 (set_attr "mode" "DF,SI,SI,DF")])
2883 (define_insn "*pushdf_integer"
2884 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2885 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2886 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2888 /* This insn should be already split before reg-stack. */
2891 [(set_attr "type" "multi")
2892 (set_attr "unit" "i387,*,*")
2893 (set_attr "mode" "DF,SI,DF")])
2895 ;; %%% Kill this when call knows how to work this out.
2897 [(set (match_operand:DF 0 "push_operand" "")
2898 (match_operand:DF 1 "any_fp_register_operand" ""))]
2900 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2901 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2905 [(set (match_operand:DF 0 "push_operand" "")
2906 (match_operand:DF 1 "general_operand" ""))]
2909 "ix86_split_long_move (operands); DONE;")
2911 ;; Moving is usually shorter when only FP registers are used. This separate
2912 ;; movdf pattern avoids the use of integer registers for FP operations
2913 ;; when optimizing for size.
2915 (define_insn "*movdf_nointeger"
2916 [(set (match_operand:DF 0 "nonimmediate_operand"
2917 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2918 (match_operand:DF 1 "general_operand"
2919 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2920 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2921 && ((optimize_function_for_size_p (cfun)
2922 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2923 && (reload_in_progress || reload_completed
2924 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2925 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2926 && optimize_function_for_size_p (cfun)
2927 && !memory_operand (operands[0], DFmode)
2928 && standard_80387_constant_p (operands[1]))
2929 || GET_CODE (operands[1]) != CONST_DOUBLE
2930 || ((optimize_function_for_size_p (cfun)
2931 || !TARGET_MEMORY_MISMATCH_STALL
2932 || reload_in_progress || reload_completed)
2933 && memory_operand (operands[0], DFmode)))"
2935 switch (which_alternative)
2939 return output_387_reg_move (insn, operands);
2942 return standard_80387_constant_opcode (operands[1]);
2948 switch (get_attr_mode (insn))
2951 return "%vxorps\t%0, %d0";
2953 return "%vxorpd\t%0, %d0";
2955 return "%vpxor\t%0, %d0";
2962 switch (get_attr_mode (insn))
2965 return "%vmovaps\t{%1, %0|%0, %1}";
2967 return "%vmovapd\t{%1, %0|%0, %1}";
2969 return "%vmovdqa\t{%1, %0|%0, %1}";
2971 return "%vmovq\t{%1, %0|%0, %1}";
2975 if (REG_P (operands[0]) && REG_P (operands[1]))
2976 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2978 return "vmovsd\t{%1, %0|%0, %1}";
2981 return "movsd\t{%1, %0|%0, %1}";
2985 if (REG_P (operands[0]))
2986 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2988 return "vmovlpd\t{%1, %0|%0, %1}";
2991 return "movlpd\t{%1, %0|%0, %1}";
2995 if (REG_P (operands[0]))
2996 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2998 return "vmovlps\t{%1, %0|%0, %1}";
3001 return "movlps\t{%1, %0|%0, %1}";
3010 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3011 (set (attr "prefix")
3012 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3013 (const_string "orig")
3014 (const_string "maybe_vex")))
3016 (cond [(eq_attr "alternative" "0,1,2")
3018 (eq_attr "alternative" "3,4")
3021 /* For SSE1, we have many fewer alternatives. */
3022 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023 (cond [(eq_attr "alternative" "5,6")
3024 (const_string "V4SF")
3026 (const_string "V2SF"))
3028 /* xorps is one byte shorter. */
3029 (eq_attr "alternative" "5")
3030 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_string "V4SF")
3033 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3037 (const_string "V2DF"))
3039 /* For architectures resolving dependencies on
3040 whole SSE registers use APD move to break dependency
3041 chains, otherwise use short move to avoid extra work.
3043 movaps encodes one byte shorter. */
3044 (eq_attr "alternative" "6")
3046 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3048 (const_string "V4SF")
3049 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3051 (const_string "V2DF")
3053 (const_string "DF"))
3054 /* For architectures resolving dependencies on register
3055 parts we may avoid extra work to zero out upper part
3057 (eq_attr "alternative" "7")
3059 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3061 (const_string "V1DF")
3062 (const_string "DF"))
3064 (const_string "DF")))])
3066 (define_insn "*movdf_integer_rex64"
3067 [(set (match_operand:DF 0 "nonimmediate_operand"
3068 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3069 (match_operand:DF 1 "general_operand"
3070 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3071 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072 && (reload_in_progress || reload_completed
3073 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3075 && optimize_function_for_size_p (cfun)
3076 && standard_80387_constant_p (operands[1]))
3077 || GET_CODE (operands[1]) != CONST_DOUBLE
3078 || memory_operand (operands[0], DFmode))"
3080 switch (which_alternative)
3084 return output_387_reg_move (insn, operands);
3087 return standard_80387_constant_opcode (operands[1]);
3094 switch (get_attr_mode (insn))
3097 return "%vxorps\t%0, %d0";
3099 return "%vxorpd\t%0, %d0";
3101 return "%vpxor\t%0, %d0";
3108 switch (get_attr_mode (insn))
3111 return "%vmovaps\t{%1, %0|%0, %1}";
3113 return "%vmovapd\t{%1, %0|%0, %1}";
3115 return "%vmovdqa\t{%1, %0|%0, %1}";
3117 return "%vmovq\t{%1, %0|%0, %1}";
3121 if (REG_P (operands[0]) && REG_P (operands[1]))
3122 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3124 return "vmovsd\t{%1, %0|%0, %1}";
3127 return "movsd\t{%1, %0|%0, %1}";
3129 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3131 return "%vmovlps\t{%1, %d0|%d0, %1}";
3138 return "%vmovd\t{%1, %0|%0, %1}";
3144 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3145 (set (attr "prefix")
3146 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3147 (const_string "orig")
3148 (const_string "maybe_vex")))
3150 (cond [(eq_attr "alternative" "0,1,2")
3152 (eq_attr "alternative" "3,4,9,10")
3155 /* For SSE1, we have many fewer alternatives. */
3156 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3157 (cond [(eq_attr "alternative" "5,6")
3158 (const_string "V4SF")
3160 (const_string "V2SF"))
3162 /* xorps is one byte shorter. */
3163 (eq_attr "alternative" "5")
3164 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3166 (const_string "V4SF")
3167 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3171 (const_string "V2DF"))
3173 /* For architectures resolving dependencies on
3174 whole SSE registers use APD move to break dependency
3175 chains, otherwise use short move to avoid extra work.
3177 movaps encodes one byte shorter. */
3178 (eq_attr "alternative" "6")
3180 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3182 (const_string "V4SF")
3183 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3185 (const_string "V2DF")
3187 (const_string "DF"))
3188 /* For architectures resolving dependencies on register
3189 parts we may avoid extra work to zero out upper part
3191 (eq_attr "alternative" "7")
3193 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3195 (const_string "V1DF")
3196 (const_string "DF"))
3198 (const_string "DF")))])
3200 (define_insn "*movdf_integer"
3201 [(set (match_operand:DF 0 "nonimmediate_operand"
3202 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3203 (match_operand:DF 1 "general_operand"
3204 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3205 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206 && optimize_function_for_speed_p (cfun)
3207 && TARGET_INTEGER_DFMODE_MOVES
3208 && (reload_in_progress || reload_completed
3209 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211 && optimize_function_for_size_p (cfun)
3212 && standard_80387_constant_p (operands[1]))
3213 || GET_CODE (operands[1]) != CONST_DOUBLE
3214 || memory_operand (operands[0], DFmode))"
3216 switch (which_alternative)
3220 return output_387_reg_move (insn, operands);
3223 return standard_80387_constant_opcode (operands[1]);
3230 switch (get_attr_mode (insn))
3233 return "xorps\t%0, %0";
3235 return "xorpd\t%0, %0";
3237 return "pxor\t%0, %0";
3244 switch (get_attr_mode (insn))
3247 return "movaps\t{%1, %0|%0, %1}";
3249 return "movapd\t{%1, %0|%0, %1}";
3251 return "movdqa\t{%1, %0|%0, %1}";
3253 return "movq\t{%1, %0|%0, %1}";
3255 return "movsd\t{%1, %0|%0, %1}";
3257 return "movlpd\t{%1, %0|%0, %1}";
3259 return "movlps\t{%1, %0|%0, %1}";
3268 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3270 (cond [(eq_attr "alternative" "0,1,2")
3272 (eq_attr "alternative" "3,4")
3275 /* For SSE1, we have many fewer alternatives. */
3276 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3277 (cond [(eq_attr "alternative" "5,6")
3278 (const_string "V4SF")
3280 (const_string "V2SF"))
3282 /* xorps is one byte shorter. */
3283 (eq_attr "alternative" "5")
3284 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3286 (const_string "V4SF")
3287 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3291 (const_string "V2DF"))
3293 /* For architectures resolving dependencies on
3294 whole SSE registers use APD move to break dependency
3295 chains, otherwise use short move to avoid extra work.
3297 movaps encodes one byte shorter. */
3298 (eq_attr "alternative" "6")
3300 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3302 (const_string "V4SF")
3303 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3305 (const_string "V2DF")
3307 (const_string "DF"))
3308 /* For architectures resolving dependencies on register
3309 parts we may avoid extra work to zero out upper part
3311 (eq_attr "alternative" "7")
3313 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3315 (const_string "V1DF")
3316 (const_string "DF"))
3318 (const_string "DF")))])
3321 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3322 (match_operand:DF 1 "general_operand" ""))]
3324 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3325 && ! (ANY_FP_REG_P (operands[0]) ||
3326 (GET_CODE (operands[0]) == SUBREG
3327 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3328 && ! (ANY_FP_REG_P (operands[1]) ||
3329 (GET_CODE (operands[1]) == SUBREG
3330 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3332 "ix86_split_long_move (operands); DONE;")
3334 (define_insn "*swapdf"
3335 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3336 (match_operand:DF 1 "fp_register_operand" "+f"))
3339 "reload_completed || TARGET_80387"
3341 if (STACK_TOP_P (operands[0]))
3346 [(set_attr "type" "fxch")
3347 (set_attr "mode" "DF")])
3349 (define_expand "movxf"
3350 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3351 (match_operand:XF 1 "general_operand" ""))]
3353 "ix86_expand_move (XFmode, operands); DONE;")
3355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3356 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3357 ;; Pushing using integer instructions is longer except for constants
3358 ;; and direct memory references.
3359 ;; (assuming that any given constant is pushed only once, but this ought to be
3360 ;; handled elsewhere).
3362 (define_insn "*pushxf_nointeger"
3363 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3364 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3365 "optimize_function_for_size_p (cfun)"
3367 /* This insn should be already split before reg-stack. */
3370 [(set_attr "type" "multi")
3371 (set_attr "unit" "i387,*,*")
3372 (set_attr "mode" "XF,SI,SI")])
3374 (define_insn "*pushxf_integer"
3375 [(set (match_operand:XF 0 "push_operand" "=<,<")
3376 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3377 "optimize_function_for_speed_p (cfun)"
3379 /* This insn should be already split before reg-stack. */
3382 [(set_attr "type" "multi")
3383 (set_attr "unit" "i387,*")
3384 (set_attr "mode" "XF,SI")])
3387 [(set (match_operand 0 "push_operand" "")
3388 (match_operand 1 "general_operand" ""))]
3390 && (GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && !ANY_FP_REG_P (operands[1])"
3394 "ix86_split_long_move (operands); DONE;")
3397 [(set (match_operand:XF 0 "push_operand" "")
3398 (match_operand:XF 1 "any_fp_register_operand" ""))]
3400 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3401 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3402 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3404 ;; Do not use integer registers when optimizing for size
3405 (define_insn "*movxf_nointeger"
3406 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3407 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3408 "optimize_function_for_size_p (cfun)
3409 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3410 && (reload_in_progress || reload_completed
3411 || standard_80387_constant_p (operands[1])
3412 || GET_CODE (operands[1]) != CONST_DOUBLE
3413 || memory_operand (operands[0], XFmode))"
3415 switch (which_alternative)
3419 return output_387_reg_move (insn, operands);
3422 return standard_80387_constant_opcode (operands[1]);
3430 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3431 (set_attr "mode" "XF,XF,XF,SI,SI")])
3433 (define_insn "*movxf_integer"
3434 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3435 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3436 "optimize_function_for_speed_p (cfun)
3437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438 && (reload_in_progress || reload_completed
3439 || GET_CODE (operands[1]) != CONST_DOUBLE
3440 || memory_operand (operands[0], XFmode))"
3442 switch (which_alternative)
3446 return output_387_reg_move (insn, operands);
3449 return standard_80387_constant_opcode (operands[1]);
3458 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3459 (set_attr "mode" "XF,XF,XF,SI,SI")])
3461 (define_expand "movtf"
3462 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3463 (match_operand:TF 1 "nonimmediate_operand" ""))]
3466 ix86_expand_move (TFmode, operands);
3470 (define_insn "*movtf_internal"
3471 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3472 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3476 switch (which_alternative)
3480 if (get_attr_mode (insn) == MODE_V4SF)
3481 return "%vmovaps\t{%1, %0|%0, %1}";
3483 return "%vmovdqa\t{%1, %0|%0, %1}";
3485 if (get_attr_mode (insn) == MODE_V4SF)
3486 return "%vxorps\t%0, %d0";
3488 return "%vpxor\t%0, %d0";
3496 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3497 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3499 (cond [(eq_attr "alternative" "0,2")
3501 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3503 (const_string "V4SF")
3504 (const_string "TI"))
3505 (eq_attr "alternative" "1")
3507 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3509 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3511 (const_string "V4SF")
3512 (const_string "TI"))]
3513 (const_string "DI")))])
3515 (define_insn "*pushtf_sse"
3516 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3517 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3520 /* This insn should be already split before reg-stack. */
3523 [(set_attr "type" "multi")
3524 (set_attr "unit" "sse,*,*")
3525 (set_attr "mode" "TF,SI,SI")])
3528 [(set (match_operand:TF 0 "push_operand" "")
3529 (match_operand:TF 1 "general_operand" ""))]
3530 "TARGET_SSE2 && reload_completed
3531 && !SSE_REG_P (operands[1])"
3533 "ix86_split_long_move (operands); DONE;")
3536 [(set (match_operand:TF 0 "push_operand" "")
3537 (match_operand:TF 1 "any_fp_register_operand" ""))]
3539 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3540 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3544 [(set (match_operand 0 "nonimmediate_operand" "")
3545 (match_operand 1 "general_operand" ""))]
3547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3548 && GET_MODE (operands[0]) == XFmode
3549 && ! (ANY_FP_REG_P (operands[0]) ||
3550 (GET_CODE (operands[0]) == SUBREG
3551 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3552 && ! (ANY_FP_REG_P (operands[1]) ||
3553 (GET_CODE (operands[1]) == SUBREG
3554 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3556 "ix86_split_long_move (operands); DONE;")
3559 [(set (match_operand 0 "register_operand" "")
3560 (match_operand 1 "memory_operand" ""))]
3562 && MEM_P (operands[1])
3563 && (GET_MODE (operands[0]) == TFmode
3564 || GET_MODE (operands[0]) == XFmode
3565 || GET_MODE (operands[0]) == SFmode
3566 || GET_MODE (operands[0]) == DFmode)
3567 && (operands[2] = find_constant_src (insn))"
3568 [(set (match_dup 0) (match_dup 2))]
3570 rtx c = operands[2];
3571 rtx r = operands[0];
3573 if (GET_CODE (r) == SUBREG)
3578 if (!standard_sse_constant_p (c))
3581 else if (FP_REG_P (r))
3583 if (!standard_80387_constant_p (c))
3586 else if (MMX_REG_P (r))
3591 [(set (match_operand 0 "register_operand" "")
3592 (float_extend (match_operand 1 "memory_operand" "")))]
3594 && MEM_P (operands[1])
3595 && (GET_MODE (operands[0]) == TFmode
3596 || GET_MODE (operands[0]) == XFmode
3597 || GET_MODE (operands[0]) == SFmode
3598 || GET_MODE (operands[0]) == DFmode)
3599 && (operands[2] = find_constant_src (insn))"
3600 [(set (match_dup 0) (match_dup 2))]
3602 rtx c = operands[2];
3603 rtx r = operands[0];
3605 if (GET_CODE (r) == SUBREG)
3610 if (!standard_sse_constant_p (c))
3613 else if (FP_REG_P (r))
3615 if (!standard_80387_constant_p (c))
3618 else if (MMX_REG_P (r))
3622 (define_insn "swapxf"
3623 [(set (match_operand:XF 0 "register_operand" "+f")
3624 (match_operand:XF 1 "register_operand" "+f"))
3629 if (STACK_TOP_P (operands[0]))
3634 [(set_attr "type" "fxch")
3635 (set_attr "mode" "XF")])
3637 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3639 [(set (match_operand:X87MODEF 0 "register_operand" "")
3640 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3641 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3642 && (standard_80387_constant_p (operands[1]) == 8
3643 || standard_80387_constant_p (operands[1]) == 9)"
3644 [(set (match_dup 0)(match_dup 1))
3646 (neg:X87MODEF (match_dup 0)))]
3650 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3651 if (real_isnegzero (&r))
3652 operands[1] = CONST0_RTX (<MODE>mode);
3654 operands[1] = CONST1_RTX (<MODE>mode);
3658 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3659 (match_operand:TF 1 "general_operand" ""))]
3661 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3663 "ix86_split_long_move (operands); DONE;")
3665 ;; Zero extension instructions
3667 (define_expand "zero_extendhisi2"
3668 [(set (match_operand:SI 0 "register_operand" "")
3669 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3672 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3674 operands[1] = force_reg (HImode, operands[1]);
3675 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3680 (define_insn "zero_extendhisi2_and"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3686 [(set_attr "type" "alu1")
3687 (set_attr "mode" "SI")])
3690 [(set (match_operand:SI 0 "register_operand" "")
3691 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))]
3693 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3694 && optimize_function_for_speed_p (cfun)"
3695 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3696 (clobber (reg:CC FLAGS_REG))])]
3699 (define_insn "*zero_extendhisi2_movzwl"
3700 [(set (match_operand:SI 0 "register_operand" "=r")
3701 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702 "!TARGET_ZERO_EXTEND_WITH_AND
3703 || optimize_function_for_size_p (cfun)"
3704 "movz{wl|x}\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "SI")])
3708 (define_expand "zero_extendqihi2"
3710 [(set (match_operand:HI 0 "register_operand" "")
3711 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3712 (clobber (reg:CC FLAGS_REG))])]
3716 (define_insn "*zero_extendqihi2_and"
3717 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3718 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3719 (clobber (reg:CC FLAGS_REG))]
3720 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3722 [(set_attr "type" "alu1")
3723 (set_attr "mode" "HI")])
3725 (define_insn "*zero_extendqihi2_movzbw_and"
3726 [(set (match_operand:HI 0 "register_operand" "=r,r")
3727 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3728 (clobber (reg:CC FLAGS_REG))]
3729 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3731 [(set_attr "type" "imovx,alu1")
3732 (set_attr "mode" "HI")])
3734 ; zero extend to SImode here to avoid partial register stalls
3735 (define_insn "*zero_extendqihi2_movzbl"
3736 [(set (match_operand:HI 0 "register_operand" "=r")
3737 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739 && reload_completed"
3740 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 ;; For the movzbw case strip only the clobber
3746 [(set (match_operand:HI 0 "register_operand" "")
3747 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3748 (clobber (reg:CC FLAGS_REG))]
3750 && (!TARGET_ZERO_EXTEND_WITH_AND
3751 || optimize_function_for_size_p (cfun))
3752 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753 [(set (match_operand:HI 0 "register_operand" "")
3754 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3759 [(set (match_operand:HI 0 "register_operand" "")
3760 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3761 (clobber (reg:CC FLAGS_REG))]
3763 && ANY_QI_REG_P (operands[0])
3764 && (TARGET_ZERO_EXTEND_WITH_AND
3765 && optimize_function_for_speed_p (cfun))
3766 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767 [(set (match_dup 0) (const_int 0))
3768 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3769 "operands[2] = gen_lowpart (QImode, operands[0]);")
3771 ;; Rest is handled by single and.
3773 [(set (match_operand:HI 0 "register_operand" "")
3774 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3775 (clobber (reg:CC FLAGS_REG))]
3777 && true_regnum (operands[0]) == true_regnum (operands[1])"
3778 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3779 (clobber (reg:CC FLAGS_REG))])]
3782 (define_expand "zero_extendqisi2"
3784 [(set (match_operand:SI 0 "register_operand" "")
3785 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3786 (clobber (reg:CC FLAGS_REG))])]
3790 (define_insn "*zero_extendqisi2_and"
3791 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3792 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3793 (clobber (reg:CC FLAGS_REG))]
3794 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3796 [(set_attr "type" "alu1")
3797 (set_attr "mode" "SI")])
3799 (define_insn "*zero_extendqisi2_movzbw_and"
3800 [(set (match_operand:SI 0 "register_operand" "=r,r")
3801 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3802 (clobber (reg:CC FLAGS_REG))]
3803 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3805 [(set_attr "type" "imovx,alu1")
3806 (set_attr "mode" "SI")])
3808 (define_insn "*zero_extendqisi2_movzbw"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3812 && reload_completed"
3813 "movz{bl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3817 ;; For the movzbl case strip only the clobber
3819 [(set (match_operand:SI 0 "register_operand" "")
3820 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821 (clobber (reg:CC FLAGS_REG))]
3823 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3824 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3826 (zero_extend:SI (match_dup 1)))])
3828 ;; When source and destination does not overlap, clear destination
3829 ;; first and then do the movb
3831 [(set (match_operand:SI 0 "register_operand" "")
3832 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3833 (clobber (reg:CC FLAGS_REG))]
3835 && ANY_QI_REG_P (operands[0])
3836 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3837 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3839 [(set (match_dup 0) (const_int 0))
3840 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3841 "operands[2] = gen_lowpart (QImode, operands[0]);")
3843 ;; Rest is handled by single and.
3845 [(set (match_operand:SI 0 "register_operand" "")
3846 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3847 (clobber (reg:CC FLAGS_REG))]
3849 && true_regnum (operands[0]) == true_regnum (operands[1])"
3850 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3851 (clobber (reg:CC FLAGS_REG))])]
3854 ;; %%% Kill me once multi-word ops are sane.
3855 (define_expand "zero_extendsidi2"
3856 [(set (match_operand:DI 0 "register_operand" "")
3857 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3862 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3867 (define_insn "zero_extendsidi2_32"
3868 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3870 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3871 (clobber (reg:CC FLAGS_REG))]
3877 movd\t{%1, %0|%0, %1}
3878 movd\t{%1, %0|%0, %1}
3879 %vmovd\t{%1, %0|%0, %1}
3880 %vmovd\t{%1, %0|%0, %1}"
3881 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3882 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3883 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3885 (define_insn "zero_extendsidi2_rex64"
3886 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3888 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3891 mov\t{%k1, %k0|%k0, %k1}
3893 movd\t{%1, %0|%0, %1}
3894 movd\t{%1, %0|%0, %1}
3895 %vmovd\t{%1, %0|%0, %1}
3896 %vmovd\t{%1, %0|%0, %1}"
3897 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3898 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3899 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3902 [(set (match_operand:DI 0 "memory_operand" "")
3903 (zero_extend:DI (match_dup 0)))]
3905 [(set (match_dup 4) (const_int 0))]
3906 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3909 [(set (match_operand:DI 0 "register_operand" "")
3910 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3911 (clobber (reg:CC FLAGS_REG))]
3912 "!TARGET_64BIT && reload_completed
3913 && true_regnum (operands[0]) == true_regnum (operands[1])"
3914 [(set (match_dup 4) (const_int 0))]
3915 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3919 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3920 (clobber (reg:CC FLAGS_REG))]
3921 "!TARGET_64BIT && reload_completed
3922 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3923 [(set (match_dup 3) (match_dup 1))
3924 (set (match_dup 4) (const_int 0))]
3925 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3927 (define_insn "zero_extendhidi2"
3928 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3931 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "DI")])
3935 (define_insn "zero_extendqidi2"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3939 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3940 [(set_attr "type" "imovx")
3941 (set_attr "mode" "DI")])
3943 ;; Sign extension instructions
3945 (define_expand "extendsidi2"
3946 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3947 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3948 (clobber (reg:CC FLAGS_REG))
3949 (clobber (match_scratch:SI 2 ""))])]
3954 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3959 (define_insn "*extendsidi2_1"
3960 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3961 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3962 (clobber (reg:CC FLAGS_REG))
3963 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3967 (define_insn "extendsidi2_rex64"
3968 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3969 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3973 movs{lq|x}\t{%1,%0|%0, %1}"
3974 [(set_attr "type" "imovx")
3975 (set_attr "mode" "DI")
3976 (set_attr "prefix_0f" "0")
3977 (set_attr "modrm" "0,1")])
3979 (define_insn "extendhidi2"
3980 [(set (match_operand:DI 0 "register_operand" "=r")
3981 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3983 "movs{wq|x}\t{%1,%0|%0, %1}"
3984 [(set_attr "type" "imovx")
3985 (set_attr "mode" "DI")])
3987 (define_insn "extendqidi2"
3988 [(set (match_operand:DI 0 "register_operand" "=r")
3989 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3991 "movs{bq|x}\t{%1,%0|%0, %1}"
3992 [(set_attr "type" "imovx")
3993 (set_attr "mode" "DI")])
3995 ;; Extend to memory case when source register does die.
3997 [(set (match_operand:DI 0 "memory_operand" "")
3998 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3999 (clobber (reg:CC FLAGS_REG))
4000 (clobber (match_operand:SI 2 "register_operand" ""))]
4002 && dead_or_set_p (insn, operands[1])
4003 && !reg_mentioned_p (operands[1], operands[0]))"
4004 [(set (match_dup 3) (match_dup 1))
4005 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4006 (clobber (reg:CC FLAGS_REG))])
4007 (set (match_dup 4) (match_dup 1))]
4008 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4010 ;; Extend to memory case when source register does not die.
4012 [(set (match_operand:DI 0 "memory_operand" "")
4013 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4014 (clobber (reg:CC FLAGS_REG))
4015 (clobber (match_operand:SI 2 "register_operand" ""))]
4019 split_di (&operands[0], 1, &operands[3], &operands[4]);
4021 emit_move_insn (operands[3], operands[1]);
4023 /* Generate a cltd if possible and doing so it profitable. */
4024 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025 && true_regnum (operands[1]) == AX_REG
4026 && true_regnum (operands[2]) == DX_REG)
4028 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4032 emit_move_insn (operands[2], operands[1]);
4033 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4035 emit_move_insn (operands[4], operands[2]);
4039 ;; Extend to register case. Optimize case where source and destination
4040 ;; registers match and cases where we can use cltd.
4042 [(set (match_operand:DI 0 "register_operand" "")
4043 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4044 (clobber (reg:CC FLAGS_REG))
4045 (clobber (match_scratch:SI 2 ""))]
4049 split_di (&operands[0], 1, &operands[3], &operands[4]);
4051 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4052 emit_move_insn (operands[3], operands[1]);
4054 /* Generate a cltd if possible and doing so it profitable. */
4055 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4056 && true_regnum (operands[3]) == AX_REG)
4058 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4062 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4063 emit_move_insn (operands[4], operands[1]);
4065 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4069 (define_insn "extendhisi2"
4070 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4071 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4074 switch (get_attr_prefix_0f (insn))
4077 return "{cwtl|cwde}";
4079 return "movs{wl|x}\t{%1,%0|%0, %1}";
4082 [(set_attr "type" "imovx")
4083 (set_attr "mode" "SI")
4084 (set (attr "prefix_0f")
4085 ;; movsx is short decodable while cwtl is vector decoded.
4086 (if_then_else (and (eq_attr "cpu" "!k6")
4087 (eq_attr "alternative" "0"))
4089 (const_string "1")))
4091 (if_then_else (eq_attr "prefix_0f" "0")
4093 (const_string "1")))])
4095 (define_insn "*extendhisi2_zext"
4096 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4098 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4101 switch (get_attr_prefix_0f (insn))
4104 return "{cwtl|cwde}";
4106 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4109 [(set_attr "type" "imovx")
4110 (set_attr "mode" "SI")
4111 (set (attr "prefix_0f")
4112 ;; movsx is short decodable while cwtl is vector decoded.
4113 (if_then_else (and (eq_attr "cpu" "!k6")
4114 (eq_attr "alternative" "0"))
4116 (const_string "1")))
4118 (if_then_else (eq_attr "prefix_0f" "0")
4120 (const_string "1")))])
4122 (define_insn "extendqihi2"
4123 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4124 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4127 switch (get_attr_prefix_0f (insn))
4130 return "{cbtw|cbw}";
4132 return "movs{bw|x}\t{%1,%0|%0, %1}";
4135 [(set_attr "type" "imovx")
4136 (set_attr "mode" "HI")
4137 (set (attr "prefix_0f")
4138 ;; movsx is short decodable while cwtl is vector decoded.
4139 (if_then_else (and (eq_attr "cpu" "!k6")
4140 (eq_attr "alternative" "0"))
4142 (const_string "1")))
4144 (if_then_else (eq_attr "prefix_0f" "0")
4146 (const_string "1")))])
4148 (define_insn "extendqisi2"
4149 [(set (match_operand:SI 0 "register_operand" "=r")
4150 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4152 "movs{bl|x}\t{%1,%0|%0, %1}"
4153 [(set_attr "type" "imovx")
4154 (set_attr "mode" "SI")])
4156 (define_insn "*extendqisi2_zext"
4157 [(set (match_operand:DI 0 "register_operand" "=r")
4159 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4161 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4162 [(set_attr "type" "imovx")
4163 (set_attr "mode" "SI")])
4165 ;; Conversions between float and double.
4167 ;; These are all no-ops in the model used for the 80387. So just
4170 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4171 (define_insn "*dummy_extendsfdf2"
4172 [(set (match_operand:DF 0 "push_operand" "=<")
4173 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4178 [(set (match_operand:DF 0 "push_operand" "")
4179 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4181 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4182 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4184 (define_insn "*dummy_extendsfxf2"
4185 [(set (match_operand:XF 0 "push_operand" "=<")
4186 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4191 [(set (match_operand:XF 0 "push_operand" "")
4192 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4194 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4195 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4196 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4199 [(set (match_operand:XF 0 "push_operand" "")
4200 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4202 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4203 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4204 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4206 (define_expand "extendsfdf2"
4207 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4208 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4209 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4211 /* ??? Needed for compress_float_constant since all fp constants
4212 are LEGITIMATE_CONSTANT_P. */
4213 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4215 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4216 && standard_80387_constant_p (operands[1]) > 0)
4218 operands[1] = simplify_const_unary_operation
4219 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4220 emit_move_insn_1 (operands[0], operands[1]);
4223 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4227 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4229 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4231 We do the conversion post reload to avoid producing of 128bit spills
4232 that might lead to ICE on 32bit target. The sequence unlikely combine
4235 [(set (match_operand:DF 0 "register_operand" "")
4237 (match_operand:SF 1 "nonimmediate_operand" "")))]
4238 "TARGET_USE_VECTOR_FP_CONVERTS
4239 && optimize_insn_for_speed_p ()
4240 && reload_completed && SSE_REG_P (operands[0])"
4245 (parallel [(const_int 0) (const_int 1)]))))]
4247 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4248 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4249 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4250 Try to avoid move when unpacking can be done in source. */
4251 if (REG_P (operands[1]))
4253 /* If it is unsafe to overwrite upper half of source, we need
4254 to move to destination and unpack there. */
4255 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4257 && true_regnum (operands[0]) != true_regnum (operands[1]))
4259 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4260 emit_move_insn (tmp, operands[1]);
4263 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4264 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4267 emit_insn (gen_vec_setv4sf_0 (operands[3],
4268 CONST0_RTX (V4SFmode), operands[1]));
4271 (define_insn "*extendsfdf2_mixed"
4272 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4274 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4275 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4277 switch (which_alternative)
4281 return output_387_reg_move (insn, operands);
4284 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4290 [(set_attr "type" "fmov,fmov,ssecvt")
4291 (set_attr "prefix" "orig,orig,maybe_vex")
4292 (set_attr "mode" "SF,XF,DF")])
4294 (define_insn "*extendsfdf2_sse"
4295 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4296 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4297 "TARGET_SSE2 && TARGET_SSE_MATH"
4298 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4299 [(set_attr "type" "ssecvt")
4300 (set_attr "prefix" "maybe_vex")
4301 (set_attr "mode" "DF")])
4303 (define_insn "*extendsfdf2_i387"
4304 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4305 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4307 "* return output_387_reg_move (insn, operands);"
4308 [(set_attr "type" "fmov")
4309 (set_attr "mode" "SF,XF")])
4311 (define_expand "extend<mode>xf2"
4312 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4313 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4316 /* ??? Needed for compress_float_constant since all fp constants
4317 are LEGITIMATE_CONSTANT_P. */
4318 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4320 if (standard_80387_constant_p (operands[1]) > 0)
4322 operands[1] = simplify_const_unary_operation
4323 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4324 emit_move_insn_1 (operands[0], operands[1]);
4327 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4331 (define_insn "*extend<mode>xf2_i387"
4332 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4334 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4336 "* return output_387_reg_move (insn, operands);"
4337 [(set_attr "type" "fmov")
4338 (set_attr "mode" "<MODE>,XF")])
4340 ;; %%% This seems bad bad news.
4341 ;; This cannot output into an f-reg because there is no way to be sure
4342 ;; of truncating in that case. Otherwise this is just like a simple move
4343 ;; insn. So we pretend we can output to a reg in order to get better
4344 ;; register preferencing, but we really use a stack slot.
4346 ;; Conversion from DFmode to SFmode.
4348 (define_expand "truncdfsf2"
4349 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4351 (match_operand:DF 1 "nonimmediate_operand" "")))]
4352 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4354 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4356 else if (flag_unsafe_math_optimizations)
4360 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4361 rtx temp = assign_386_stack_local (SFmode, slot);
4362 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4367 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4369 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4371 We do the conversion post reload to avoid producing of 128bit spills
4372 that might lead to ICE on 32bit target. The sequence unlikely combine
4375 [(set (match_operand:SF 0 "register_operand" "")
4377 (match_operand:DF 1 "nonimmediate_operand" "")))]
4378 "TARGET_USE_VECTOR_FP_CONVERTS
4379 && optimize_insn_for_speed_p ()
4380 && reload_completed && SSE_REG_P (operands[0])"
4383 (float_truncate:V2SF
4387 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4388 operands[3] = CONST0_RTX (V2SFmode);
4389 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4390 /* Use movsd for loading from memory, unpcklpd for registers.
4391 Try to avoid move when unpacking can be done in source, or SSE3
4392 movddup is available. */
4393 if (REG_P (operands[1]))
4396 && true_regnum (operands[0]) != true_regnum (operands[1])
4397 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4398 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4400 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4401 emit_move_insn (tmp, operands[1]);
4404 else if (!TARGET_SSE3)
4405 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4406 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4409 emit_insn (gen_sse2_loadlpd (operands[4],
4410 CONST0_RTX (V2DFmode), operands[1]));
4413 (define_expand "truncdfsf2_with_temp"
4414 [(parallel [(set (match_operand:SF 0 "" "")
4415 (float_truncate:SF (match_operand:DF 1 "" "")))
4416 (clobber (match_operand:SF 2 "" ""))])]
4419 (define_insn "*truncdfsf_fast_mixed"
4420 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4422 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4423 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4425 switch (which_alternative)
4428 return output_387_reg_move (insn, operands);
4430 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4435 [(set_attr "type" "fmov,ssecvt")
4436 (set_attr "prefix" "orig,maybe_vex")
4437 (set_attr "mode" "SF")])
4439 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4440 ;; because nothing we do here is unsafe.
4441 (define_insn "*truncdfsf_fast_sse"
4442 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4444 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4445 "TARGET_SSE2 && TARGET_SSE_MATH"
4446 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4447 [(set_attr "type" "ssecvt")
4448 (set_attr "prefix" "maybe_vex")
4449 (set_attr "mode" "SF")])
4451 (define_insn "*truncdfsf_fast_i387"
4452 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4454 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4455 "TARGET_80387 && flag_unsafe_math_optimizations"
4456 "* return output_387_reg_move (insn, operands);"
4457 [(set_attr "type" "fmov")
4458 (set_attr "mode" "SF")])
4460 (define_insn "*truncdfsf_mixed"
4461 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4463 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4464 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4465 "TARGET_MIX_SSE_I387"
4467 switch (which_alternative)
4470 return output_387_reg_move (insn, operands);
4472 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4478 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4479 (set_attr "unit" "*,*,i387,i387,i387")
4480 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4481 (set_attr "mode" "SF")])
4483 (define_insn "*truncdfsf_i387"
4484 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4486 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4487 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4490 switch (which_alternative)
4493 return output_387_reg_move (insn, operands);
4499 [(set_attr "type" "fmov,multi,multi,multi")
4500 (set_attr "unit" "*,i387,i387,i387")
4501 (set_attr "mode" "SF")])
4503 (define_insn "*truncdfsf2_i387_1"
4504 [(set (match_operand:SF 0 "memory_operand" "=m")
4506 (match_operand:DF 1 "register_operand" "f")))]
4508 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4509 && !TARGET_MIX_SSE_I387"
4510 "* return output_387_reg_move (insn, operands);"
4511 [(set_attr "type" "fmov")
4512 (set_attr "mode" "SF")])
4515 [(set (match_operand:SF 0 "register_operand" "")
4517 (match_operand:DF 1 "fp_register_operand" "")))
4518 (clobber (match_operand 2 "" ""))]
4520 [(set (match_dup 2) (match_dup 1))
4521 (set (match_dup 0) (match_dup 2))]
4523 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4526 ;; Conversion from XFmode to {SF,DF}mode
4528 (define_expand "truncxf<mode>2"
4529 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4530 (float_truncate:MODEF
4531 (match_operand:XF 1 "register_operand" "")))
4532 (clobber (match_dup 2))])]
4535 if (flag_unsafe_math_optimizations)
4537 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4538 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4539 if (reg != operands[0])
4540 emit_move_insn (operands[0], reg);
4545 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4546 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4550 (define_insn "*truncxfsf2_mixed"
4551 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4553 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4554 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4557 gcc_assert (!which_alternative);
4558 return output_387_reg_move (insn, operands);
4560 [(set_attr "type" "fmov,multi,multi,multi")
4561 (set_attr "unit" "*,i387,i387,i387")
4562 (set_attr "mode" "SF")])
4564 (define_insn "*truncxfdf2_mixed"
4565 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4567 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4568 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4571 gcc_assert (!which_alternative);
4572 return output_387_reg_move (insn, operands);
4574 [(set_attr "type" "fmov,multi,multi,multi")
4575 (set_attr "unit" "*,i387,i387,i387")
4576 (set_attr "mode" "DF")])
4578 (define_insn "truncxf<mode>2_i387_noop"
4579 [(set (match_operand:MODEF 0 "register_operand" "=f")
4580 (float_truncate:MODEF
4581 (match_operand:XF 1 "register_operand" "f")))]
4582 "TARGET_80387 && flag_unsafe_math_optimizations"
4583 "* return output_387_reg_move (insn, operands);"
4584 [(set_attr "type" "fmov")
4585 (set_attr "mode" "<MODE>")])
4587 (define_insn "*truncxf<mode>2_i387"
4588 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4589 (float_truncate:MODEF
4590 (match_operand:XF 1 "register_operand" "f")))]
4592 "* return output_387_reg_move (insn, operands);"
4593 [(set_attr "type" "fmov")
4594 (set_attr "mode" "<MODE>")])
4597 [(set (match_operand:MODEF 0 "register_operand" "")
4598 (float_truncate:MODEF
4599 (match_operand:XF 1 "register_operand" "")))
4600 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4601 "TARGET_80387 && reload_completed"
4602 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4603 (set (match_dup 0) (match_dup 2))]
4607 [(set (match_operand:MODEF 0 "memory_operand" "")
4608 (float_truncate:MODEF
4609 (match_operand:XF 1 "register_operand" "")))
4610 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4612 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4615 ;; Signed conversion to DImode.
4617 (define_expand "fix_truncxfdi2"
4618 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4619 (fix:DI (match_operand:XF 1 "register_operand" "")))
4620 (clobber (reg:CC FLAGS_REG))])]
4625 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4630 (define_expand "fix_trunc<mode>di2"
4631 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4632 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4633 (clobber (reg:CC FLAGS_REG))])]
4634 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4637 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4639 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4642 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4644 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646 if (out != operands[0])
4647 emit_move_insn (operands[0], out);
4652 ;; Signed conversion to SImode.
4654 (define_expand "fix_truncxfsi2"
4655 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4656 (fix:SI (match_operand:XF 1 "register_operand" "")))
4657 (clobber (reg:CC FLAGS_REG))])]
4662 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4667 (define_expand "fix_trunc<mode>si2"
4668 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4669 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4670 (clobber (reg:CC FLAGS_REG))])]
4671 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4674 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4676 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4679 if (SSE_FLOAT_MODE_P (<MODE>mode))
4681 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683 if (out != operands[0])
4684 emit_move_insn (operands[0], out);
4689 ;; Signed conversion to HImode.
4691 (define_expand "fix_trunc<mode>hi2"
4692 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4693 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4694 (clobber (reg:CC FLAGS_REG))])]
4696 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4700 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4705 ;; Unsigned conversion to SImode.
4707 (define_expand "fixuns_trunc<mode>si2"
4709 [(set (match_operand:SI 0 "register_operand" "")
4711 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4713 (clobber (match_scratch:<ssevecmode> 3 ""))
4714 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4715 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4717 enum machine_mode mode = <MODE>mode;
4718 enum machine_mode vecmode = <ssevecmode>mode;
4719 REAL_VALUE_TYPE TWO31r;
4722 if (optimize_insn_for_size_p ())
4725 real_ldexp (&TWO31r, &dconst1, 31);
4726 two31 = const_double_from_real_value (TWO31r, mode);
4727 two31 = ix86_build_const_vector (mode, true, two31);
4728 operands[2] = force_reg (vecmode, two31);
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4734 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4736 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739 && optimize_function_for_speed_p (cfun)"
4741 "&& reload_completed"
4744 ix86_split_convert_uns_si_sse (operands);
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752 (define_expand "fixuns_trunc<mode>hi2"
4754 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4755 (set (match_operand:HI 0 "nonimmediate_operand" "")
4756 (subreg:HI (match_dup 2) 0))]
4757 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758 "operands[2] = gen_reg_rtx (SImode);")
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<mode>di_sse"
4762 [(set (match_operand:DI 0 "register_operand" "=r,r")
4763 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4764 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4765 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4767 [(set_attr "type" "sseicvt")
4768 (set_attr "prefix" "maybe_vex")
4769 (set_attr "mode" "<MODE>")
4770 (set_attr "athlon_decode" "double,vector")
4771 (set_attr "amdfam10_decode" "double,double")])
4773 (define_insn "fix_trunc<mode>si_sse"
4774 [(set (match_operand:SI 0 "register_operand" "=r,r")
4775 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4776 "SSE_FLOAT_MODE_P (<MODE>mode)
4777 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4778 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sseicvt")
4780 (set_attr "prefix" "maybe_vex")
4781 (set_attr "mode" "<MODE>")
4782 (set_attr "athlon_decode" "double,vector")
4783 (set_attr "amdfam10_decode" "double,double")])
4785 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4787 [(set (match_operand:MODEF 0 "register_operand" "")
4788 (match_operand:MODEF 1 "memory_operand" ""))
4789 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4790 (fix:SSEMODEI24 (match_dup 0)))]
4791 "TARGET_SHORTEN_X87_SSE
4792 && peep2_reg_dead_p (2, operands[0])"
4793 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4796 ;; Avoid vector decoded forms of the instruction.
4798 [(match_scratch:DF 2 "Y2")
4799 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4800 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4801 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4802 [(set (match_dup 2) (match_dup 1))
4803 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4807 [(match_scratch:SF 2 "x")
4808 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4809 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4810 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4811 [(set (match_dup 2) (match_dup 1))
4812 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4815 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4816 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4817 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4818 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4820 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4821 && (TARGET_64BIT || <MODE>mode != DImode))
4823 && !(reload_completed || reload_in_progress)"
4828 if (memory_operand (operands[0], VOIDmode))
4829 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4832 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4833 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4839 [(set_attr "type" "fisttp")
4840 (set_attr "mode" "<MODE>")])
4842 (define_insn "fix_trunc<mode>_i387_fisttp"
4843 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4844 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4845 (clobber (match_scratch:XF 2 "=&1f"))]
4846 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4848 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4849 && (TARGET_64BIT || <MODE>mode != DImode))
4850 && TARGET_SSE_MATH)"
4851 "* return output_fix_trunc (insn, operands, 1);"
4852 [(set_attr "type" "fisttp")
4853 (set_attr "mode" "<MODE>")])
4855 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4856 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4857 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4858 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4859 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4860 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4862 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4863 && (TARGET_64BIT || <MODE>mode != DImode))
4864 && TARGET_SSE_MATH)"
4866 [(set_attr "type" "fisttp")
4867 (set_attr "mode" "<MODE>")])
4870 [(set (match_operand:X87MODEI 0 "register_operand" "")
4871 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4872 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4873 (clobber (match_scratch 3 ""))]
4875 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4876 (clobber (match_dup 3))])
4877 (set (match_dup 0) (match_dup 2))]
4881 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4882 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4884 (clobber (match_scratch 3 ""))]
4886 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4887 (clobber (match_dup 3))])]
4890 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4891 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4892 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4893 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4894 ;; function in i386.c.
4895 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4896 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4897 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4898 (clobber (reg:CC FLAGS_REG))]
4899 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4901 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902 && (TARGET_64BIT || <MODE>mode != DImode))
4903 && !(reload_completed || reload_in_progress)"
4908 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4910 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4911 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4912 if (memory_operand (operands[0], VOIDmode))
4913 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4914 operands[2], operands[3]));
4917 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4918 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4919 operands[2], operands[3],
4924 [(set_attr "type" "fistp")
4925 (set_attr "i387_cw" "trunc")
4926 (set_attr "mode" "<MODE>")])
4928 (define_insn "fix_truncdi_i387"
4929 [(set (match_operand:DI 0 "memory_operand" "=m")
4930 (fix:DI (match_operand 1 "register_operand" "f")))
4931 (use (match_operand:HI 2 "memory_operand" "m"))
4932 (use (match_operand:HI 3 "memory_operand" "m"))
4933 (clobber (match_scratch:XF 4 "=&1f"))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4936 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937 "* return output_fix_trunc (insn, operands, 0);"
4938 [(set_attr "type" "fistp")
4939 (set_attr "i387_cw" "trunc")
4940 (set_attr "mode" "DI")])
4942 (define_insn "fix_truncdi_i387_with_temp"
4943 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4944 (fix:DI (match_operand 1 "register_operand" "f,f")))
4945 (use (match_operand:HI 2 "memory_operand" "m,m"))
4946 (use (match_operand:HI 3 "memory_operand" "m,m"))
4947 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4948 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4949 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4951 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4953 [(set_attr "type" "fistp")
4954 (set_attr "i387_cw" "trunc")
4955 (set_attr "mode" "DI")])
4958 [(set (match_operand:DI 0 "register_operand" "")
4959 (fix:DI (match_operand 1 "register_operand" "")))
4960 (use (match_operand:HI 2 "memory_operand" ""))
4961 (use (match_operand:HI 3 "memory_operand" ""))
4962 (clobber (match_operand:DI 4 "memory_operand" ""))
4963 (clobber (match_scratch 5 ""))]
4965 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4968 (clobber (match_dup 5))])
4969 (set (match_dup 0) (match_dup 4))]
4973 [(set (match_operand:DI 0 "memory_operand" "")
4974 (fix:DI (match_operand 1 "register_operand" "")))
4975 (use (match_operand:HI 2 "memory_operand" ""))
4976 (use (match_operand:HI 3 "memory_operand" ""))
4977 (clobber (match_operand:DI 4 "memory_operand" ""))
4978 (clobber (match_scratch 5 ""))]
4980 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4983 (clobber (match_dup 5))])]
4986 (define_insn "fix_trunc<mode>_i387"
4987 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4988 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4989 (use (match_operand:HI 2 "memory_operand" "m"))
4990 (use (match_operand:HI 3 "memory_operand" "m"))]
4991 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4993 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994 "* return output_fix_trunc (insn, operands, 0);"
4995 [(set_attr "type" "fistp")
4996 (set_attr "i387_cw" "trunc")
4997 (set_attr "mode" "<MODE>")])
4999 (define_insn "fix_trunc<mode>_i387_with_temp"
5000 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5001 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5002 (use (match_operand:HI 2 "memory_operand" "m,m"))
5003 (use (match_operand:HI 3 "memory_operand" "m,m"))
5004 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5005 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5007 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5009 [(set_attr "type" "fistp")
5010 (set_attr "i387_cw" "trunc")
5011 (set_attr "mode" "<MODE>")])
5014 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5015 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5016 (use (match_operand:HI 2 "memory_operand" ""))
5017 (use (match_operand:HI 3 "memory_operand" ""))
5018 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5020 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5022 (use (match_dup 3))])
5023 (set (match_dup 0) (match_dup 4))]
5027 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5028 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5029 (use (match_operand:HI 2 "memory_operand" ""))
5030 (use (match_operand:HI 3 "memory_operand" ""))
5031 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5033 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5035 (use (match_dup 3))])]
5038 (define_insn "x86_fnstcw_1"
5039 [(set (match_operand:HI 0 "memory_operand" "=m")
5040 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5043 [(set_attr "length" "2")
5044 (set_attr "mode" "HI")
5045 (set_attr "unit" "i387")])
5047 (define_insn "x86_fldcw_1"
5048 [(set (reg:HI FPCR_REG)
5049 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5052 [(set_attr "length" "2")
5053 (set_attr "mode" "HI")
5054 (set_attr "unit" "i387")
5055 (set_attr "athlon_decode" "vector")
5056 (set_attr "amdfam10_decode" "vector")])
5058 ;; Conversion between fixed point and floating point.
5060 ;; Even though we only accept memory inputs, the backend _really_
5061 ;; wants to be able to do this between registers.
5063 (define_expand "floathi<mode>2"
5064 [(set (match_operand:X87MODEF 0 "register_operand" "")
5065 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068 || TARGET_MIX_SSE_I387)"
5071 ;; Pre-reload splitter to add memory clobber to the pattern.
5072 (define_insn_and_split "*floathi<mode>2_1"
5073 [(set (match_operand:X87MODEF 0 "register_operand" "")
5074 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077 || TARGET_MIX_SSE_I387)
5078 && !(reload_completed || reload_in_progress)"
5081 [(parallel [(set (match_dup 0)
5082 (float:X87MODEF (match_dup 1)))
5083 (clobber (match_dup 2))])]
5084 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5086 (define_insn "*floathi<mode>2_i387_with_temp"
5087 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5088 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5089 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5092 || TARGET_MIX_SSE_I387)"
5094 [(set_attr "type" "fmov,multi")
5095 (set_attr "mode" "<MODE>")
5096 (set_attr "unit" "*,i387")
5097 (set_attr "fp_int_src" "true")])
5099 (define_insn "*floathi<mode>2_i387"
5100 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5101 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5104 || TARGET_MIX_SSE_I387)"
5106 [(set_attr "type" "fmov")
5107 (set_attr "mode" "<MODE>")
5108 (set_attr "fp_int_src" "true")])
5111 [(set (match_operand:X87MODEF 0 "register_operand" "")
5112 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5113 (clobber (match_operand:HI 2 "memory_operand" ""))]
5115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116 || TARGET_MIX_SSE_I387)
5117 && reload_completed"
5118 [(set (match_dup 2) (match_dup 1))
5119 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5123 [(set (match_operand:X87MODEF 0 "register_operand" "")
5124 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5125 (clobber (match_operand:HI 2 "memory_operand" ""))]
5127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5128 || TARGET_MIX_SSE_I387)
5129 && reload_completed"
5130 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5133 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5134 [(set (match_operand:X87MODEF 0 "register_operand" "")
5136 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5138 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5139 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5142 ;; Pre-reload splitter to add memory clobber to the pattern.
5143 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5144 [(set (match_operand:X87MODEF 0 "register_operand" "")
5145 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5147 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5148 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5149 || TARGET_MIX_SSE_I387))
5150 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5151 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5152 && ((<SSEMODEI24:MODE>mode == SImode
5153 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5154 && optimize_function_for_speed_p (cfun)
5155 && flag_trapping_math)
5156 || !(TARGET_INTER_UNIT_CONVERSIONS
5157 || optimize_function_for_size_p (cfun)))))
5158 && !(reload_completed || reload_in_progress)"
5161 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5162 (clobber (match_dup 2))])]
5164 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5166 /* Avoid store forwarding (partial memory) stall penalty
5167 by passing DImode value through XMM registers. */
5168 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5169 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5170 && optimize_function_for_speed_p (cfun))
5172 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5179 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5180 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5182 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5183 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5184 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5185 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5187 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5188 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5189 (set_attr "unit" "*,i387,*,*,*")
5190 (set_attr "athlon_decode" "*,*,double,direct,double")
5191 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5192 (set_attr "fp_int_src" "true")])
5194 (define_insn "*floatsi<mode>2_vector_mixed"
5195 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5196 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5197 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5198 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5202 [(set_attr "type" "fmov,sseicvt")
5203 (set_attr "mode" "<MODE>,<ssevecmode>")
5204 (set_attr "unit" "i387,*")
5205 (set_attr "athlon_decode" "*,direct")
5206 (set_attr "amdfam10_decode" "*,double")
5207 (set_attr "fp_int_src" "true")])
5209 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5210 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5212 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5213 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5214 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5215 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5217 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5218 (set_attr "mode" "<MODEF:MODE>")
5219 (set_attr "unit" "*,i387,*,*")
5220 (set_attr "athlon_decode" "*,*,double,direct")
5221 (set_attr "amdfam10_decode" "*,*,vector,double")
5222 (set_attr "fp_int_src" "true")])
5225 [(set (match_operand:MODEF 0 "register_operand" "")
5226 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5227 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5228 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5229 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5230 && TARGET_INTER_UNIT_CONVERSIONS
5232 && (SSE_REG_P (operands[0])
5233 || (GET_CODE (operands[0]) == SUBREG
5234 && SSE_REG_P (operands[0])))"
5235 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5239 [(set (match_operand:MODEF 0 "register_operand" "")
5240 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5241 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5242 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5246 && (SSE_REG_P (operands[0])
5247 || (GET_CODE (operands[0]) == SUBREG
5248 && SSE_REG_P (operands[0])))"
5249 [(set (match_dup 2) (match_dup 1))
5250 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5253 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5254 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5256 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5257 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5258 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5259 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5262 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5263 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5264 [(set_attr "type" "fmov,sseicvt,sseicvt")
5265 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5266 (set_attr "mode" "<MODEF:MODE>")
5267 (set_attr "unit" "i387,*,*")
5268 (set_attr "athlon_decode" "*,double,direct")
5269 (set_attr "amdfam10_decode" "*,vector,double")
5270 (set_attr "fp_int_src" "true")])
5272 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5273 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5275 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5276 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5278 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5281 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5282 [(set_attr "type" "fmov,sseicvt")
5283 (set_attr "prefix" "orig,maybe_vex")
5284 (set_attr "mode" "<MODEF:MODE>")
5285 (set_attr "athlon_decode" "*,direct")
5286 (set_attr "amdfam10_decode" "*,double")
5287 (set_attr "fp_int_src" "true")])
5289 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5290 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5292 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5293 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5294 "TARGET_SSE2 && TARGET_SSE_MATH
5295 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5297 [(set_attr "type" "sseicvt")
5298 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5299 (set_attr "athlon_decode" "double,direct,double")
5300 (set_attr "amdfam10_decode" "vector,double,double")
5301 (set_attr "fp_int_src" "true")])
5303 (define_insn "*floatsi<mode>2_vector_sse"
5304 [(set (match_operand:MODEF 0 "register_operand" "=x")
5305 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5306 "TARGET_SSE2 && TARGET_SSE_MATH
5307 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5309 [(set_attr "type" "sseicvt")
5310 (set_attr "mode" "<MODE>")
5311 (set_attr "athlon_decode" "direct")
5312 (set_attr "amdfam10_decode" "double")
5313 (set_attr "fp_int_src" "true")])
5316 [(set (match_operand:MODEF 0 "register_operand" "")
5317 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5318 (clobber (match_operand:SI 2 "memory_operand" ""))]
5319 "TARGET_SSE2 && TARGET_SSE_MATH
5320 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5322 && (SSE_REG_P (operands[0])
5323 || (GET_CODE (operands[0]) == SUBREG
5324 && SSE_REG_P (operands[0])))"
5327 rtx op1 = operands[1];
5329 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5331 if (GET_CODE (op1) == SUBREG)
5332 op1 = SUBREG_REG (op1);
5334 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5336 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5337 emit_insn (gen_sse2_loadld (operands[4],
5338 CONST0_RTX (V4SImode), operands[1]));
5340 /* We can ignore possible trapping value in the
5341 high part of SSE register for non-trapping math. */
5342 else if (SSE_REG_P (op1) && !flag_trapping_math)
5343 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5346 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5347 emit_move_insn (operands[2], operands[1]);
5348 emit_insn (gen_sse2_loadld (operands[4],
5349 CONST0_RTX (V4SImode), operands[2]));
5352 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5357 [(set (match_operand:MODEF 0 "register_operand" "")
5358 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5359 (clobber (match_operand:SI 2 "memory_operand" ""))]
5360 "TARGET_SSE2 && TARGET_SSE_MATH
5361 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5363 && (SSE_REG_P (operands[0])
5364 || (GET_CODE (operands[0]) == SUBREG
5365 && SSE_REG_P (operands[0])))"
5368 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5370 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5372 emit_insn (gen_sse2_loadld (operands[4],
5373 CONST0_RTX (V4SImode), operands[1]));
5375 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5380 [(set (match_operand:MODEF 0 "register_operand" "")
5381 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5382 "TARGET_SSE2 && TARGET_SSE_MATH
5383 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5385 && (SSE_REG_P (operands[0])
5386 || (GET_CODE (operands[0]) == SUBREG
5387 && SSE_REG_P (operands[0])))"
5390 rtx op1 = operands[1];
5392 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5394 if (GET_CODE (op1) == SUBREG)
5395 op1 = SUBREG_REG (op1);
5397 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5399 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5400 emit_insn (gen_sse2_loadld (operands[4],
5401 CONST0_RTX (V4SImode), operands[1]));
5403 /* We can ignore possible trapping value in the
5404 high part of SSE register for non-trapping math. */
5405 else if (SSE_REG_P (op1) && !flag_trapping_math)
5406 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5410 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5415 [(set (match_operand:MODEF 0 "register_operand" "")
5416 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5417 "TARGET_SSE2 && TARGET_SSE_MATH
5418 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5420 && (SSE_REG_P (operands[0])
5421 || (GET_CODE (operands[0]) == SUBREG
5422 && SSE_REG_P (operands[0])))"
5425 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5427 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5429 emit_insn (gen_sse2_loadld (operands[4],
5430 CONST0_RTX (V4SImode), operands[1]));
5432 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5436 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5437 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5439 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5440 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5441 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5444 [(set_attr "type" "sseicvt")
5445 (set_attr "mode" "<MODEF:MODE>")
5446 (set_attr "athlon_decode" "double,direct")
5447 (set_attr "amdfam10_decode" "vector,double")
5448 (set_attr "fp_int_src" "true")])
5450 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5451 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5453 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5454 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5457 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5458 [(set_attr "type" "sseicvt")
5459 (set_attr "prefix" "maybe_vex")
5460 (set_attr "mode" "<MODEF:MODE>")
5461 (set_attr "athlon_decode" "double,direct")
5462 (set_attr "amdfam10_decode" "vector,double")
5463 (set_attr "fp_int_src" "true")])
5466 [(set (match_operand:MODEF 0 "register_operand" "")
5467 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5468 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5469 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5470 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5471 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5473 && (SSE_REG_P (operands[0])
5474 || (GET_CODE (operands[0]) == SUBREG
5475 && SSE_REG_P (operands[0])))"
5476 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5479 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5480 [(set (match_operand:MODEF 0 "register_operand" "=x")
5482 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5483 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5486 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5487 [(set_attr "type" "sseicvt")
5488 (set_attr "prefix" "maybe_vex")
5489 (set_attr "mode" "<MODEF:MODE>")
5490 (set_attr "athlon_decode" "direct")
5491 (set_attr "amdfam10_decode" "double")
5492 (set_attr "fp_int_src" "true")])
5495 [(set (match_operand:MODEF 0 "register_operand" "")
5496 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5497 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5502 && (SSE_REG_P (operands[0])
5503 || (GET_CODE (operands[0]) == SUBREG
5504 && SSE_REG_P (operands[0])))"
5505 [(set (match_dup 2) (match_dup 1))
5506 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5510 [(set (match_operand:MODEF 0 "register_operand" "")
5511 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5512 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5513 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5514 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5516 && (SSE_REG_P (operands[0])
5517 || (GET_CODE (operands[0]) == SUBREG
5518 && SSE_REG_P (operands[0])))"
5519 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5522 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5523 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5525 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5526 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5531 [(set_attr "type" "fmov,multi")
5532 (set_attr "mode" "<X87MODEF:MODE>")
5533 (set_attr "unit" "*,i387")
5534 (set_attr "fp_int_src" "true")])
5536 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5537 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5539 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5542 [(set_attr "type" "fmov")
5543 (set_attr "mode" "<X87MODEF:MODE>")
5544 (set_attr "fp_int_src" "true")])
5547 [(set (match_operand:X87MODEF 0 "register_operand" "")
5548 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5549 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5552 && FP_REG_P (operands[0])"
5553 [(set (match_dup 2) (match_dup 1))
5554 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5558 [(set (match_operand:X87MODEF 0 "register_operand" "")
5559 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5560 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5563 && FP_REG_P (operands[0])"
5564 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5567 ;; Avoid store forwarding (partial memory) stall penalty
5568 ;; by passing DImode value through XMM registers. */
5570 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5571 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5573 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5574 (clobber (match_scratch:V4SI 3 "=X,x"))
5575 (clobber (match_scratch:V4SI 4 "=X,x"))
5576 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5577 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5578 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5580 [(set_attr "type" "multi")
5581 (set_attr "mode" "<X87MODEF:MODE>")
5582 (set_attr "unit" "i387")
5583 (set_attr "fp_int_src" "true")])
5586 [(set (match_operand:X87MODEF 0 "register_operand" "")
5587 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5588 (clobber (match_scratch:V4SI 3 ""))
5589 (clobber (match_scratch:V4SI 4 ""))
5590 (clobber (match_operand:DI 2 "memory_operand" ""))]
5591 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5592 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5594 && FP_REG_P (operands[0])"
5595 [(set (match_dup 2) (match_dup 3))
5596 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5598 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5599 Assemble the 64-bit DImode value in an xmm register. */
5600 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5601 gen_rtx_SUBREG (SImode, operands[1], 0)));
5602 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5603 gen_rtx_SUBREG (SImode, operands[1], 4)));
5604 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5606 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5610 [(set (match_operand:X87MODEF 0 "register_operand" "")
5611 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5612 (clobber (match_scratch:V4SI 3 ""))
5613 (clobber (match_scratch:V4SI 4 ""))
5614 (clobber (match_operand:DI 2 "memory_operand" ""))]
5615 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5616 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5618 && FP_REG_P (operands[0])"
5619 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5622 ;; Avoid store forwarding (partial memory) stall penalty by extending
5623 ;; SImode value to DImode through XMM register instead of pushing two
5624 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5625 ;; targets benefit from this optimization. Also note that fild
5626 ;; loads from memory only.
5628 (define_insn "*floatunssi<mode>2_1"
5629 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5630 (unsigned_float:X87MODEF
5631 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5632 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5633 (clobber (match_scratch:SI 3 "=X,x"))]
5635 && TARGET_80387 && TARGET_SSE"
5637 [(set_attr "type" "multi")
5638 (set_attr "mode" "<MODE>")])
5641 [(set (match_operand:X87MODEF 0 "register_operand" "")
5642 (unsigned_float:X87MODEF
5643 (match_operand:SI 1 "register_operand" "")))
5644 (clobber (match_operand:DI 2 "memory_operand" ""))
5645 (clobber (match_scratch:SI 3 ""))]
5647 && TARGET_80387 && TARGET_SSE
5648 && reload_completed"
5649 [(set (match_dup 2) (match_dup 1))
5651 (float:X87MODEF (match_dup 2)))]
5652 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5655 [(set (match_operand:X87MODEF 0 "register_operand" "")
5656 (unsigned_float:X87MODEF
5657 (match_operand:SI 1 "memory_operand" "")))
5658 (clobber (match_operand:DI 2 "memory_operand" ""))
5659 (clobber (match_scratch:SI 3 ""))]
5661 && TARGET_80387 && TARGET_SSE
5662 && reload_completed"
5663 [(set (match_dup 2) (match_dup 3))
5665 (float:X87MODEF (match_dup 2)))]
5667 emit_move_insn (operands[3], operands[1]);
5668 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5671 (define_expand "floatunssi<mode>2"
5673 [(set (match_operand:X87MODEF 0 "register_operand" "")
5674 (unsigned_float:X87MODEF
5675 (match_operand:SI 1 "nonimmediate_operand" "")))
5676 (clobber (match_dup 2))
5677 (clobber (match_scratch:SI 3 ""))])]
5679 && ((TARGET_80387 && TARGET_SSE)
5680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5682 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5684 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5689 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5690 operands[2] = assign_386_stack_local (DImode, slot);
5694 (define_expand "floatunsdisf2"
5695 [(use (match_operand:SF 0 "register_operand" ""))
5696 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5697 "TARGET_64BIT && TARGET_SSE_MATH"
5698 "x86_emit_floatuns (operands); DONE;")
5700 (define_expand "floatunsdidf2"
5701 [(use (match_operand:DF 0 "register_operand" ""))
5702 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5703 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5704 && TARGET_SSE2 && TARGET_SSE_MATH"
5707 x86_emit_floatuns (operands);
5709 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5715 ;; %%% splits for addditi3
5717 (define_expand "addti3"
5718 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720 (match_operand:TI 2 "x86_64_general_operand" "")))]
5722 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5724 (define_insn "*addti3_1"
5725 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5726 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5727 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5733 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5734 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5735 (match_operand:TI 2 "x86_64_general_operand" "")))
5736 (clobber (reg:CC FLAGS_REG))]
5737 "TARGET_64BIT && reload_completed"
5738 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5740 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5741 (parallel [(set (match_dup 3)
5742 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5745 (clobber (reg:CC FLAGS_REG))])]
5746 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5748 ;; %%% splits for addsidi3
5749 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5750 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5751 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5753 (define_expand "adddi3"
5754 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756 (match_operand:DI 2 "x86_64_general_operand" "")))]
5758 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5760 (define_insn "*adddi3_1"
5761 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5762 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5763 (match_operand:DI 2 "general_operand" "roiF,riF")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5769 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5770 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5771 (match_operand:DI 2 "general_operand" "")))
5772 (clobber (reg:CC FLAGS_REG))]
5773 "!TARGET_64BIT && reload_completed"
5774 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5776 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5777 (parallel [(set (match_dup 3)
5778 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5781 (clobber (reg:CC FLAGS_REG))])]
5782 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5784 (define_insn "adddi3_carry_rex64"
5785 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5787 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5788 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5789 (clobber (reg:CC FLAGS_REG))]
5790 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5791 "adc{q}\t{%2, %0|%0, %2}"
5792 [(set_attr "type" "alu")
5793 (set_attr "pent_pair" "pu")
5794 (set_attr "mode" "DI")])
5796 (define_insn "*adddi3_cc_rex64"
5797 [(set (reg:CC FLAGS_REG)
5798 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5799 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5801 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5802 (plus:DI (match_dup 1) (match_dup 2)))]
5803 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5804 "add{q}\t{%2, %0|%0, %2}"
5805 [(set_attr "type" "alu")
5806 (set_attr "mode" "DI")])
5808 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5809 [(set (reg:CCC FLAGS_REG)
5812 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5813 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5815 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5816 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5817 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5818 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5819 [(set_attr "type" "alu")
5820 (set_attr "mode" "<MODE>")])
5822 (define_insn "*add<mode>3_cconly_overflow"
5823 [(set (reg:CCC FLAGS_REG)
5825 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5826 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5828 (clobber (match_scratch:SWI 0 "=<r>"))]
5829 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5830 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5831 [(set_attr "type" "alu")
5832 (set_attr "mode" "<MODE>")])
5834 (define_insn "*sub<mode>3_cconly_overflow"
5835 [(set (reg:CCC FLAGS_REG)
5837 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5838 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5841 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5842 [(set_attr "type" "icmp")
5843 (set_attr "mode" "<MODE>")])
5845 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5846 [(set (reg:CCC FLAGS_REG)
5848 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5849 (match_operand:SI 2 "general_operand" "g"))
5851 (set (match_operand:DI 0 "register_operand" "=r")
5852 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5853 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5854 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5855 [(set_attr "type" "alu")
5856 (set_attr "mode" "SI")])
5858 (define_insn "addqi3_carry"
5859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5860 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5861 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5862 (match_operand:QI 2 "general_operand" "qn,qm")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5865 "adc{b}\t{%2, %0|%0, %2}"
5866 [(set_attr "type" "alu")
5867 (set_attr "pent_pair" "pu")
5868 (set_attr "mode" "QI")])
5870 (define_insn "addhi3_carry"
5871 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5872 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5873 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5874 (match_operand:HI 2 "general_operand" "rn,rm")))
5875 (clobber (reg:CC FLAGS_REG))]
5876 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5877 "adc{w}\t{%2, %0|%0, %2}"
5878 [(set_attr "type" "alu")
5879 (set_attr "pent_pair" "pu")
5880 (set_attr "mode" "HI")])
5882 (define_insn "addsi3_carry"
5883 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5884 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5885 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5886 (match_operand:SI 2 "general_operand" "ri,rm")))
5887 (clobber (reg:CC FLAGS_REG))]
5888 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5889 "adc{l}\t{%2, %0|%0, %2}"
5890 [(set_attr "type" "alu")
5891 (set_attr "pent_pair" "pu")
5892 (set_attr "mode" "SI")])
5894 (define_insn "*addsi3_carry_zext"
5895 [(set (match_operand:DI 0 "register_operand" "=r")
5897 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5898 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5899 (match_operand:SI 2 "general_operand" "g"))))
5900 (clobber (reg:CC FLAGS_REG))]
5901 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5902 "adc{l}\t{%2, %k0|%k0, %2}"
5903 [(set_attr "type" "alu")
5904 (set_attr "pent_pair" "pu")
5905 (set_attr "mode" "SI")])
5907 (define_insn "*addsi3_cc"
5908 [(set (reg:CC FLAGS_REG)
5909 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5910 (match_operand:SI 2 "general_operand" "ri,rm")]
5912 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5913 (plus:SI (match_dup 1) (match_dup 2)))]
5914 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5915 "add{l}\t{%2, %0|%0, %2}"
5916 [(set_attr "type" "alu")
5917 (set_attr "mode" "SI")])
5919 (define_insn "addqi3_cc"
5920 [(set (reg:CC FLAGS_REG)
5921 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5922 (match_operand:QI 2 "general_operand" "qn,qm")]
5924 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5925 (plus:QI (match_dup 1) (match_dup 2)))]
5926 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5927 "add{b}\t{%2, %0|%0, %2}"
5928 [(set_attr "type" "alu")
5929 (set_attr "mode" "QI")])
5931 (define_expand "addsi3"
5932 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5933 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5934 (match_operand:SI 2 "general_operand" "")))]
5936 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5938 (define_insn "*lea_1"
5939 [(set (match_operand:SI 0 "register_operand" "=r")
5940 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5942 "lea{l}\t{%a1, %0|%0, %a1}"
5943 [(set_attr "type" "lea")
5944 (set_attr "mode" "SI")])
5946 (define_insn "*lea_1_rex64"
5947 [(set (match_operand:SI 0 "register_operand" "=r")
5948 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5950 "lea{l}\t{%a1, %0|%0, %a1}"
5951 [(set_attr "type" "lea")
5952 (set_attr "mode" "SI")])
5954 (define_insn "*lea_1_zext"
5955 [(set (match_operand:DI 0 "register_operand" "=r")
5957 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5959 "lea{l}\t{%a1, %k0|%k0, %a1}"
5960 [(set_attr "type" "lea")
5961 (set_attr "mode" "SI")])
5963 (define_insn "*lea_2_rex64"
5964 [(set (match_operand:DI 0 "register_operand" "=r")
5965 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5967 "lea{q}\t{%a1, %0|%0, %a1}"
5968 [(set_attr "type" "lea")
5969 (set_attr "mode" "DI")])
5971 ;; The lea patterns for non-Pmodes needs to be matched by several
5972 ;; insns converted to real lea by splitters.
5974 (define_insn_and_split "*lea_general_1"
5975 [(set (match_operand 0 "register_operand" "=r")
5976 (plus (plus (match_operand 1 "index_register_operand" "l")
5977 (match_operand 2 "register_operand" "r"))
5978 (match_operand 3 "immediate_operand" "i")))]
5979 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5980 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5981 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5982 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5983 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5984 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5985 || GET_MODE (operands[3]) == VOIDmode)"
5987 "&& reload_completed"
5991 operands[0] = gen_lowpart (SImode, operands[0]);
5992 operands[1] = gen_lowpart (Pmode, operands[1]);
5993 operands[2] = gen_lowpart (Pmode, operands[2]);
5994 operands[3] = gen_lowpart (Pmode, operands[3]);
5995 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5997 if (Pmode != SImode)
5998 pat = gen_rtx_SUBREG (SImode, pat, 0);
5999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6002 [(set_attr "type" "lea")
6003 (set_attr "mode" "SI")])
6005 (define_insn_and_split "*lea_general_1_zext"
6006 [(set (match_operand:DI 0 "register_operand" "=r")
6008 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6009 (match_operand:SI 2 "register_operand" "r"))
6010 (match_operand:SI 3 "immediate_operand" "i"))))]
6013 "&& reload_completed"
6015 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6017 (match_dup 3)) 0)))]
6019 operands[1] = gen_lowpart (Pmode, operands[1]);
6020 operands[2] = gen_lowpart (Pmode, operands[2]);
6021 operands[3] = gen_lowpart (Pmode, operands[3]);
6023 [(set_attr "type" "lea")
6024 (set_attr "mode" "SI")])
6026 (define_insn_and_split "*lea_general_2"
6027 [(set (match_operand 0 "register_operand" "=r")
6028 (plus (mult (match_operand 1 "index_register_operand" "l")
6029 (match_operand 2 "const248_operand" "i"))
6030 (match_operand 3 "nonmemory_operand" "ri")))]
6031 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6032 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6033 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6034 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6036 || GET_MODE (operands[3]) == VOIDmode)"
6038 "&& reload_completed"
6042 operands[0] = gen_lowpart (SImode, operands[0]);
6043 operands[1] = gen_lowpart (Pmode, operands[1]);
6044 operands[3] = gen_lowpart (Pmode, operands[3]);
6045 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6047 if (Pmode != SImode)
6048 pat = gen_rtx_SUBREG (SImode, pat, 0);
6049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6052 [(set_attr "type" "lea")
6053 (set_attr "mode" "SI")])
6055 (define_insn_and_split "*lea_general_2_zext"
6056 [(set (match_operand:DI 0 "register_operand" "=r")
6058 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6059 (match_operand:SI 2 "const248_operand" "n"))
6060 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6063 "&& reload_completed"
6065 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6067 (match_dup 3)) 0)))]
6069 operands[1] = gen_lowpart (Pmode, operands[1]);
6070 operands[3] = gen_lowpart (Pmode, operands[3]);
6072 [(set_attr "type" "lea")
6073 (set_attr "mode" "SI")])
6075 (define_insn_and_split "*lea_general_3"
6076 [(set (match_operand 0 "register_operand" "=r")
6077 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6078 (match_operand 2 "const248_operand" "i"))
6079 (match_operand 3 "register_operand" "r"))
6080 (match_operand 4 "immediate_operand" "i")))]
6081 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6082 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6083 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6084 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6085 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6087 "&& reload_completed"
6091 operands[0] = gen_lowpart (SImode, operands[0]);
6092 operands[1] = gen_lowpart (Pmode, operands[1]);
6093 operands[3] = gen_lowpart (Pmode, operands[3]);
6094 operands[4] = gen_lowpart (Pmode, operands[4]);
6095 pat = gen_rtx_PLUS (Pmode,
6096 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6100 if (Pmode != SImode)
6101 pat = gen_rtx_SUBREG (SImode, pat, 0);
6102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6105 [(set_attr "type" "lea")
6106 (set_attr "mode" "SI")])
6108 (define_insn_and_split "*lea_general_3_zext"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6111 (plus:SI (plus:SI (mult:SI
6112 (match_operand:SI 1 "index_register_operand" "l")
6113 (match_operand:SI 2 "const248_operand" "n"))
6114 (match_operand:SI 3 "register_operand" "r"))
6115 (match_operand:SI 4 "immediate_operand" "i"))))]
6118 "&& reload_completed"
6120 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6123 (match_dup 4)) 0)))]
6125 operands[1] = gen_lowpart (Pmode, operands[1]);
6126 operands[3] = gen_lowpart (Pmode, operands[3]);
6127 operands[4] = gen_lowpart (Pmode, operands[4]);
6129 [(set_attr "type" "lea")
6130 (set_attr "mode" "SI")])
6132 (define_insn "*adddi_1_rex64"
6133 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6134 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6135 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6136 (clobber (reg:CC FLAGS_REG))]
6137 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6139 switch (get_attr_type (insn))
6142 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6143 return "lea{q}\t{%a2, %0|%0, %a2}";
6146 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6147 if (operands[2] == const1_rtx)
6148 return "inc{q}\t%0";
6151 gcc_assert (operands[2] == constm1_rtx);
6152 return "dec{q}\t%0";
6156 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6158 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6159 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6160 if (CONST_INT_P (operands[2])
6161 /* Avoid overflows. */
6162 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
6168 return "sub{q}\t{%2, %0|%0, %2}";
6170 return "add{q}\t{%2, %0|%0, %2}";
6174 (cond [(eq_attr "alternative" "2")
6175 (const_string "lea")
6176 ; Current assemblers are broken and do not allow @GOTOFF in
6177 ; ought but a memory context.
6178 (match_operand:DI 2 "pic_symbolic_operand" "")
6179 (const_string "lea")
6180 (match_operand:DI 2 "incdec_operand" "")
6181 (const_string "incdec")
6183 (const_string "alu")))
6184 (set_attr "mode" "DI")])
6186 ;; Convert lea to the lea pattern to avoid flags dependency.
6188 [(set (match_operand:DI 0 "register_operand" "")
6189 (plus:DI (match_operand:DI 1 "register_operand" "")
6190 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6191 (clobber (reg:CC FLAGS_REG))]
6192 "TARGET_64BIT && reload_completed
6193 && true_regnum (operands[0]) != true_regnum (operands[1])"
6195 (plus:DI (match_dup 1)
6199 (define_insn "*adddi_2_rex64"
6200 [(set (reg FLAGS_REG)
6202 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6203 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6205 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6206 (plus:DI (match_dup 1) (match_dup 2)))]
6207 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6208 && ix86_binary_operator_ok (PLUS, DImode, operands)
6209 /* Current assemblers are broken and do not allow @GOTOFF in
6210 ought but a memory context. */
6211 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6213 switch (get_attr_type (insn))
6216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217 if (operands[2] == const1_rtx)
6218 return "inc{q}\t%0";
6221 gcc_assert (operands[2] == constm1_rtx);
6222 return "dec{q}\t%0";
6226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6227 /* ???? We ought to handle there the 32bit case too
6228 - do we need new constraint? */
6229 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6230 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6231 if (CONST_INT_P (operands[2])
6232 /* Avoid overflows. */
6233 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6234 && (INTVAL (operands[2]) == 128
6235 || (INTVAL (operands[2]) < 0
6236 && INTVAL (operands[2]) != -128)))
6238 operands[2] = GEN_INT (-INTVAL (operands[2]));
6239 return "sub{q}\t{%2, %0|%0, %2}";
6241 return "add{q}\t{%2, %0|%0, %2}";
6245 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6246 (const_string "incdec")
6247 (const_string "alu")))
6248 (set_attr "mode" "DI")])
6250 (define_insn "*adddi_3_rex64"
6251 [(set (reg FLAGS_REG)
6252 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6253 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6254 (clobber (match_scratch:DI 0 "=r"))]
6256 && ix86_match_ccmode (insn, CCZmode)
6257 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6258 /* Current assemblers are broken and do not allow @GOTOFF in
6259 ought but a memory context. */
6260 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6262 switch (get_attr_type (insn))
6265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266 if (operands[2] == const1_rtx)
6267 return "inc{q}\t%0";
6270 gcc_assert (operands[2] == constm1_rtx);
6271 return "dec{q}\t%0";
6275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276 /* ???? We ought to handle there the 32bit case too
6277 - do we need new constraint? */
6278 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6280 if (CONST_INT_P (operands[2])
6281 /* Avoid overflows. */
6282 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6283 && (INTVAL (operands[2]) == 128
6284 || (INTVAL (operands[2]) < 0
6285 && INTVAL (operands[2]) != -128)))
6287 operands[2] = GEN_INT (-INTVAL (operands[2]));
6288 return "sub{q}\t{%2, %0|%0, %2}";
6290 return "add{q}\t{%2, %0|%0, %2}";
6294 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6295 (const_string "incdec")
6296 (const_string "alu")))
6297 (set_attr "mode" "DI")])
6299 ; For comparisons against 1, -1 and 128, we may generate better code
6300 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6301 ; is matched then. We can't accept general immediate, because for
6302 ; case of overflows, the result is messed up.
6303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6306 ; only for comparisons not depending on it.
6307 (define_insn "*adddi_4_rex64"
6308 [(set (reg FLAGS_REG)
6309 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6310 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6311 (clobber (match_scratch:DI 0 "=rm"))]
6313 && ix86_match_ccmode (insn, CCGCmode)"
6315 switch (get_attr_type (insn))
6318 if (operands[2] == constm1_rtx)
6319 return "inc{q}\t%0";
6322 gcc_assert (operands[2] == const1_rtx);
6323 return "dec{q}\t%0";
6327 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6328 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6329 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6330 if ((INTVAL (operands[2]) == -128
6331 || (INTVAL (operands[2]) > 0
6332 && INTVAL (operands[2]) != 128))
6333 /* Avoid overflows. */
6334 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6335 return "sub{q}\t{%2, %0|%0, %2}";
6336 operands[2] = GEN_INT (-INTVAL (operands[2]));
6337 return "add{q}\t{%2, %0|%0, %2}";
6341 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6342 (const_string "incdec")
6343 (const_string "alu")))
6344 (set_attr "mode" "DI")])
6346 (define_insn "*adddi_5_rex64"
6347 [(set (reg FLAGS_REG)
6349 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6350 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6352 (clobber (match_scratch:DI 0 "=r"))]
6354 && ix86_match_ccmode (insn, CCGOCmode)
6355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6356 /* Current assemblers are broken and do not allow @GOTOFF in
6357 ought but a memory context. */
6358 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6360 switch (get_attr_type (insn))
6363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6364 if (operands[2] == const1_rtx)
6365 return "inc{q}\t%0";
6368 gcc_assert (operands[2] == constm1_rtx);
6369 return "dec{q}\t%0";
6373 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6376 if (CONST_INT_P (operands[2])
6377 /* Avoid overflows. */
6378 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6379 && (INTVAL (operands[2]) == 128
6380 || (INTVAL (operands[2]) < 0
6381 && INTVAL (operands[2]) != -128)))
6383 operands[2] = GEN_INT (-INTVAL (operands[2]));
6384 return "sub{q}\t{%2, %0|%0, %2}";
6386 return "add{q}\t{%2, %0|%0, %2}";
6390 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6391 (const_string "incdec")
6392 (const_string "alu")))
6393 (set_attr "mode" "DI")])
6396 (define_insn "*addsi_1"
6397 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6398 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6399 (match_operand:SI 2 "general_operand" "g,ri,li")))
6400 (clobber (reg:CC FLAGS_REG))]
6401 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6403 switch (get_attr_type (insn))
6406 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6407 return "lea{l}\t{%a2, %0|%0, %a2}";
6410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411 if (operands[2] == const1_rtx)
6412 return "inc{l}\t%0";
6415 gcc_assert (operands[2] == constm1_rtx);
6416 return "dec{l}\t%0";
6420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6422 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
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{l}\t{%2, %0|%0, %2}";
6432 return "add{l}\t{%2, %0|%0, %2}";
6436 (cond [(eq_attr "alternative" "2")
6437 (const_string "lea")
6438 ; Current assemblers are broken and do not allow @GOTOFF in
6439 ; ought but a memory context.
6440 (match_operand:SI 2 "pic_symbolic_operand" "")
6441 (const_string "lea")
6442 (match_operand:SI 2 "incdec_operand" "")
6443 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "SI")])
6448 ;; Convert lea to the lea pattern to avoid flags dependency.
6450 [(set (match_operand 0 "register_operand" "")
6451 (plus (match_operand 1 "register_operand" "")
6452 (match_operand 2 "nonmemory_operand" "")))
6453 (clobber (reg:CC FLAGS_REG))]
6455 && true_regnum (operands[0]) != true_regnum (operands[1])"
6459 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6460 may confuse gen_lowpart. */
6461 if (GET_MODE (operands[0]) != Pmode)
6463 operands[1] = gen_lowpart (Pmode, operands[1]);
6464 operands[2] = gen_lowpart (Pmode, operands[2]);
6466 operands[0] = gen_lowpart (SImode, operands[0]);
6467 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6468 if (Pmode != SImode)
6469 pat = gen_rtx_SUBREG (SImode, pat, 0);
6470 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6474 ;; It may seem that nonimmediate operand is proper one for operand 1.
6475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6476 ;; we take care in ix86_binary_operator_ok to not allow two memory
6477 ;; operands so proper swapping will be done in reload. This allow
6478 ;; patterns constructed from addsi_1 to match.
6479 (define_insn "addsi_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r,r")
6482 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6483 (match_operand:SI 2 "general_operand" "g,li"))))
6484 (clobber (reg:CC FLAGS_REG))]
6485 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6487 switch (get_attr_type (insn))
6490 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6491 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6494 if (operands[2] == const1_rtx)
6495 return "inc{l}\t%k0";
6498 gcc_assert (operands[2] == constm1_rtx);
6499 return "dec{l}\t%k0";
6503 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6505 if (CONST_INT_P (operands[2])
6506 && (INTVAL (operands[2]) == 128
6507 || (INTVAL (operands[2]) < 0
6508 && INTVAL (operands[2]) != -128)))
6510 operands[2] = GEN_INT (-INTVAL (operands[2]));
6511 return "sub{l}\t{%2, %k0|%k0, %2}";
6513 return "add{l}\t{%2, %k0|%k0, %2}";
6517 (cond [(eq_attr "alternative" "1")
6518 (const_string "lea")
6519 ; Current assemblers are broken and do not allow @GOTOFF in
6520 ; ought but a memory context.
6521 (match_operand:SI 2 "pic_symbolic_operand" "")
6522 (const_string "lea")
6523 (match_operand:SI 2 "incdec_operand" "")
6524 (const_string "incdec")
6526 (const_string "alu")))
6527 (set_attr "mode" "SI")])
6529 ;; Convert lea to the lea pattern to avoid flags dependency.
6531 [(set (match_operand:DI 0 "register_operand" "")
6533 (plus:SI (match_operand:SI 1 "register_operand" "")
6534 (match_operand:SI 2 "nonmemory_operand" ""))))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "TARGET_64BIT && reload_completed
6537 && true_regnum (operands[0]) != true_regnum (operands[1])"
6539 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6541 operands[1] = gen_lowpart (Pmode, operands[1]);
6542 operands[2] = gen_lowpart (Pmode, operands[2]);
6545 (define_insn "*addsi_2"
6546 [(set (reg FLAGS_REG)
6548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6549 (match_operand:SI 2 "general_operand" "g,ri"))
6551 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6552 (plus:SI (match_dup 1) (match_dup 2)))]
6553 "ix86_match_ccmode (insn, CCGOCmode)
6554 && ix86_binary_operator_ok (PLUS, SImode, operands)
6555 /* Current assemblers are broken and do not allow @GOTOFF in
6556 ought but a memory context. */
6557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6559 switch (get_attr_type (insn))
6562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6563 if (operands[2] == const1_rtx)
6564 return "inc{l}\t%0";
6567 gcc_assert (operands[2] == constm1_rtx);
6568 return "dec{l}\t%0";
6572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6575 if (CONST_INT_P (operands[2])
6576 && (INTVAL (operands[2]) == 128
6577 || (INTVAL (operands[2]) < 0
6578 && INTVAL (operands[2]) != -128)))
6580 operands[2] = GEN_INT (-INTVAL (operands[2]));
6581 return "sub{l}\t{%2, %0|%0, %2}";
6583 return "add{l}\t{%2, %0|%0, %2}";
6587 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6588 (const_string "incdec")
6589 (const_string "alu")))
6590 (set_attr "mode" "SI")])
6592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6593 (define_insn "*addsi_2_zext"
6594 [(set (reg FLAGS_REG)
6596 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6597 (match_operand:SI 2 "general_operand" "g"))
6599 (set (match_operand:DI 0 "register_operand" "=r")
6600 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6601 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6602 && ix86_binary_operator_ok (PLUS, SImode, operands)
6603 /* Current assemblers are broken and do not allow @GOTOFF in
6604 ought but a memory context. */
6605 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6607 switch (get_attr_type (insn))
6610 if (operands[2] == const1_rtx)
6611 return "inc{l}\t%k0";
6614 gcc_assert (operands[2] == constm1_rtx);
6615 return "dec{l}\t%k0";
6619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6621 if (CONST_INT_P (operands[2])
6622 && (INTVAL (operands[2]) == 128
6623 || (INTVAL (operands[2]) < 0
6624 && INTVAL (operands[2]) != -128)))
6626 operands[2] = GEN_INT (-INTVAL (operands[2]));
6627 return "sub{l}\t{%2, %k0|%k0, %2}";
6629 return "add{l}\t{%2, %k0|%k0, %2}";
6633 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6634 (const_string "incdec")
6635 (const_string "alu")))
6636 (set_attr "mode" "SI")])
6638 (define_insn "*addsi_3"
6639 [(set (reg FLAGS_REG)
6640 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6641 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6642 (clobber (match_scratch:SI 0 "=r"))]
6643 "ix86_match_ccmode (insn, CCZmode)
6644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6645 /* Current assemblers are broken and do not allow @GOTOFF in
6646 ought but a memory context. */
6647 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6649 switch (get_attr_type (insn))
6652 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6653 if (operands[2] == const1_rtx)
6654 return "inc{l}\t%0";
6657 gcc_assert (operands[2] == constm1_rtx);
6658 return "dec{l}\t%0";
6662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6663 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6664 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6665 if (CONST_INT_P (operands[2])
6666 && (INTVAL (operands[2]) == 128
6667 || (INTVAL (operands[2]) < 0
6668 && INTVAL (operands[2]) != -128)))
6670 operands[2] = GEN_INT (-INTVAL (operands[2]));
6671 return "sub{l}\t{%2, %0|%0, %2}";
6673 return "add{l}\t{%2, %0|%0, %2}";
6677 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6678 (const_string "incdec")
6679 (const_string "alu")))
6680 (set_attr "mode" "SI")])
6682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6683 (define_insn "*addsi_3_zext"
6684 [(set (reg FLAGS_REG)
6685 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6686 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6687 (set (match_operand:DI 0 "register_operand" "=r")
6688 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6689 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6690 && ix86_binary_operator_ok (PLUS, SImode, operands)
6691 /* Current assemblers are broken and do not allow @GOTOFF in
6692 ought but a memory context. */
6693 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6695 switch (get_attr_type (insn))
6698 if (operands[2] == const1_rtx)
6699 return "inc{l}\t%k0";
6702 gcc_assert (operands[2] == constm1_rtx);
6703 return "dec{l}\t%k0";
6707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6709 if (CONST_INT_P (operands[2])
6710 && (INTVAL (operands[2]) == 128
6711 || (INTVAL (operands[2]) < 0
6712 && INTVAL (operands[2]) != -128)))
6714 operands[2] = GEN_INT (-INTVAL (operands[2]));
6715 return "sub{l}\t{%2, %k0|%k0, %2}";
6717 return "add{l}\t{%2, %k0|%k0, %2}";
6721 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6722 (const_string "incdec")
6723 (const_string "alu")))
6724 (set_attr "mode" "SI")])
6726 ; For comparisons against 1, -1 and 128, we may generate better code
6727 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6728 ; is matched then. We can't accept general immediate, because for
6729 ; case of overflows, the result is messed up.
6730 ; This pattern also don't hold of 0x80000000, since the value overflows
6732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6733 ; only for comparisons not depending on it.
6734 (define_insn "*addsi_4"
6735 [(set (reg FLAGS_REG)
6736 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6737 (match_operand:SI 2 "const_int_operand" "n")))
6738 (clobber (match_scratch:SI 0 "=rm"))]
6739 "ix86_match_ccmode (insn, CCGCmode)
6740 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6742 switch (get_attr_type (insn))
6745 if (operands[2] == constm1_rtx)
6746 return "inc{l}\t%0";
6749 gcc_assert (operands[2] == const1_rtx);
6750 return "dec{l}\t%0";
6754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6757 if ((INTVAL (operands[2]) == -128
6758 || (INTVAL (operands[2]) > 0
6759 && INTVAL (operands[2]) != 128)))
6760 return "sub{l}\t{%2, %0|%0, %2}";
6761 operands[2] = GEN_INT (-INTVAL (operands[2]));
6762 return "add{l}\t{%2, %0|%0, %2}";
6766 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6767 (const_string "incdec")
6768 (const_string "alu")))
6769 (set_attr "mode" "SI")])
6771 (define_insn "*addsi_5"
6772 [(set (reg FLAGS_REG)
6774 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6775 (match_operand:SI 2 "general_operand" "g"))
6777 (clobber (match_scratch:SI 0 "=r"))]
6778 "ix86_match_ccmode (insn, CCGOCmode)
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6780 /* Current assemblers are broken and do not allow @GOTOFF in
6781 ought but a memory context. */
6782 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6784 switch (get_attr_type (insn))
6787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6788 if (operands[2] == const1_rtx)
6789 return "inc{l}\t%0";
6792 gcc_assert (operands[2] == constm1_rtx);
6793 return "dec{l}\t%0";
6797 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6800 if (CONST_INT_P (operands[2])
6801 && (INTVAL (operands[2]) == 128
6802 || (INTVAL (operands[2]) < 0
6803 && INTVAL (operands[2]) != -128)))
6805 operands[2] = GEN_INT (-INTVAL (operands[2]));
6806 return "sub{l}\t{%2, %0|%0, %2}";
6808 return "add{l}\t{%2, %0|%0, %2}";
6812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6813 (const_string "incdec")
6814 (const_string "alu")))
6815 (set_attr "mode" "SI")])
6817 (define_expand "addhi3"
6818 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6819 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6820 (match_operand:HI 2 "general_operand" "")))]
6821 "TARGET_HIMODE_MATH"
6822 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6824 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6825 ;; type optimizations enabled by define-splits. This is not important
6826 ;; for PII, and in fact harmful because of partial register stalls.
6828 (define_insn "*addhi_1_lea"
6829 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6830 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6831 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6832 (clobber (reg:CC FLAGS_REG))]
6833 "!TARGET_PARTIAL_REG_STALL
6834 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6836 switch (get_attr_type (insn))
6841 if (operands[2] == const1_rtx)
6842 return "inc{w}\t%0";
6845 gcc_assert (operands[2] == constm1_rtx);
6846 return "dec{w}\t%0";
6850 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6851 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6852 if (CONST_INT_P (operands[2])
6853 && (INTVAL (operands[2]) == 128
6854 || (INTVAL (operands[2]) < 0
6855 && INTVAL (operands[2]) != -128)))
6857 operands[2] = GEN_INT (-INTVAL (operands[2]));
6858 return "sub{w}\t{%2, %0|%0, %2}";
6860 return "add{w}\t{%2, %0|%0, %2}";
6864 (if_then_else (eq_attr "alternative" "2")
6865 (const_string "lea")
6866 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6867 (const_string "incdec")
6868 (const_string "alu"))))
6869 (set_attr "mode" "HI,HI,SI")])
6871 (define_insn "*addhi_1"
6872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6873 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6874 (match_operand:HI 2 "general_operand" "rn,rm")))
6875 (clobber (reg:CC FLAGS_REG))]
6876 "TARGET_PARTIAL_REG_STALL
6877 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6879 switch (get_attr_type (insn))
6882 if (operands[2] == const1_rtx)
6883 return "inc{w}\t%0";
6886 gcc_assert (operands[2] == constm1_rtx);
6887 return "dec{w}\t%0";
6891 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6892 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6893 if (CONST_INT_P (operands[2])
6894 && (INTVAL (operands[2]) == 128
6895 || (INTVAL (operands[2]) < 0
6896 && INTVAL (operands[2]) != -128)))
6898 operands[2] = GEN_INT (-INTVAL (operands[2]));
6899 return "sub{w}\t{%2, %0|%0, %2}";
6901 return "add{w}\t{%2, %0|%0, %2}";
6905 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6906 (const_string "incdec")
6907 (const_string "alu")))
6908 (set_attr "mode" "HI")])
6910 (define_insn "*addhi_2"
6911 [(set (reg FLAGS_REG)
6913 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6914 (match_operand:HI 2 "general_operand" "rmn,rn"))
6916 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6917 (plus:HI (match_dup 1) (match_dup 2)))]
6918 "ix86_match_ccmode (insn, CCGOCmode)
6919 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6921 switch (get_attr_type (insn))
6924 if (operands[2] == const1_rtx)
6925 return "inc{w}\t%0";
6928 gcc_assert (operands[2] == constm1_rtx);
6929 return "dec{w}\t%0";
6933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6935 if (CONST_INT_P (operands[2])
6936 && (INTVAL (operands[2]) == 128
6937 || (INTVAL (operands[2]) < 0
6938 && INTVAL (operands[2]) != -128)))
6940 operands[2] = GEN_INT (-INTVAL (operands[2]));
6941 return "sub{w}\t{%2, %0|%0, %2}";
6943 return "add{w}\t{%2, %0|%0, %2}";
6947 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6948 (const_string "incdec")
6949 (const_string "alu")))
6950 (set_attr "mode" "HI")])
6952 (define_insn "*addhi_3"
6953 [(set (reg FLAGS_REG)
6954 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6955 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6956 (clobber (match_scratch:HI 0 "=r"))]
6957 "ix86_match_ccmode (insn, CCZmode)
6958 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960 switch (get_attr_type (insn))
6963 if (operands[2] == const1_rtx)
6964 return "inc{w}\t%0";
6967 gcc_assert (operands[2] == constm1_rtx);
6968 return "dec{w}\t%0";
6972 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6973 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6974 if (CONST_INT_P (operands[2])
6975 && (INTVAL (operands[2]) == 128
6976 || (INTVAL (operands[2]) < 0
6977 && INTVAL (operands[2]) != -128)))
6979 operands[2] = GEN_INT (-INTVAL (operands[2]));
6980 return "sub{w}\t{%2, %0|%0, %2}";
6982 return "add{w}\t{%2, %0|%0, %2}";
6986 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6987 (const_string "incdec")
6988 (const_string "alu")))
6989 (set_attr "mode" "HI")])
6991 ; See comments above addsi_4 for details.
6992 (define_insn "*addhi_4"
6993 [(set (reg FLAGS_REG)
6994 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6995 (match_operand:HI 2 "const_int_operand" "n")))
6996 (clobber (match_scratch:HI 0 "=rm"))]
6997 "ix86_match_ccmode (insn, CCGCmode)
6998 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7000 switch (get_attr_type (insn))
7003 if (operands[2] == constm1_rtx)
7004 return "inc{w}\t%0";
7007 gcc_assert (operands[2] == const1_rtx);
7008 return "dec{w}\t%0";
7012 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7013 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7014 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7015 if ((INTVAL (operands[2]) == -128
7016 || (INTVAL (operands[2]) > 0
7017 && INTVAL (operands[2]) != 128)))
7018 return "sub{w}\t{%2, %0|%0, %2}";
7019 operands[2] = GEN_INT (-INTVAL (operands[2]));
7020 return "add{w}\t{%2, %0|%0, %2}";
7024 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025 (const_string "incdec")
7026 (const_string "alu")))
7027 (set_attr "mode" "SI")])
7030 (define_insn "*addhi_5"
7031 [(set (reg FLAGS_REG)
7033 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7034 (match_operand:HI 2 "general_operand" "rmn"))
7036 (clobber (match_scratch:HI 0 "=r"))]
7037 "ix86_match_ccmode (insn, CCGOCmode)
7038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7040 switch (get_attr_type (insn))
7043 if (operands[2] == const1_rtx)
7044 return "inc{w}\t%0";
7047 gcc_assert (operands[2] == constm1_rtx);
7048 return "dec{w}\t%0";
7052 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7053 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7054 if (CONST_INT_P (operands[2])
7055 && (INTVAL (operands[2]) == 128
7056 || (INTVAL (operands[2]) < 0
7057 && INTVAL (operands[2]) != -128)))
7059 operands[2] = GEN_INT (-INTVAL (operands[2]));
7060 return "sub{w}\t{%2, %0|%0, %2}";
7062 return "add{w}\t{%2, %0|%0, %2}";
7066 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7067 (const_string "incdec")
7068 (const_string "alu")))
7069 (set_attr "mode" "HI")])
7071 (define_expand "addqi3"
7072 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7073 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7074 (match_operand:QI 2 "general_operand" "")))]
7075 "TARGET_QIMODE_MATH"
7076 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7078 ;; %%% Potential partial reg stall on alternative 2. What to do?
7079 (define_insn "*addqi_1_lea"
7080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7081 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7082 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7083 (clobber (reg:CC FLAGS_REG))]
7084 "!TARGET_PARTIAL_REG_STALL
7085 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7087 int widen = (which_alternative == 2);
7088 switch (get_attr_type (insn))
7093 if (operands[2] == const1_rtx)
7094 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7097 gcc_assert (operands[2] == constm1_rtx);
7098 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7102 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7103 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7104 if (CONST_INT_P (operands[2])
7105 && (INTVAL (operands[2]) == 128
7106 || (INTVAL (operands[2]) < 0
7107 && INTVAL (operands[2]) != -128)))
7109 operands[2] = GEN_INT (-INTVAL (operands[2]));
7111 return "sub{l}\t{%2, %k0|%k0, %2}";
7113 return "sub{b}\t{%2, %0|%0, %2}";
7116 return "add{l}\t{%k2, %k0|%k0, %k2}";
7118 return "add{b}\t{%2, %0|%0, %2}";
7122 (if_then_else (eq_attr "alternative" "3")
7123 (const_string "lea")
7124 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7125 (const_string "incdec")
7126 (const_string "alu"))))
7127 (set_attr "mode" "QI,QI,SI,SI")])
7129 (define_insn "*addqi_1"
7130 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7131 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7132 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7133 (clobber (reg:CC FLAGS_REG))]
7134 "TARGET_PARTIAL_REG_STALL
7135 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7137 int widen = (which_alternative == 2);
7138 switch (get_attr_type (insn))
7141 if (operands[2] == const1_rtx)
7142 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7145 gcc_assert (operands[2] == constm1_rtx);
7146 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7150 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7151 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7152 if (CONST_INT_P (operands[2])
7153 && (INTVAL (operands[2]) == 128
7154 || (INTVAL (operands[2]) < 0
7155 && INTVAL (operands[2]) != -128)))
7157 operands[2] = GEN_INT (-INTVAL (operands[2]));
7159 return "sub{l}\t{%2, %k0|%k0, %2}";
7161 return "sub{b}\t{%2, %0|%0, %2}";
7164 return "add{l}\t{%k2, %k0|%k0, %k2}";
7166 return "add{b}\t{%2, %0|%0, %2}";
7170 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7171 (const_string "incdec")
7172 (const_string "alu")))
7173 (set_attr "mode" "QI,QI,SI")])
7175 (define_insn "*addqi_1_slp"
7176 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7177 (plus:QI (match_dup 0)
7178 (match_operand:QI 1 "general_operand" "qn,qnm")))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7181 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7183 switch (get_attr_type (insn))
7186 if (operands[1] == const1_rtx)
7187 return "inc{b}\t%0";
7190 gcc_assert (operands[1] == constm1_rtx);
7191 return "dec{b}\t%0";
7195 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7196 if (CONST_INT_P (operands[1])
7197 && INTVAL (operands[1]) < 0)
7199 operands[1] = GEN_INT (-INTVAL (operands[1]));
7200 return "sub{b}\t{%1, %0|%0, %1}";
7202 return "add{b}\t{%1, %0|%0, %1}";
7206 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7207 (const_string "incdec")
7208 (const_string "alu1")))
7209 (set (attr "memory")
7210 (if_then_else (match_operand 1 "memory_operand" "")
7211 (const_string "load")
7212 (const_string "none")))
7213 (set_attr "mode" "QI")])
7215 (define_insn "*addqi_2"
7216 [(set (reg FLAGS_REG)
7218 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7219 (match_operand:QI 2 "general_operand" "qmn,qn"))
7221 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7222 (plus:QI (match_dup 1) (match_dup 2)))]
7223 "ix86_match_ccmode (insn, CCGOCmode)
7224 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7226 switch (get_attr_type (insn))
7229 if (operands[2] == const1_rtx)
7230 return "inc{b}\t%0";
7233 gcc_assert (operands[2] == constm1_rtx
7234 || (CONST_INT_P (operands[2])
7235 && INTVAL (operands[2]) == 255));
7236 return "dec{b}\t%0";
7240 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7241 if (CONST_INT_P (operands[2])
7242 && INTVAL (operands[2]) < 0)
7244 operands[2] = GEN_INT (-INTVAL (operands[2]));
7245 return "sub{b}\t{%2, %0|%0, %2}";
7247 return "add{b}\t{%2, %0|%0, %2}";
7251 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7252 (const_string "incdec")
7253 (const_string "alu")))
7254 (set_attr "mode" "QI")])
7256 (define_insn "*addqi_3"
7257 [(set (reg FLAGS_REG)
7258 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7259 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7260 (clobber (match_scratch:QI 0 "=q"))]
7261 "ix86_match_ccmode (insn, CCZmode)
7262 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7264 switch (get_attr_type (insn))
7267 if (operands[2] == const1_rtx)
7268 return "inc{b}\t%0";
7271 gcc_assert (operands[2] == constm1_rtx
7272 || (CONST_INT_P (operands[2])
7273 && INTVAL (operands[2]) == 255));
7274 return "dec{b}\t%0";
7278 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7279 if (CONST_INT_P (operands[2])
7280 && INTVAL (operands[2]) < 0)
7282 operands[2] = GEN_INT (-INTVAL (operands[2]));
7283 return "sub{b}\t{%2, %0|%0, %2}";
7285 return "add{b}\t{%2, %0|%0, %2}";
7289 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7290 (const_string "incdec")
7291 (const_string "alu")))
7292 (set_attr "mode" "QI")])
7294 ; See comments above addsi_4 for details.
7295 (define_insn "*addqi_4"
7296 [(set (reg FLAGS_REG)
7297 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7298 (match_operand:QI 2 "const_int_operand" "n")))
7299 (clobber (match_scratch:QI 0 "=qm"))]
7300 "ix86_match_ccmode (insn, CCGCmode)
7301 && (INTVAL (operands[2]) & 0xff) != 0x80"
7303 switch (get_attr_type (insn))
7306 if (operands[2] == constm1_rtx
7307 || (CONST_INT_P (operands[2])
7308 && INTVAL (operands[2]) == 255))
7309 return "inc{b}\t%0";
7312 gcc_assert (operands[2] == const1_rtx);
7313 return "dec{b}\t%0";
7317 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7318 if (INTVAL (operands[2]) < 0)
7320 operands[2] = GEN_INT (-INTVAL (operands[2]));
7321 return "add{b}\t{%2, %0|%0, %2}";
7323 return "sub{b}\t{%2, %0|%0, %2}";
7327 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7328 (const_string "incdec")
7329 (const_string "alu")))
7330 (set_attr "mode" "QI")])
7333 (define_insn "*addqi_5"
7334 [(set (reg FLAGS_REG)
7336 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7337 (match_operand:QI 2 "general_operand" "qmn"))
7339 (clobber (match_scratch:QI 0 "=q"))]
7340 "ix86_match_ccmode (insn, CCGOCmode)
7341 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7343 switch (get_attr_type (insn))
7346 if (operands[2] == const1_rtx)
7347 return "inc{b}\t%0";
7350 gcc_assert (operands[2] == constm1_rtx
7351 || (CONST_INT_P (operands[2])
7352 && INTVAL (operands[2]) == 255));
7353 return "dec{b}\t%0";
7357 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7358 if (CONST_INT_P (operands[2])
7359 && INTVAL (operands[2]) < 0)
7361 operands[2] = GEN_INT (-INTVAL (operands[2]));
7362 return "sub{b}\t{%2, %0|%0, %2}";
7364 return "add{b}\t{%2, %0|%0, %2}";
7368 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7369 (const_string "incdec")
7370 (const_string "alu")))
7371 (set_attr "mode" "QI")])
7374 (define_insn "addqi_ext_1"
7375 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7380 (match_operand 1 "ext_register_operand" "0")
7383 (match_operand:QI 2 "general_operand" "Qmn")))
7384 (clobber (reg:CC FLAGS_REG))]
7387 switch (get_attr_type (insn))
7390 if (operands[2] == const1_rtx)
7391 return "inc{b}\t%h0";
7394 gcc_assert (operands[2] == constm1_rtx
7395 || (CONST_INT_P (operands[2])
7396 && INTVAL (operands[2]) == 255));
7397 return "dec{b}\t%h0";
7401 return "add{b}\t{%2, %h0|%h0, %2}";
7405 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7406 (const_string "incdec")
7407 (const_string "alu")))
7408 (set_attr "mode" "QI")])
7410 (define_insn "*addqi_ext_1_rex64"
7411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7416 (match_operand 1 "ext_register_operand" "0")
7419 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7420 (clobber (reg:CC FLAGS_REG))]
7423 switch (get_attr_type (insn))
7426 if (operands[2] == const1_rtx)
7427 return "inc{b}\t%h0";
7430 gcc_assert (operands[2] == constm1_rtx
7431 || (CONST_INT_P (operands[2])
7432 && INTVAL (operands[2]) == 255));
7433 return "dec{b}\t%h0";
7437 return "add{b}\t{%2, %h0|%h0, %2}";
7441 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7442 (const_string "incdec")
7443 (const_string "alu")))
7444 (set_attr "mode" "QI")])
7446 (define_insn "*addqi_ext_2"
7447 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7452 (match_operand 1 "ext_register_operand" "%0")
7456 (match_operand 2 "ext_register_operand" "Q")
7459 (clobber (reg:CC FLAGS_REG))]
7461 "add{b}\t{%h2, %h0|%h0, %h2}"
7462 [(set_attr "type" "alu")
7463 (set_attr "mode" "QI")])
7465 ;; The patterns that match these are at the end of this file.
7467 (define_expand "addxf3"
7468 [(set (match_operand:XF 0 "register_operand" "")
7469 (plus:XF (match_operand:XF 1 "register_operand" "")
7470 (match_operand:XF 2 "register_operand" "")))]
7474 (define_expand "add<mode>3"
7475 [(set (match_operand:MODEF 0 "register_operand" "")
7476 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7477 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7478 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7481 ;; Subtract instructions
7483 ;; %%% splits for subditi3
7485 (define_expand "subti3"
7486 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488 (match_operand:TI 2 "x86_64_general_operand" "")))]
7490 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7492 (define_insn "*subti3_1"
7493 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7494 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7495 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7496 (clobber (reg:CC FLAGS_REG))]
7497 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7501 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7502 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7503 (match_operand:TI 2 "x86_64_general_operand" "")))
7504 (clobber (reg:CC FLAGS_REG))]
7505 "TARGET_64BIT && reload_completed"
7506 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7507 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7508 (parallel [(set (match_dup 3)
7509 (minus:DI (match_dup 4)
7510 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7512 (clobber (reg:CC FLAGS_REG))])]
7513 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7515 ;; %%% splits for subsidi3
7517 (define_expand "subdi3"
7518 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520 (match_operand:DI 2 "x86_64_general_operand" "")))]
7522 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7524 (define_insn "*subdi3_1"
7525 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7526 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7527 (match_operand:DI 2 "general_operand" "roiF,riF")))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7533 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7535 (match_operand:DI 2 "general_operand" "")))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "!TARGET_64BIT && reload_completed"
7538 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7539 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7540 (parallel [(set (match_dup 3)
7541 (minus:SI (match_dup 4)
7542 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7544 (clobber (reg:CC FLAGS_REG))])]
7545 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7547 (define_insn "subdi3_carry_rex64"
7548 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7549 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7550 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7551 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7552 (clobber (reg:CC FLAGS_REG))]
7553 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7554 "sbb{q}\t{%2, %0|%0, %2}"
7555 [(set_attr "type" "alu")
7556 (set_attr "pent_pair" "pu")
7557 (set_attr "mode" "DI")])
7559 (define_insn "*subdi_1_rex64"
7560 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7562 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7563 (clobber (reg:CC FLAGS_REG))]
7564 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7565 "sub{q}\t{%2, %0|%0, %2}"
7566 [(set_attr "type" "alu")
7567 (set_attr "mode" "DI")])
7569 (define_insn "*subdi_2_rex64"
7570 [(set (reg FLAGS_REG)
7572 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7573 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7575 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7576 (minus:DI (match_dup 1) (match_dup 2)))]
7577 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7578 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7579 "sub{q}\t{%2, %0|%0, %2}"
7580 [(set_attr "type" "alu")
7581 (set_attr "mode" "DI")])
7583 (define_insn "*subdi_3_rex63"
7584 [(set (reg FLAGS_REG)
7585 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7586 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7587 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7588 (minus:DI (match_dup 1) (match_dup 2)))]
7589 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7590 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7591 "sub{q}\t{%2, %0|%0, %2}"
7592 [(set_attr "type" "alu")
7593 (set_attr "mode" "DI")])
7595 (define_insn "subqi3_carry"
7596 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7597 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7598 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7599 (match_operand:QI 2 "general_operand" "qn,qm"))))
7600 (clobber (reg:CC FLAGS_REG))]
7601 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7602 "sbb{b}\t{%2, %0|%0, %2}"
7603 [(set_attr "type" "alu")
7604 (set_attr "pent_pair" "pu")
7605 (set_attr "mode" "QI")])
7607 (define_insn "subhi3_carry"
7608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7609 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7610 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7611 (match_operand:HI 2 "general_operand" "rn,rm"))))
7612 (clobber (reg:CC FLAGS_REG))]
7613 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7614 "sbb{w}\t{%2, %0|%0, %2}"
7615 [(set_attr "type" "alu")
7616 (set_attr "pent_pair" "pu")
7617 (set_attr "mode" "HI")])
7619 (define_insn "subsi3_carry"
7620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7621 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7622 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7623 (match_operand:SI 2 "general_operand" "ri,rm"))))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7626 "sbb{l}\t{%2, %0|%0, %2}"
7627 [(set_attr "type" "alu")
7628 (set_attr "pent_pair" "pu")
7629 (set_attr "mode" "SI")])
7631 (define_insn "subsi3_carry_zext"
7632 [(set (match_operand:DI 0 "register_operand" "=r")
7634 (minus:SI (match_operand:SI 1 "register_operand" "0")
7635 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7636 (match_operand:SI 2 "general_operand" "g")))))
7637 (clobber (reg:CC FLAGS_REG))]
7638 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7639 "sbb{l}\t{%2, %k0|%k0, %2}"
7640 [(set_attr "type" "alu")
7641 (set_attr "pent_pair" "pu")
7642 (set_attr "mode" "SI")])
7644 (define_expand "subsi3"
7645 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7646 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7647 (match_operand:SI 2 "general_operand" "")))]
7649 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7651 (define_insn "*subsi_1"
7652 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7653 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7654 (match_operand:SI 2 "general_operand" "ri,rm")))
7655 (clobber (reg:CC FLAGS_REG))]
7656 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7657 "sub{l}\t{%2, %0|%0, %2}"
7658 [(set_attr "type" "alu")
7659 (set_attr "mode" "SI")])
7661 (define_insn "*subsi_1_zext"
7662 [(set (match_operand:DI 0 "register_operand" "=r")
7664 (minus:SI (match_operand:SI 1 "register_operand" "0")
7665 (match_operand:SI 2 "general_operand" "g"))))
7666 (clobber (reg:CC FLAGS_REG))]
7667 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7668 "sub{l}\t{%2, %k0|%k0, %2}"
7669 [(set_attr "type" "alu")
7670 (set_attr "mode" "SI")])
7672 (define_insn "*subsi_2"
7673 [(set (reg FLAGS_REG)
7675 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7676 (match_operand:SI 2 "general_operand" "ri,rm"))
7678 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7679 (minus:SI (match_dup 1) (match_dup 2)))]
7680 "ix86_match_ccmode (insn, CCGOCmode)
7681 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sub{l}\t{%2, %0|%0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "mode" "SI")])
7686 (define_insn "*subsi_2_zext"
7687 [(set (reg FLAGS_REG)
7689 (minus:SI (match_operand:SI 1 "register_operand" "0")
7690 (match_operand:SI 2 "general_operand" "g"))
7692 (set (match_operand:DI 0 "register_operand" "=r")
7694 (minus:SI (match_dup 1)
7696 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7697 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7698 "sub{l}\t{%2, %k0|%k0, %2}"
7699 [(set_attr "type" "alu")
7700 (set_attr "mode" "SI")])
7702 (define_insn "*subsi_3"
7703 [(set (reg FLAGS_REG)
7704 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7705 (match_operand:SI 2 "general_operand" "ri,rm")))
7706 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7707 (minus:SI (match_dup 1) (match_dup 2)))]
7708 "ix86_match_ccmode (insn, CCmode)
7709 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7710 "sub{l}\t{%2, %0|%0, %2}"
7711 [(set_attr "type" "alu")
7712 (set_attr "mode" "SI")])
7714 (define_insn "*subsi_3_zext"
7715 [(set (reg FLAGS_REG)
7716 (compare (match_operand:SI 1 "register_operand" "0")
7717 (match_operand:SI 2 "general_operand" "g")))
7718 (set (match_operand:DI 0 "register_operand" "=r")
7720 (minus:SI (match_dup 1)
7722 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7723 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7724 "sub{l}\t{%2, %1|%1, %2}"
7725 [(set_attr "type" "alu")
7726 (set_attr "mode" "DI")])
7728 (define_expand "subhi3"
7729 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7730 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7731 (match_operand:HI 2 "general_operand" "")))]
7732 "TARGET_HIMODE_MATH"
7733 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7735 (define_insn "*subhi_1"
7736 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7738 (match_operand:HI 2 "general_operand" "rn,rm")))
7739 (clobber (reg:CC FLAGS_REG))]
7740 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7741 "sub{w}\t{%2, %0|%0, %2}"
7742 [(set_attr "type" "alu")
7743 (set_attr "mode" "HI")])
7745 (define_insn "*subhi_2"
7746 [(set (reg FLAGS_REG)
7748 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7749 (match_operand:HI 2 "general_operand" "rn,rm"))
7751 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7752 (minus:HI (match_dup 1) (match_dup 2)))]
7753 "ix86_match_ccmode (insn, CCGOCmode)
7754 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7755 "sub{w}\t{%2, %0|%0, %2}"
7756 [(set_attr "type" "alu")
7757 (set_attr "mode" "HI")])
7759 (define_insn "*subhi_3"
7760 [(set (reg FLAGS_REG)
7761 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7762 (match_operand:HI 2 "general_operand" "rn,rm")))
7763 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7764 (minus:HI (match_dup 1) (match_dup 2)))]
7765 "ix86_match_ccmode (insn, CCmode)
7766 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7767 "sub{w}\t{%2, %0|%0, %2}"
7768 [(set_attr "type" "alu")
7769 (set_attr "mode" "HI")])
7771 (define_expand "subqi3"
7772 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7773 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7774 (match_operand:QI 2 "general_operand" "")))]
7775 "TARGET_QIMODE_MATH"
7776 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7778 (define_insn "*subqi_1"
7779 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7780 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7781 (match_operand:QI 2 "general_operand" "qn,qm")))
7782 (clobber (reg:CC FLAGS_REG))]
7783 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7784 "sub{b}\t{%2, %0|%0, %2}"
7785 [(set_attr "type" "alu")
7786 (set_attr "mode" "QI")])
7788 (define_insn "*subqi_1_slp"
7789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7790 (minus:QI (match_dup 0)
7791 (match_operand:QI 1 "general_operand" "qn,qm")))
7792 (clobber (reg:CC FLAGS_REG))]
7793 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7794 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7795 "sub{b}\t{%1, %0|%0, %1}"
7796 [(set_attr "type" "alu1")
7797 (set_attr "mode" "QI")])
7799 (define_insn "*subqi_2"
7800 [(set (reg FLAGS_REG)
7802 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7803 (match_operand:QI 2 "general_operand" "qn,qm"))
7805 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7806 (minus:QI (match_dup 1) (match_dup 2)))]
7807 "ix86_match_ccmode (insn, CCGOCmode)
7808 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7809 "sub{b}\t{%2, %0|%0, %2}"
7810 [(set_attr "type" "alu")
7811 (set_attr "mode" "QI")])
7813 (define_insn "*subqi_3"
7814 [(set (reg FLAGS_REG)
7815 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7816 (match_operand:QI 2 "general_operand" "qn,qm")))
7817 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7818 (minus:QI (match_dup 1) (match_dup 2)))]
7819 "ix86_match_ccmode (insn, CCmode)
7820 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7821 "sub{b}\t{%2, %0|%0, %2}"
7822 [(set_attr "type" "alu")
7823 (set_attr "mode" "QI")])
7825 ;; The patterns that match these are at the end of this file.
7827 (define_expand "subxf3"
7828 [(set (match_operand:XF 0 "register_operand" "")
7829 (minus:XF (match_operand:XF 1 "register_operand" "")
7830 (match_operand:XF 2 "register_operand" "")))]
7834 (define_expand "sub<mode>3"
7835 [(set (match_operand:MODEF 0 "register_operand" "")
7836 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7837 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7838 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7841 ;; Multiply instructions
7843 (define_expand "muldi3"
7844 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7845 (mult:DI (match_operand:DI 1 "register_operand" "")
7846 (match_operand:DI 2 "x86_64_general_operand" "")))
7847 (clobber (reg:CC FLAGS_REG))])]
7852 ;; IMUL reg64, reg64, imm8 Direct
7853 ;; IMUL reg64, mem64, imm8 VectorPath
7854 ;; IMUL reg64, reg64, imm32 Direct
7855 ;; IMUL reg64, mem64, imm32 VectorPath
7856 ;; IMUL reg64, reg64 Direct
7857 ;; IMUL reg64, mem64 Direct
7859 (define_insn "*muldi3_1_rex64"
7860 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7861 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7862 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7863 (clobber (reg:CC FLAGS_REG))]
7865 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7867 imul{q}\t{%2, %1, %0|%0, %1, %2}
7868 imul{q}\t{%2, %1, %0|%0, %1, %2}
7869 imul{q}\t{%2, %0|%0, %2}"
7870 [(set_attr "type" "imul")
7871 (set_attr "prefix_0f" "0,0,1")
7872 (set (attr "athlon_decode")
7873 (cond [(eq_attr "cpu" "athlon")
7874 (const_string "vector")
7875 (eq_attr "alternative" "1")
7876 (const_string "vector")
7877 (and (eq_attr "alternative" "2")
7878 (match_operand 1 "memory_operand" ""))
7879 (const_string "vector")]
7880 (const_string "direct")))
7881 (set (attr "amdfam10_decode")
7882 (cond [(and (eq_attr "alternative" "0,1")
7883 (match_operand 1 "memory_operand" ""))
7884 (const_string "vector")]
7885 (const_string "direct")))
7886 (set_attr "mode" "DI")])
7888 (define_expand "mulsi3"
7889 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7890 (mult:SI (match_operand:SI 1 "register_operand" "")
7891 (match_operand:SI 2 "general_operand" "")))
7892 (clobber (reg:CC FLAGS_REG))])]
7897 ;; IMUL reg32, reg32, imm8 Direct
7898 ;; IMUL reg32, mem32, imm8 VectorPath
7899 ;; IMUL reg32, reg32, imm32 Direct
7900 ;; IMUL reg32, mem32, imm32 VectorPath
7901 ;; IMUL reg32, reg32 Direct
7902 ;; IMUL reg32, mem32 Direct
7904 (define_insn "*mulsi3_1"
7905 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7906 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7907 (match_operand:SI 2 "general_operand" "K,i,mr")))
7908 (clobber (reg:CC FLAGS_REG))]
7909 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7911 imul{l}\t{%2, %1, %0|%0, %1, %2}
7912 imul{l}\t{%2, %1, %0|%0, %1, %2}
7913 imul{l}\t{%2, %0|%0, %2}"
7914 [(set_attr "type" "imul")
7915 (set_attr "prefix_0f" "0,0,1")
7916 (set (attr "athlon_decode")
7917 (cond [(eq_attr "cpu" "athlon")
7918 (const_string "vector")
7919 (eq_attr "alternative" "1")
7920 (const_string "vector")
7921 (and (eq_attr "alternative" "2")
7922 (match_operand 1 "memory_operand" ""))
7923 (const_string "vector")]
7924 (const_string "direct")))
7925 (set (attr "amdfam10_decode")
7926 (cond [(and (eq_attr "alternative" "0,1")
7927 (match_operand 1 "memory_operand" ""))
7928 (const_string "vector")]
7929 (const_string "direct")))
7930 (set_attr "mode" "SI")])
7932 (define_insn "*mulsi3_1_zext"
7933 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7935 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7936 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7937 (clobber (reg:CC FLAGS_REG))]
7939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7941 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7942 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7943 imul{l}\t{%2, %k0|%k0, %2}"
7944 [(set_attr "type" "imul")
7945 (set_attr "prefix_0f" "0,0,1")
7946 (set (attr "athlon_decode")
7947 (cond [(eq_attr "cpu" "athlon")
7948 (const_string "vector")
7949 (eq_attr "alternative" "1")
7950 (const_string "vector")
7951 (and (eq_attr "alternative" "2")
7952 (match_operand 1 "memory_operand" ""))
7953 (const_string "vector")]
7954 (const_string "direct")))
7955 (set (attr "amdfam10_decode")
7956 (cond [(and (eq_attr "alternative" "0,1")
7957 (match_operand 1 "memory_operand" ""))
7958 (const_string "vector")]
7959 (const_string "direct")))
7960 (set_attr "mode" "SI")])
7962 (define_expand "mulhi3"
7963 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7964 (mult:HI (match_operand:HI 1 "register_operand" "")
7965 (match_operand:HI 2 "general_operand" "")))
7966 (clobber (reg:CC FLAGS_REG))])]
7967 "TARGET_HIMODE_MATH"
7971 ;; IMUL reg16, reg16, imm8 VectorPath
7972 ;; IMUL reg16, mem16, imm8 VectorPath
7973 ;; IMUL reg16, reg16, imm16 VectorPath
7974 ;; IMUL reg16, mem16, imm16 VectorPath
7975 ;; IMUL reg16, reg16 Direct
7976 ;; IMUL reg16, mem16 Direct
7977 (define_insn "*mulhi3_1"
7978 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7979 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7980 (match_operand:HI 2 "general_operand" "K,n,mr")))
7981 (clobber (reg:CC FLAGS_REG))]
7982 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7984 imul{w}\t{%2, %1, %0|%0, %1, %2}
7985 imul{w}\t{%2, %1, %0|%0, %1, %2}
7986 imul{w}\t{%2, %0|%0, %2}"
7987 [(set_attr "type" "imul")
7988 (set_attr "prefix_0f" "0,0,1")
7989 (set (attr "athlon_decode")
7990 (cond [(eq_attr "cpu" "athlon")
7991 (const_string "vector")
7992 (eq_attr "alternative" "1,2")
7993 (const_string "vector")]
7994 (const_string "direct")))
7995 (set (attr "amdfam10_decode")
7996 (cond [(eq_attr "alternative" "0,1")
7997 (const_string "vector")]
7998 (const_string "direct")))
7999 (set_attr "mode" "HI")])
8001 (define_expand "mulqi3"
8002 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8003 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8004 (match_operand:QI 2 "register_operand" "")))
8005 (clobber (reg:CC FLAGS_REG))])]
8006 "TARGET_QIMODE_MATH"
8013 (define_insn "*mulqi3_1"
8014 [(set (match_operand:QI 0 "register_operand" "=a")
8015 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8016 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8017 (clobber (reg:CC FLAGS_REG))]
8019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8021 [(set_attr "type" "imul")
8022 (set_attr "length_immediate" "0")
8023 (set (attr "athlon_decode")
8024 (if_then_else (eq_attr "cpu" "athlon")
8025 (const_string "vector")
8026 (const_string "direct")))
8027 (set_attr "amdfam10_decode" "direct")
8028 (set_attr "mode" "QI")])
8030 (define_expand "umulqihi3"
8031 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8032 (mult:HI (zero_extend:HI
8033 (match_operand:QI 1 "nonimmediate_operand" ""))
8035 (match_operand:QI 2 "register_operand" ""))))
8036 (clobber (reg:CC FLAGS_REG))])]
8037 "TARGET_QIMODE_MATH"
8040 (define_insn "*umulqihi3_1"
8041 [(set (match_operand:HI 0 "register_operand" "=a")
8042 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8043 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8044 (clobber (reg:CC FLAGS_REG))]
8046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8048 [(set_attr "type" "imul")
8049 (set_attr "length_immediate" "0")
8050 (set (attr "athlon_decode")
8051 (if_then_else (eq_attr "cpu" "athlon")
8052 (const_string "vector")
8053 (const_string "direct")))
8054 (set_attr "amdfam10_decode" "direct")
8055 (set_attr "mode" "QI")])
8057 (define_expand "mulqihi3"
8058 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8059 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8060 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8061 (clobber (reg:CC FLAGS_REG))])]
8062 "TARGET_QIMODE_MATH"
8065 (define_insn "*mulqihi3_insn"
8066 [(set (match_operand:HI 0 "register_operand" "=a")
8067 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8068 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8069 (clobber (reg:CC FLAGS_REG))]
8071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8073 [(set_attr "type" "imul")
8074 (set_attr "length_immediate" "0")
8075 (set (attr "athlon_decode")
8076 (if_then_else (eq_attr "cpu" "athlon")
8077 (const_string "vector")
8078 (const_string "direct")))
8079 (set_attr "amdfam10_decode" "direct")
8080 (set_attr "mode" "QI")])
8082 (define_expand "umulditi3"
8083 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8084 (mult:TI (zero_extend:TI
8085 (match_operand:DI 1 "nonimmediate_operand" ""))
8087 (match_operand:DI 2 "register_operand" ""))))
8088 (clobber (reg:CC FLAGS_REG))])]
8092 (define_insn "*umulditi3_insn"
8093 [(set (match_operand:TI 0 "register_operand" "=A")
8094 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8095 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8096 (clobber (reg:CC FLAGS_REG))]
8098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8100 [(set_attr "type" "imul")
8101 (set_attr "length_immediate" "0")
8102 (set (attr "athlon_decode")
8103 (if_then_else (eq_attr "cpu" "athlon")
8104 (const_string "vector")
8105 (const_string "double")))
8106 (set_attr "amdfam10_decode" "double")
8107 (set_attr "mode" "DI")])
8109 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8110 (define_expand "umulsidi3"
8111 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8112 (mult:DI (zero_extend:DI
8113 (match_operand:SI 1 "nonimmediate_operand" ""))
8115 (match_operand:SI 2 "register_operand" ""))))
8116 (clobber (reg:CC FLAGS_REG))])]
8120 (define_insn "*umulsidi3_insn"
8121 [(set (match_operand:DI 0 "register_operand" "=A")
8122 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8123 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8124 (clobber (reg:CC FLAGS_REG))]
8126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8128 [(set_attr "type" "imul")
8129 (set_attr "length_immediate" "0")
8130 (set (attr "athlon_decode")
8131 (if_then_else (eq_attr "cpu" "athlon")
8132 (const_string "vector")
8133 (const_string "double")))
8134 (set_attr "amdfam10_decode" "double")
8135 (set_attr "mode" "SI")])
8137 (define_expand "mulditi3"
8138 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8139 (mult:TI (sign_extend:TI
8140 (match_operand:DI 1 "nonimmediate_operand" ""))
8142 (match_operand:DI 2 "register_operand" ""))))
8143 (clobber (reg:CC FLAGS_REG))])]
8147 (define_insn "*mulditi3_insn"
8148 [(set (match_operand:TI 0 "register_operand" "=A")
8149 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8150 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8151 (clobber (reg:CC FLAGS_REG))]
8153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8155 [(set_attr "type" "imul")
8156 (set_attr "length_immediate" "0")
8157 (set (attr "athlon_decode")
8158 (if_then_else (eq_attr "cpu" "athlon")
8159 (const_string "vector")
8160 (const_string "double")))
8161 (set_attr "amdfam10_decode" "double")
8162 (set_attr "mode" "DI")])
8164 (define_expand "mulsidi3"
8165 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8166 (mult:DI (sign_extend:DI
8167 (match_operand:SI 1 "nonimmediate_operand" ""))
8169 (match_operand:SI 2 "register_operand" ""))))
8170 (clobber (reg:CC FLAGS_REG))])]
8174 (define_insn "*mulsidi3_insn"
8175 [(set (match_operand:DI 0 "register_operand" "=A")
8176 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8177 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8178 (clobber (reg:CC FLAGS_REG))]
8180 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8182 [(set_attr "type" "imul")
8183 (set_attr "length_immediate" "0")
8184 (set (attr "athlon_decode")
8185 (if_then_else (eq_attr "cpu" "athlon")
8186 (const_string "vector")
8187 (const_string "double")))
8188 (set_attr "amdfam10_decode" "double")
8189 (set_attr "mode" "SI")])
8191 (define_expand "umuldi3_highpart"
8192 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8195 (mult:TI (zero_extend:TI
8196 (match_operand:DI 1 "nonimmediate_operand" ""))
8198 (match_operand:DI 2 "register_operand" "")))
8200 (clobber (match_scratch:DI 3 ""))
8201 (clobber (reg:CC FLAGS_REG))])]
8205 (define_insn "*umuldi3_highpart_rex64"
8206 [(set (match_operand:DI 0 "register_operand" "=d")
8209 (mult:TI (zero_extend:TI
8210 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8212 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8214 (clobber (match_scratch:DI 3 "=1"))
8215 (clobber (reg:CC FLAGS_REG))]
8217 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8219 [(set_attr "type" "imul")
8220 (set_attr "length_immediate" "0")
8221 (set (attr "athlon_decode")
8222 (if_then_else (eq_attr "cpu" "athlon")
8223 (const_string "vector")
8224 (const_string "double")))
8225 (set_attr "amdfam10_decode" "double")
8226 (set_attr "mode" "DI")])
8228 (define_expand "umulsi3_highpart"
8229 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8232 (mult:DI (zero_extend:DI
8233 (match_operand:SI 1 "nonimmediate_operand" ""))
8235 (match_operand:SI 2 "register_operand" "")))
8237 (clobber (match_scratch:SI 3 ""))
8238 (clobber (reg:CC FLAGS_REG))])]
8242 (define_insn "*umulsi3_highpart_insn"
8243 [(set (match_operand:SI 0 "register_operand" "=d")
8246 (mult:DI (zero_extend:DI
8247 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8249 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8251 (clobber (match_scratch:SI 3 "=1"))
8252 (clobber (reg:CC FLAGS_REG))]
8253 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8255 [(set_attr "type" "imul")
8256 (set_attr "length_immediate" "0")
8257 (set (attr "athlon_decode")
8258 (if_then_else (eq_attr "cpu" "athlon")
8259 (const_string "vector")
8260 (const_string "double")))
8261 (set_attr "amdfam10_decode" "double")
8262 (set_attr "mode" "SI")])
8264 (define_insn "*umulsi3_highpart_zext"
8265 [(set (match_operand:DI 0 "register_operand" "=d")
8266 (zero_extend:DI (truncate:SI
8268 (mult:DI (zero_extend:DI
8269 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8271 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8273 (clobber (match_scratch:SI 3 "=1"))
8274 (clobber (reg:CC FLAGS_REG))]
8276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8278 [(set_attr "type" "imul")
8279 (set_attr "length_immediate" "0")
8280 (set (attr "athlon_decode")
8281 (if_then_else (eq_attr "cpu" "athlon")
8282 (const_string "vector")
8283 (const_string "double")))
8284 (set_attr "amdfam10_decode" "double")
8285 (set_attr "mode" "SI")])
8287 (define_expand "smuldi3_highpart"
8288 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8291 (mult:TI (sign_extend:TI
8292 (match_operand:DI 1 "nonimmediate_operand" ""))
8294 (match_operand:DI 2 "register_operand" "")))
8296 (clobber (match_scratch:DI 3 ""))
8297 (clobber (reg:CC FLAGS_REG))])]
8301 (define_insn "*smuldi3_highpart_rex64"
8302 [(set (match_operand:DI 0 "register_operand" "=d")
8305 (mult:TI (sign_extend:TI
8306 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8308 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8310 (clobber (match_scratch:DI 3 "=1"))
8311 (clobber (reg:CC FLAGS_REG))]
8313 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8315 [(set_attr "type" "imul")
8316 (set (attr "athlon_decode")
8317 (if_then_else (eq_attr "cpu" "athlon")
8318 (const_string "vector")
8319 (const_string "double")))
8320 (set_attr "amdfam10_decode" "double")
8321 (set_attr "mode" "DI")])
8323 (define_expand "smulsi3_highpart"
8324 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8327 (mult:DI (sign_extend:DI
8328 (match_operand:SI 1 "nonimmediate_operand" ""))
8330 (match_operand:SI 2 "register_operand" "")))
8332 (clobber (match_scratch:SI 3 ""))
8333 (clobber (reg:CC FLAGS_REG))])]
8337 (define_insn "*smulsi3_highpart_insn"
8338 [(set (match_operand:SI 0 "register_operand" "=d")
8341 (mult:DI (sign_extend:DI
8342 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8344 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8346 (clobber (match_scratch:SI 3 "=1"))
8347 (clobber (reg:CC FLAGS_REG))]
8348 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8350 [(set_attr "type" "imul")
8351 (set (attr "athlon_decode")
8352 (if_then_else (eq_attr "cpu" "athlon")
8353 (const_string "vector")
8354 (const_string "double")))
8355 (set_attr "amdfam10_decode" "double")
8356 (set_attr "mode" "SI")])
8358 (define_insn "*smulsi3_highpart_zext"
8359 [(set (match_operand:DI 0 "register_operand" "=d")
8360 (zero_extend:DI (truncate:SI
8362 (mult:DI (sign_extend:DI
8363 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8365 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8367 (clobber (match_scratch:SI 3 "=1"))
8368 (clobber (reg:CC FLAGS_REG))]
8370 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8372 [(set_attr "type" "imul")
8373 (set (attr "athlon_decode")
8374 (if_then_else (eq_attr "cpu" "athlon")
8375 (const_string "vector")
8376 (const_string "double")))
8377 (set_attr "amdfam10_decode" "double")
8378 (set_attr "mode" "SI")])
8380 ;; The patterns that match these are at the end of this file.
8382 (define_expand "mulxf3"
8383 [(set (match_operand:XF 0 "register_operand" "")
8384 (mult:XF (match_operand:XF 1 "register_operand" "")
8385 (match_operand:XF 2 "register_operand" "")))]
8389 (define_expand "mul<mode>3"
8390 [(set (match_operand:MODEF 0 "register_operand" "")
8391 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8392 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8393 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8396 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8399 ;; Divide instructions
8401 (define_insn "divqi3"
8402 [(set (match_operand:QI 0 "register_operand" "=a")
8403 (div:QI (match_operand:HI 1 "register_operand" "0")
8404 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8405 (clobber (reg:CC FLAGS_REG))]
8406 "TARGET_QIMODE_MATH"
8408 [(set_attr "type" "idiv")
8409 (set_attr "mode" "QI")])
8411 (define_insn "udivqi3"
8412 [(set (match_operand:QI 0 "register_operand" "=a")
8413 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8414 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8415 (clobber (reg:CC FLAGS_REG))]
8416 "TARGET_QIMODE_MATH"
8418 [(set_attr "type" "idiv")
8419 (set_attr "mode" "QI")])
8421 ;; The patterns that match these are at the end of this file.
8423 (define_expand "divxf3"
8424 [(set (match_operand:XF 0 "register_operand" "")
8425 (div:XF (match_operand:XF 1 "register_operand" "")
8426 (match_operand:XF 2 "register_operand" "")))]
8430 (define_expand "divdf3"
8431 [(set (match_operand:DF 0 "register_operand" "")
8432 (div:DF (match_operand:DF 1 "register_operand" "")
8433 (match_operand:DF 2 "nonimmediate_operand" "")))]
8434 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8437 (define_expand "divsf3"
8438 [(set (match_operand:SF 0 "register_operand" "")
8439 (div:SF (match_operand:SF 1 "register_operand" "")
8440 (match_operand:SF 2 "nonimmediate_operand" "")))]
8441 "TARGET_80387 || TARGET_SSE_MATH"
8443 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8444 && flag_finite_math_only && !flag_trapping_math
8445 && flag_unsafe_math_optimizations)
8447 ix86_emit_swdivsf (operands[0], operands[1],
8448 operands[2], SFmode);
8453 ;; Remainder instructions.
8455 (define_expand "divmoddi4"
8456 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8457 (div:DI (match_operand:DI 1 "register_operand" "")
8458 (match_operand:DI 2 "nonimmediate_operand" "")))
8459 (set (match_operand:DI 3 "register_operand" "")
8460 (mod:DI (match_dup 1) (match_dup 2)))
8461 (clobber (reg:CC FLAGS_REG))])]
8465 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8466 ;; Penalize eax case slightly because it results in worse scheduling
8468 (define_insn "*divmoddi4_nocltd_rex64"
8469 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8470 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8471 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8472 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8473 (mod:DI (match_dup 2) (match_dup 3)))
8474 (clobber (reg:CC FLAGS_REG))]
8475 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8477 [(set_attr "type" "multi")])
8479 (define_insn "*divmoddi4_cltd_rex64"
8480 [(set (match_operand:DI 0 "register_operand" "=a")
8481 (div:DI (match_operand:DI 2 "register_operand" "a")
8482 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8483 (set (match_operand:DI 1 "register_operand" "=&d")
8484 (mod:DI (match_dup 2) (match_dup 3)))
8485 (clobber (reg:CC FLAGS_REG))]
8486 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8488 [(set_attr "type" "multi")])
8490 (define_insn "*divmoddi_noext_rex64"
8491 [(set (match_operand:DI 0 "register_operand" "=a")
8492 (div:DI (match_operand:DI 1 "register_operand" "0")
8493 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8494 (set (match_operand:DI 3 "register_operand" "=d")
8495 (mod:DI (match_dup 1) (match_dup 2)))
8496 (use (match_operand:DI 4 "register_operand" "3"))
8497 (clobber (reg:CC FLAGS_REG))]
8500 [(set_attr "type" "idiv")
8501 (set_attr "mode" "DI")])
8504 [(set (match_operand:DI 0 "register_operand" "")
8505 (div:DI (match_operand:DI 1 "register_operand" "")
8506 (match_operand:DI 2 "nonimmediate_operand" "")))
8507 (set (match_operand:DI 3 "register_operand" "")
8508 (mod:DI (match_dup 1) (match_dup 2)))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "TARGET_64BIT && reload_completed"
8511 [(parallel [(set (match_dup 3)
8512 (ashiftrt:DI (match_dup 4) (const_int 63)))
8513 (clobber (reg:CC FLAGS_REG))])
8514 (parallel [(set (match_dup 0)
8515 (div:DI (reg:DI 0) (match_dup 2)))
8517 (mod:DI (reg:DI 0) (match_dup 2)))
8519 (clobber (reg:CC FLAGS_REG))])]
8521 /* Avoid use of cltd in favor of a mov+shift. */
8522 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8524 if (true_regnum (operands[1]))
8525 emit_move_insn (operands[0], operands[1]);
8527 emit_move_insn (operands[3], operands[1]);
8528 operands[4] = operands[3];
8532 gcc_assert (!true_regnum (operands[1]));
8533 operands[4] = operands[1];
8538 (define_expand "divmodsi4"
8539 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8540 (div:SI (match_operand:SI 1 "register_operand" "")
8541 (match_operand:SI 2 "nonimmediate_operand" "")))
8542 (set (match_operand:SI 3 "register_operand" "")
8543 (mod:SI (match_dup 1) (match_dup 2)))
8544 (clobber (reg:CC FLAGS_REG))])]
8548 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8549 ;; Penalize eax case slightly because it results in worse scheduling
8551 (define_insn "*divmodsi4_nocltd"
8552 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8553 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8554 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8555 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8556 (mod:SI (match_dup 2) (match_dup 3)))
8557 (clobber (reg:CC FLAGS_REG))]
8558 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8560 [(set_attr "type" "multi")])
8562 (define_insn "*divmodsi4_cltd"
8563 [(set (match_operand:SI 0 "register_operand" "=a")
8564 (div:SI (match_operand:SI 2 "register_operand" "a")
8565 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8566 (set (match_operand:SI 1 "register_operand" "=&d")
8567 (mod:SI (match_dup 2) (match_dup 3)))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8571 [(set_attr "type" "multi")])
8573 (define_insn "*divmodsi_noext"
8574 [(set (match_operand:SI 0 "register_operand" "=a")
8575 (div:SI (match_operand:SI 1 "register_operand" "0")
8576 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8577 (set (match_operand:SI 3 "register_operand" "=d")
8578 (mod:SI (match_dup 1) (match_dup 2)))
8579 (use (match_operand:SI 4 "register_operand" "3"))
8580 (clobber (reg:CC FLAGS_REG))]
8583 [(set_attr "type" "idiv")
8584 (set_attr "mode" "SI")])
8587 [(set (match_operand:SI 0 "register_operand" "")
8588 (div:SI (match_operand:SI 1 "register_operand" "")
8589 (match_operand:SI 2 "nonimmediate_operand" "")))
8590 (set (match_operand:SI 3 "register_operand" "")
8591 (mod:SI (match_dup 1) (match_dup 2)))
8592 (clobber (reg:CC FLAGS_REG))]
8594 [(parallel [(set (match_dup 3)
8595 (ashiftrt:SI (match_dup 4) (const_int 31)))
8596 (clobber (reg:CC FLAGS_REG))])
8597 (parallel [(set (match_dup 0)
8598 (div:SI (reg:SI 0) (match_dup 2)))
8600 (mod:SI (reg:SI 0) (match_dup 2)))
8602 (clobber (reg:CC FLAGS_REG))])]
8604 /* Avoid use of cltd in favor of a mov+shift. */
8605 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8607 if (true_regnum (operands[1]))
8608 emit_move_insn (operands[0], operands[1]);
8610 emit_move_insn (operands[3], operands[1]);
8611 operands[4] = operands[3];
8615 gcc_assert (!true_regnum (operands[1]));
8616 operands[4] = operands[1];
8620 (define_insn "divmodhi4"
8621 [(set (match_operand:HI 0 "register_operand" "=a")
8622 (div:HI (match_operand:HI 1 "register_operand" "0")
8623 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8624 (set (match_operand:HI 3 "register_operand" "=&d")
8625 (mod:HI (match_dup 1) (match_dup 2)))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "TARGET_HIMODE_MATH"
8629 [(set_attr "type" "multi")
8630 (set_attr "length_immediate" "0")
8631 (set_attr "mode" "SI")])
8633 (define_insn "udivmoddi4"
8634 [(set (match_operand:DI 0 "register_operand" "=a")
8635 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8636 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8637 (set (match_operand:DI 3 "register_operand" "=&d")
8638 (umod:DI (match_dup 1) (match_dup 2)))
8639 (clobber (reg:CC FLAGS_REG))]
8641 "xor{q}\t%3, %3\;div{q}\t%2"
8642 [(set_attr "type" "multi")
8643 (set_attr "length_immediate" "0")
8644 (set_attr "mode" "DI")])
8646 (define_insn "*udivmoddi4_noext"
8647 [(set (match_operand:DI 0 "register_operand" "=a")
8648 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8649 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8650 (set (match_operand:DI 3 "register_operand" "=d")
8651 (umod:DI (match_dup 1) (match_dup 2)))
8653 (clobber (reg:CC FLAGS_REG))]
8656 [(set_attr "type" "idiv")
8657 (set_attr "mode" "DI")])
8660 [(set (match_operand:DI 0 "register_operand" "")
8661 (udiv:DI (match_operand:DI 1 "register_operand" "")
8662 (match_operand:DI 2 "nonimmediate_operand" "")))
8663 (set (match_operand:DI 3 "register_operand" "")
8664 (umod:DI (match_dup 1) (match_dup 2)))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_64BIT && reload_completed"
8667 [(set (match_dup 3) (const_int 0))
8668 (parallel [(set (match_dup 0)
8669 (udiv:DI (match_dup 1) (match_dup 2)))
8671 (umod:DI (match_dup 1) (match_dup 2)))
8673 (clobber (reg:CC FLAGS_REG))])]
8676 (define_insn "udivmodsi4"
8677 [(set (match_operand:SI 0 "register_operand" "=a")
8678 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8679 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8680 (set (match_operand:SI 3 "register_operand" "=&d")
8681 (umod:SI (match_dup 1) (match_dup 2)))
8682 (clobber (reg:CC FLAGS_REG))]
8684 "xor{l}\t%3, %3\;div{l}\t%2"
8685 [(set_attr "type" "multi")
8686 (set_attr "length_immediate" "0")
8687 (set_attr "mode" "SI")])
8689 (define_insn "*udivmodsi4_noext"
8690 [(set (match_operand:SI 0 "register_operand" "=a")
8691 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8692 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8693 (set (match_operand:SI 3 "register_operand" "=d")
8694 (umod:SI (match_dup 1) (match_dup 2)))
8696 (clobber (reg:CC FLAGS_REG))]
8699 [(set_attr "type" "idiv")
8700 (set_attr "mode" "SI")])
8703 [(set (match_operand:SI 0 "register_operand" "")
8704 (udiv:SI (match_operand:SI 1 "register_operand" "")
8705 (match_operand:SI 2 "nonimmediate_operand" "")))
8706 (set (match_operand:SI 3 "register_operand" "")
8707 (umod:SI (match_dup 1) (match_dup 2)))
8708 (clobber (reg:CC FLAGS_REG))]
8710 [(set (match_dup 3) (const_int 0))
8711 (parallel [(set (match_dup 0)
8712 (udiv:SI (match_dup 1) (match_dup 2)))
8714 (umod:SI (match_dup 1) (match_dup 2)))
8716 (clobber (reg:CC FLAGS_REG))])]
8719 (define_expand "udivmodhi4"
8720 [(set (match_dup 4) (const_int 0))
8721 (parallel [(set (match_operand:HI 0 "register_operand" "")
8722 (udiv:HI (match_operand:HI 1 "register_operand" "")
8723 (match_operand:HI 2 "nonimmediate_operand" "")))
8724 (set (match_operand:HI 3 "register_operand" "")
8725 (umod:HI (match_dup 1) (match_dup 2)))
8727 (clobber (reg:CC FLAGS_REG))])]
8728 "TARGET_HIMODE_MATH"
8729 "operands[4] = gen_reg_rtx (HImode);")
8731 (define_insn "*udivmodhi_noext"
8732 [(set (match_operand:HI 0 "register_operand" "=a")
8733 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8734 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8735 (set (match_operand:HI 3 "register_operand" "=d")
8736 (umod:HI (match_dup 1) (match_dup 2)))
8737 (use (match_operand:HI 4 "register_operand" "3"))
8738 (clobber (reg:CC FLAGS_REG))]
8741 [(set_attr "type" "idiv")
8742 (set_attr "mode" "HI")])
8744 ;; We cannot use div/idiv for double division, because it causes
8745 ;; "division by zero" on the overflow and that's not what we expect
8746 ;; from truncate. Because true (non truncating) double division is
8747 ;; never generated, we can't create this insn anyway.
8750 ; [(set (match_operand:SI 0 "register_operand" "=a")
8752 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8754 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8755 ; (set (match_operand:SI 3 "register_operand" "=d")
8757 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8758 ; (clobber (reg:CC FLAGS_REG))]
8760 ; "div{l}\t{%2, %0|%0, %2}"
8761 ; [(set_attr "type" "idiv")])
8763 ;;- Logical AND instructions
8765 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8766 ;; Note that this excludes ah.
8768 (define_insn "*testdi_1_rex64"
8769 [(set (reg FLAGS_REG)
8771 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8772 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8774 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8777 test{l}\t{%k1, %k0|%k0, %k1}
8778 test{l}\t{%k1, %k0|%k0, %k1}
8779 test{q}\t{%1, %0|%0, %1}
8780 test{q}\t{%1, %0|%0, %1}
8781 test{q}\t{%1, %0|%0, %1}"
8782 [(set_attr "type" "test")
8783 (set_attr "modrm" "0,1,0,1,1")
8784 (set_attr "mode" "SI,SI,DI,DI,DI")
8785 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8787 (define_insn "testsi_1"
8788 [(set (reg FLAGS_REG)
8790 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8791 (match_operand:SI 1 "general_operand" "i,i,ri"))
8793 "ix86_match_ccmode (insn, CCNOmode)
8794 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8795 "test{l}\t{%1, %0|%0, %1}"
8796 [(set_attr "type" "test")
8797 (set_attr "modrm" "0,1,1")
8798 (set_attr "mode" "SI")
8799 (set_attr "pent_pair" "uv,np,uv")])
8801 (define_expand "testsi_ccno_1"
8802 [(set (reg:CCNO FLAGS_REG)
8804 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8805 (match_operand:SI 1 "nonmemory_operand" ""))
8810 (define_insn "*testhi_1"
8811 [(set (reg FLAGS_REG)
8812 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8813 (match_operand:HI 1 "general_operand" "n,n,rn"))
8815 "ix86_match_ccmode (insn, CCNOmode)
8816 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8817 "test{w}\t{%1, %0|%0, %1}"
8818 [(set_attr "type" "test")
8819 (set_attr "modrm" "0,1,1")
8820 (set_attr "mode" "HI")
8821 (set_attr "pent_pair" "uv,np,uv")])
8823 (define_expand "testqi_ccz_1"
8824 [(set (reg:CCZ FLAGS_REG)
8825 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8826 (match_operand:QI 1 "nonmemory_operand" ""))
8831 (define_insn "*testqi_1_maybe_si"
8832 [(set (reg FLAGS_REG)
8835 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8836 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8838 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8839 && ix86_match_ccmode (insn,
8840 CONST_INT_P (operands[1])
8841 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8843 if (which_alternative == 3)
8845 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8846 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8847 return "test{l}\t{%1, %k0|%k0, %1}";
8849 return "test{b}\t{%1, %0|%0, %1}";
8851 [(set_attr "type" "test")
8852 (set_attr "modrm" "0,1,1,1")
8853 (set_attr "mode" "QI,QI,QI,SI")
8854 (set_attr "pent_pair" "uv,np,uv,np")])
8856 (define_insn "*testqi_1"
8857 [(set (reg FLAGS_REG)
8860 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8861 (match_operand:QI 1 "general_operand" "n,n,qn"))
8863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8864 && ix86_match_ccmode (insn, CCNOmode)"
8865 "test{b}\t{%1, %0|%0, %1}"
8866 [(set_attr "type" "test")
8867 (set_attr "modrm" "0,1,1")
8868 (set_attr "mode" "QI")
8869 (set_attr "pent_pair" "uv,np,uv")])
8871 (define_expand "testqi_ext_ccno_0"
8872 [(set (reg:CCNO FLAGS_REG)
8876 (match_operand 0 "ext_register_operand" "")
8879 (match_operand 1 "const_int_operand" ""))
8884 (define_insn "*testqi_ext_0"
8885 [(set (reg FLAGS_REG)
8889 (match_operand 0 "ext_register_operand" "Q")
8892 (match_operand 1 "const_int_operand" "n"))
8894 "ix86_match_ccmode (insn, CCNOmode)"
8895 "test{b}\t{%1, %h0|%h0, %1}"
8896 [(set_attr "type" "test")
8897 (set_attr "mode" "QI")
8898 (set_attr "length_immediate" "1")
8899 (set_attr "pent_pair" "np")])
8901 (define_insn "*testqi_ext_1"
8902 [(set (reg FLAGS_REG)
8906 (match_operand 0 "ext_register_operand" "Q")
8910 (match_operand:QI 1 "general_operand" "Qm")))
8912 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8913 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8914 "test{b}\t{%1, %h0|%h0, %1}"
8915 [(set_attr "type" "test")
8916 (set_attr "mode" "QI")])
8918 (define_insn "*testqi_ext_1_rex64"
8919 [(set (reg FLAGS_REG)
8923 (match_operand 0 "ext_register_operand" "Q")
8927 (match_operand:QI 1 "register_operand" "Q")))
8929 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8930 "test{b}\t{%1, %h0|%h0, %1}"
8931 [(set_attr "type" "test")
8932 (set_attr "mode" "QI")])
8934 (define_insn "*testqi_ext_2"
8935 [(set (reg FLAGS_REG)
8939 (match_operand 0 "ext_register_operand" "Q")
8943 (match_operand 1 "ext_register_operand" "Q")
8947 "ix86_match_ccmode (insn, CCNOmode)"
8948 "test{b}\t{%h1, %h0|%h0, %h1}"
8949 [(set_attr "type" "test")
8950 (set_attr "mode" "QI")])
8952 ;; Combine likes to form bit extractions for some tests. Humor it.
8953 (define_insn "*testqi_ext_3"
8954 [(set (reg FLAGS_REG)
8955 (compare (zero_extract:SI
8956 (match_operand 0 "nonimmediate_operand" "rm")
8957 (match_operand:SI 1 "const_int_operand" "")
8958 (match_operand:SI 2 "const_int_operand" ""))
8960 "ix86_match_ccmode (insn, CCNOmode)
8961 && INTVAL (operands[1]) > 0
8962 && INTVAL (operands[2]) >= 0
8963 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8964 && (GET_MODE (operands[0]) == SImode
8965 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8966 || GET_MODE (operands[0]) == HImode
8967 || GET_MODE (operands[0]) == QImode)"
8970 (define_insn "*testqi_ext_3_rex64"
8971 [(set (reg FLAGS_REG)
8972 (compare (zero_extract:DI
8973 (match_operand 0 "nonimmediate_operand" "rm")
8974 (match_operand:DI 1 "const_int_operand" "")
8975 (match_operand:DI 2 "const_int_operand" ""))
8978 && ix86_match_ccmode (insn, CCNOmode)
8979 && INTVAL (operands[1]) > 0
8980 && INTVAL (operands[2]) >= 0
8981 /* Ensure that resulting mask is zero or sign extended operand. */
8982 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8983 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8984 && INTVAL (operands[1]) > 32))
8985 && (GET_MODE (operands[0]) == SImode
8986 || GET_MODE (operands[0]) == DImode
8987 || GET_MODE (operands[0]) == HImode
8988 || GET_MODE (operands[0]) == QImode)"
8992 [(set (match_operand 0 "flags_reg_operand" "")
8993 (match_operator 1 "compare_operator"
8995 (match_operand 2 "nonimmediate_operand" "")
8996 (match_operand 3 "const_int_operand" "")
8997 (match_operand 4 "const_int_operand" ""))
8999 "ix86_match_ccmode (insn, CCNOmode)"
9000 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9002 rtx val = operands[2];
9003 HOST_WIDE_INT len = INTVAL (operands[3]);
9004 HOST_WIDE_INT pos = INTVAL (operands[4]);
9006 enum machine_mode mode, submode;
9008 mode = GET_MODE (val);
9011 /* ??? Combine likes to put non-volatile mem extractions in QImode
9012 no matter the size of the test. So find a mode that works. */
9013 if (! MEM_VOLATILE_P (val))
9015 mode = smallest_mode_for_size (pos + len, MODE_INT);
9016 val = adjust_address (val, mode, 0);
9019 else if (GET_CODE (val) == SUBREG
9020 && (submode = GET_MODE (SUBREG_REG (val)),
9021 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9022 && pos + len <= GET_MODE_BITSIZE (submode))
9024 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9026 val = SUBREG_REG (val);
9028 else if (mode == HImode && pos + len <= 8)
9030 /* Small HImode tests can be converted to QImode. */
9032 val = gen_lowpart (QImode, val);
9035 if (len == HOST_BITS_PER_WIDE_INT)
9038 mask = ((HOST_WIDE_INT)1 << len) - 1;
9041 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9044 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9045 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9046 ;; this is relatively important trick.
9047 ;; Do the conversion only post-reload to avoid limiting of the register class
9050 [(set (match_operand 0 "flags_reg_operand" "")
9051 (match_operator 1 "compare_operator"
9052 [(and (match_operand 2 "register_operand" "")
9053 (match_operand 3 "const_int_operand" ""))
9056 && QI_REG_P (operands[2])
9057 && GET_MODE (operands[2]) != QImode
9058 && ((ix86_match_ccmode (insn, CCZmode)
9059 && !(INTVAL (operands[3]) & ~(255 << 8)))
9060 || (ix86_match_ccmode (insn, CCNOmode)
9061 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9064 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9067 "operands[2] = gen_lowpart (SImode, operands[2]);
9068 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9071 [(set (match_operand 0 "flags_reg_operand" "")
9072 (match_operator 1 "compare_operator"
9073 [(and (match_operand 2 "nonimmediate_operand" "")
9074 (match_operand 3 "const_int_operand" ""))
9077 && GET_MODE (operands[2]) != QImode
9078 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9079 && ((ix86_match_ccmode (insn, CCZmode)
9080 && !(INTVAL (operands[3]) & ~255))
9081 || (ix86_match_ccmode (insn, CCNOmode)
9082 && !(INTVAL (operands[3]) & ~127)))"
9084 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9086 "operands[2] = gen_lowpart (QImode, operands[2]);
9087 operands[3] = gen_lowpart (QImode, operands[3]);")
9090 ;; %%% This used to optimize known byte-wide and operations to memory,
9091 ;; and sometimes to QImode registers. If this is considered useful,
9092 ;; it should be done with splitters.
9094 (define_expand "anddi3"
9095 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9096 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9097 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9099 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9101 (define_insn "*anddi_1_rex64"
9102 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9103 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9104 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9105 (clobber (reg:CC FLAGS_REG))]
9106 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9108 switch (get_attr_type (insn))
9112 enum machine_mode mode;
9114 gcc_assert (CONST_INT_P (operands[2]));
9115 if (INTVAL (operands[2]) == 0xff)
9119 gcc_assert (INTVAL (operands[2]) == 0xffff);
9123 operands[1] = gen_lowpart (mode, operands[1]);
9125 return "movz{bq|x}\t{%1,%0|%0, %1}";
9127 return "movz{wq|x}\t{%1,%0|%0, %1}";
9131 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132 if (get_attr_mode (insn) == MODE_SI)
9133 return "and{l}\t{%k2, %k0|%k0, %k2}";
9135 return "and{q}\t{%2, %0|%0, %2}";
9138 [(set_attr "type" "alu,alu,alu,imovx")
9139 (set_attr "length_immediate" "*,*,*,0")
9140 (set_attr "mode" "SI,DI,DI,DI")])
9142 (define_insn "*anddi_2"
9143 [(set (reg FLAGS_REG)
9144 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9145 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9147 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9148 (and:DI (match_dup 1) (match_dup 2)))]
9149 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9150 && ix86_binary_operator_ok (AND, DImode, operands)"
9152 and{l}\t{%k2, %k0|%k0, %k2}
9153 and{q}\t{%2, %0|%0, %2}
9154 and{q}\t{%2, %0|%0, %2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "mode" "SI,DI,DI")])
9158 (define_expand "andsi3"
9159 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9160 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9161 (match_operand:SI 2 "general_operand" "")))]
9163 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9165 (define_insn "*andsi_1"
9166 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9167 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9168 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "ix86_binary_operator_ok (AND, SImode, operands)"
9172 switch (get_attr_type (insn))
9176 enum machine_mode mode;
9178 gcc_assert (CONST_INT_P (operands[2]));
9179 if (INTVAL (operands[2]) == 0xff)
9183 gcc_assert (INTVAL (operands[2]) == 0xffff);
9187 operands[1] = gen_lowpart (mode, operands[1]);
9189 return "movz{bl|x}\t{%1,%0|%0, %1}";
9191 return "movz{wl|x}\t{%1,%0|%0, %1}";
9195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9196 return "and{l}\t{%2, %0|%0, %2}";
9199 [(set_attr "type" "alu,alu,imovx")
9200 (set_attr "length_immediate" "*,*,0")
9201 (set_attr "mode" "SI")])
9204 [(set (match_operand 0 "register_operand" "")
9206 (const_int -65536)))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9209 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9210 "operands[1] = gen_lowpart (HImode, operands[0]);")
9213 [(set (match_operand 0 "ext_register_operand" "")
9216 (clobber (reg:CC FLAGS_REG))]
9217 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9218 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9219 "operands[1] = gen_lowpart (QImode, operands[0]);")
9222 [(set (match_operand 0 "ext_register_operand" "")
9224 (const_int -65281)))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9227 [(parallel [(set (zero_extract:SI (match_dup 0)
9231 (zero_extract:SI (match_dup 0)
9234 (zero_extract:SI (match_dup 0)
9237 (clobber (reg:CC FLAGS_REG))])]
9238 "operands[0] = gen_lowpart (SImode, operands[0]);")
9240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9241 (define_insn "*andsi_1_zext"
9242 [(set (match_operand:DI 0 "register_operand" "=r")
9244 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9245 (match_operand:SI 2 "general_operand" "g"))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9248 "and{l}\t{%2, %k0|%k0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "SI")])
9252 (define_insn "*andsi_2"
9253 [(set (reg FLAGS_REG)
9254 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9255 (match_operand:SI 2 "general_operand" "g,ri"))
9257 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9258 (and:SI (match_dup 1) (match_dup 2)))]
9259 "ix86_match_ccmode (insn, CCNOmode)
9260 && ix86_binary_operator_ok (AND, SImode, operands)"
9261 "and{l}\t{%2, %0|%0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "SI")])
9265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9266 (define_insn "*andsi_2_zext"
9267 [(set (reg FLAGS_REG)
9268 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9269 (match_operand:SI 2 "general_operand" "g"))
9271 (set (match_operand:DI 0 "register_operand" "=r")
9272 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9273 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (AND, SImode, operands)"
9275 "and{l}\t{%2, %k0|%k0, %2}"
9276 [(set_attr "type" "alu")
9277 (set_attr "mode" "SI")])
9279 (define_expand "andhi3"
9280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9281 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9282 (match_operand:HI 2 "general_operand" "")))]
9283 "TARGET_HIMODE_MATH"
9284 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9286 (define_insn "*andhi_1"
9287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9288 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9289 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "ix86_binary_operator_ok (AND, HImode, operands)"
9293 switch (get_attr_type (insn))
9296 gcc_assert (CONST_INT_P (operands[2]));
9297 gcc_assert (INTVAL (operands[2]) == 0xff);
9298 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9303 return "and{w}\t{%2, %0|%0, %2}";
9306 [(set_attr "type" "alu,alu,imovx")
9307 (set_attr "length_immediate" "*,*,0")
9308 (set_attr "mode" "HI,HI,SI")])
9310 (define_insn "*andhi_2"
9311 [(set (reg FLAGS_REG)
9312 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9313 (match_operand:HI 2 "general_operand" "rmn,rn"))
9315 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9316 (and:HI (match_dup 1) (match_dup 2)))]
9317 "ix86_match_ccmode (insn, CCNOmode)
9318 && ix86_binary_operator_ok (AND, HImode, operands)"
9319 "and{w}\t{%2, %0|%0, %2}"
9320 [(set_attr "type" "alu")
9321 (set_attr "mode" "HI")])
9323 (define_expand "andqi3"
9324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9325 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9326 (match_operand:QI 2 "general_operand" "")))]
9327 "TARGET_QIMODE_MATH"
9328 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9330 ;; %%% Potential partial reg stall on alternative 2. What to do?
9331 (define_insn "*andqi_1"
9332 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9333 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9334 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9335 (clobber (reg:CC FLAGS_REG))]
9336 "ix86_binary_operator_ok (AND, QImode, operands)"
9338 and{b}\t{%2, %0|%0, %2}
9339 and{b}\t{%2, %0|%0, %2}
9340 and{l}\t{%k2, %k0|%k0, %k2}"
9341 [(set_attr "type" "alu")
9342 (set_attr "mode" "QI,QI,SI")])
9344 (define_insn "*andqi_1_slp"
9345 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9346 (and:QI (match_dup 0)
9347 (match_operand:QI 1 "general_operand" "qn,qmn")))
9348 (clobber (reg:CC FLAGS_REG))]
9349 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9350 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9351 "and{b}\t{%1, %0|%0, %1}"
9352 [(set_attr "type" "alu1")
9353 (set_attr "mode" "QI")])
9355 (define_insn "*andqi_2_maybe_si"
9356 [(set (reg FLAGS_REG)
9358 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9359 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9361 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9362 (and:QI (match_dup 1) (match_dup 2)))]
9363 "ix86_binary_operator_ok (AND, QImode, operands)
9364 && ix86_match_ccmode (insn,
9365 CONST_INT_P (operands[2])
9366 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9368 if (which_alternative == 2)
9370 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9371 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9372 return "and{l}\t{%2, %k0|%k0, %2}";
9374 return "and{b}\t{%2, %0|%0, %2}";
9376 [(set_attr "type" "alu")
9377 (set_attr "mode" "QI,QI,SI")])
9379 (define_insn "*andqi_2"
9380 [(set (reg FLAGS_REG)
9382 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9383 (match_operand:QI 2 "general_operand" "qmn,qn"))
9385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9386 (and:QI (match_dup 1) (match_dup 2)))]
9387 "ix86_match_ccmode (insn, CCNOmode)
9388 && ix86_binary_operator_ok (AND, QImode, operands)"
9389 "and{b}\t{%2, %0|%0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "QI")])
9393 (define_insn "*andqi_2_slp"
9394 [(set (reg FLAGS_REG)
9396 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9397 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9399 (set (strict_low_part (match_dup 0))
9400 (and:QI (match_dup 0) (match_dup 1)))]
9401 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9402 && ix86_match_ccmode (insn, CCNOmode)
9403 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9404 "and{b}\t{%1, %0|%0, %1}"
9405 [(set_attr "type" "alu1")
9406 (set_attr "mode" "QI")])
9408 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9409 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9410 ;; for a QImode operand, which of course failed.
9412 (define_insn "andqi_ext_0"
9413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9418 (match_operand 1 "ext_register_operand" "0")
9421 (match_operand 2 "const_int_operand" "n")))
9422 (clobber (reg:CC FLAGS_REG))]
9424 "and{b}\t{%2, %h0|%h0, %2}"
9425 [(set_attr "type" "alu")
9426 (set_attr "length_immediate" "1")
9427 (set_attr "mode" "QI")])
9429 ;; Generated by peephole translating test to and. This shows up
9430 ;; often in fp comparisons.
9432 (define_insn "*andqi_ext_0_cc"
9433 [(set (reg FLAGS_REG)
9437 (match_operand 1 "ext_register_operand" "0")
9440 (match_operand 2 "const_int_operand" "n"))
9442 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9451 "ix86_match_ccmode (insn, CCNOmode)"
9452 "and{b}\t{%2, %h0|%h0, %2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "length_immediate" "1")
9455 (set_attr "mode" "QI")])
9457 (define_insn "*andqi_ext_1"
9458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9463 (match_operand 1 "ext_register_operand" "0")
9467 (match_operand:QI 2 "general_operand" "Qm"))))
9468 (clobber (reg:CC FLAGS_REG))]
9470 "and{b}\t{%2, %h0|%h0, %2}"
9471 [(set_attr "type" "alu")
9472 (set_attr "length_immediate" "0")
9473 (set_attr "mode" "QI")])
9475 (define_insn "*andqi_ext_1_rex64"
9476 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9481 (match_operand 1 "ext_register_operand" "0")
9485 (match_operand 2 "ext_register_operand" "Q"))))
9486 (clobber (reg:CC FLAGS_REG))]
9488 "and{b}\t{%2, %h0|%h0, %2}"
9489 [(set_attr "type" "alu")
9490 (set_attr "length_immediate" "0")
9491 (set_attr "mode" "QI")])
9493 (define_insn "*andqi_ext_2"
9494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9499 (match_operand 1 "ext_register_operand" "%0")
9503 (match_operand 2 "ext_register_operand" "Q")
9506 (clobber (reg:CC FLAGS_REG))]
9508 "and{b}\t{%h2, %h0|%h0, %h2}"
9509 [(set_attr "type" "alu")
9510 (set_attr "length_immediate" "0")
9511 (set_attr "mode" "QI")])
9513 ;; Convert wide AND instructions with immediate operand to shorter QImode
9514 ;; equivalents when possible.
9515 ;; Don't do the splitting with memory operands, since it introduces risk
9516 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9517 ;; for size, but that can (should?) be handled by generic code instead.
9519 [(set (match_operand 0 "register_operand" "")
9520 (and (match_operand 1 "register_operand" "")
9521 (match_operand 2 "const_int_operand" "")))
9522 (clobber (reg:CC FLAGS_REG))]
9524 && QI_REG_P (operands[0])
9525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9526 && !(~INTVAL (operands[2]) & ~(255 << 8))
9527 && GET_MODE (operands[0]) != QImode"
9528 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9529 (and:SI (zero_extract:SI (match_dup 1)
9530 (const_int 8) (const_int 8))
9532 (clobber (reg:CC FLAGS_REG))])]
9533 "operands[0] = gen_lowpart (SImode, operands[0]);
9534 operands[1] = gen_lowpart (SImode, operands[1]);
9535 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9537 ;; Since AND can be encoded with sign extended immediate, this is only
9538 ;; profitable when 7th bit is not set.
9540 [(set (match_operand 0 "register_operand" "")
9541 (and (match_operand 1 "general_operand" "")
9542 (match_operand 2 "const_int_operand" "")))
9543 (clobber (reg:CC FLAGS_REG))]
9545 && ANY_QI_REG_P (operands[0])
9546 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9547 && !(~INTVAL (operands[2]) & ~255)
9548 && !(INTVAL (operands[2]) & 128)
9549 && GET_MODE (operands[0]) != QImode"
9550 [(parallel [(set (strict_low_part (match_dup 0))
9551 (and:QI (match_dup 1)
9553 (clobber (reg:CC FLAGS_REG))])]
9554 "operands[0] = gen_lowpart (QImode, operands[0]);
9555 operands[1] = gen_lowpart (QImode, operands[1]);
9556 operands[2] = gen_lowpart (QImode, operands[2]);")
9558 ;; Logical inclusive OR instructions
9560 ;; %%% This used to optimize known byte-wide and operations to memory.
9561 ;; If this is considered useful, it should be done with splitters.
9563 (define_expand "iordi3"
9564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9565 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9566 (match_operand:DI 2 "x86_64_general_operand" "")))]
9568 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9570 (define_insn "*iordi_1_rex64"
9571 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9572 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9573 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9574 (clobber (reg:CC FLAGS_REG))]
9576 && ix86_binary_operator_ok (IOR, DImode, operands)"
9577 "or{q}\t{%2, %0|%0, %2}"
9578 [(set_attr "type" "alu")
9579 (set_attr "mode" "DI")])
9581 (define_insn "*iordi_2_rex64"
9582 [(set (reg FLAGS_REG)
9583 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9584 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9586 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9587 (ior:DI (match_dup 1) (match_dup 2)))]
9589 && ix86_match_ccmode (insn, CCNOmode)
9590 && ix86_binary_operator_ok (IOR, DImode, operands)"
9591 "or{q}\t{%2, %0|%0, %2}"
9592 [(set_attr "type" "alu")
9593 (set_attr "mode" "DI")])
9595 (define_insn "*iordi_3_rex64"
9596 [(set (reg FLAGS_REG)
9597 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9598 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9600 (clobber (match_scratch:DI 0 "=r"))]
9602 && ix86_match_ccmode (insn, CCNOmode)
9603 && ix86_binary_operator_ok (IOR, DImode, operands)"
9604 "or{q}\t{%2, %0|%0, %2}"
9605 [(set_attr "type" "alu")
9606 (set_attr "mode" "DI")])
9609 (define_expand "iorsi3"
9610 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9611 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9612 (match_operand:SI 2 "general_operand" "")))]
9614 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9616 (define_insn "*iorsi_1"
9617 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9618 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9619 (match_operand:SI 2 "general_operand" "ri,g")))
9620 (clobber (reg:CC FLAGS_REG))]
9621 "ix86_binary_operator_ok (IOR, SImode, operands)"
9622 "or{l}\t{%2, %0|%0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "mode" "SI")])
9626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9627 (define_insn "*iorsi_1_zext"
9628 [(set (match_operand:DI 0 "register_operand" "=r")
9630 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9631 (match_operand:SI 2 "general_operand" "g"))))
9632 (clobber (reg:CC FLAGS_REG))]
9633 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9634 "or{l}\t{%2, %k0|%k0, %2}"
9635 [(set_attr "type" "alu")
9636 (set_attr "mode" "SI")])
9638 (define_insn "*iorsi_1_zext_imm"
9639 [(set (match_operand:DI 0 "register_operand" "=r")
9640 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9641 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9642 (clobber (reg:CC FLAGS_REG))]
9644 "or{l}\t{%2, %k0|%k0, %2}"
9645 [(set_attr "type" "alu")
9646 (set_attr "mode" "SI")])
9648 (define_insn "*iorsi_2"
9649 [(set (reg FLAGS_REG)
9650 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9651 (match_operand:SI 2 "general_operand" "g,ri"))
9653 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9654 (ior:SI (match_dup 1) (match_dup 2)))]
9655 "ix86_match_ccmode (insn, CCNOmode)
9656 && ix86_binary_operator_ok (IOR, SImode, operands)"
9657 "or{l}\t{%2, %0|%0, %2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "mode" "SI")])
9661 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9662 ;; ??? Special case for immediate operand is missing - it is tricky.
9663 (define_insn "*iorsi_2_zext"
9664 [(set (reg FLAGS_REG)
9665 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9666 (match_operand:SI 2 "general_operand" "g"))
9668 (set (match_operand:DI 0 "register_operand" "=r")
9669 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9670 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9671 && ix86_binary_operator_ok (IOR, SImode, operands)"
9672 "or{l}\t{%2, %k0|%k0, %2}"
9673 [(set_attr "type" "alu")
9674 (set_attr "mode" "SI")])
9676 (define_insn "*iorsi_2_zext_imm"
9677 [(set (reg FLAGS_REG)
9678 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9679 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9681 (set (match_operand:DI 0 "register_operand" "=r")
9682 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9683 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9684 && ix86_binary_operator_ok (IOR, SImode, operands)"
9685 "or{l}\t{%2, %k0|%k0, %2}"
9686 [(set_attr "type" "alu")
9687 (set_attr "mode" "SI")])
9689 (define_insn "*iorsi_3"
9690 [(set (reg FLAGS_REG)
9691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692 (match_operand:SI 2 "general_operand" "g"))
9694 (clobber (match_scratch:SI 0 "=r"))]
9695 "ix86_match_ccmode (insn, CCNOmode)
9696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9697 "or{l}\t{%2, %0|%0, %2}"
9698 [(set_attr "type" "alu")
9699 (set_attr "mode" "SI")])
9701 (define_expand "iorhi3"
9702 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9703 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9704 (match_operand:HI 2 "general_operand" "")))]
9705 "TARGET_HIMODE_MATH"
9706 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9708 (define_insn "*iorhi_1"
9709 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9710 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9711 (match_operand:HI 2 "general_operand" "rmn,rn")))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (IOR, HImode, operands)"
9714 "or{w}\t{%2, %0|%0, %2}"
9715 [(set_attr "type" "alu")
9716 (set_attr "mode" "HI")])
9718 (define_insn "*iorhi_2"
9719 [(set (reg FLAGS_REG)
9720 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9721 (match_operand:HI 2 "general_operand" "rmn,rn"))
9723 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9724 (ior:HI (match_dup 1) (match_dup 2)))]
9725 "ix86_match_ccmode (insn, CCNOmode)
9726 && ix86_binary_operator_ok (IOR, HImode, operands)"
9727 "or{w}\t{%2, %0|%0, %2}"
9728 [(set_attr "type" "alu")
9729 (set_attr "mode" "HI")])
9731 (define_insn "*iorhi_3"
9732 [(set (reg FLAGS_REG)
9733 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9734 (match_operand:HI 2 "general_operand" "rmn"))
9736 (clobber (match_scratch:HI 0 "=r"))]
9737 "ix86_match_ccmode (insn, CCNOmode)
9738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9739 "or{w}\t{%2, %0|%0, %2}"
9740 [(set_attr "type" "alu")
9741 (set_attr "mode" "HI")])
9743 (define_expand "iorqi3"
9744 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9745 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9746 (match_operand:QI 2 "general_operand" "")))]
9747 "TARGET_QIMODE_MATH"
9748 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9750 ;; %%% Potential partial reg stall on alternative 2. What to do?
9751 (define_insn "*iorqi_1"
9752 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9753 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9754 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9755 (clobber (reg:CC FLAGS_REG))]
9756 "ix86_binary_operator_ok (IOR, QImode, operands)"
9758 or{b}\t{%2, %0|%0, %2}
9759 or{b}\t{%2, %0|%0, %2}
9760 or{l}\t{%k2, %k0|%k0, %k2}"
9761 [(set_attr "type" "alu")
9762 (set_attr "mode" "QI,QI,SI")])
9764 (define_insn "*iorqi_1_slp"
9765 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9766 (ior:QI (match_dup 0)
9767 (match_operand:QI 1 "general_operand" "qmn,qn")))
9768 (clobber (reg:CC FLAGS_REG))]
9769 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9771 "or{b}\t{%1, %0|%0, %1}"
9772 [(set_attr "type" "alu1")
9773 (set_attr "mode" "QI")])
9775 (define_insn "*iorqi_2"
9776 [(set (reg FLAGS_REG)
9777 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9778 (match_operand:QI 2 "general_operand" "qmn,qn"))
9780 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9781 (ior:QI (match_dup 1) (match_dup 2)))]
9782 "ix86_match_ccmode (insn, CCNOmode)
9783 && ix86_binary_operator_ok (IOR, QImode, operands)"
9784 "or{b}\t{%2, %0|%0, %2}"
9785 [(set_attr "type" "alu")
9786 (set_attr "mode" "QI")])
9788 (define_insn "*iorqi_2_slp"
9789 [(set (reg FLAGS_REG)
9790 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9791 (match_operand:QI 1 "general_operand" "qmn,qn"))
9793 (set (strict_low_part (match_dup 0))
9794 (ior:QI (match_dup 0) (match_dup 1)))]
9795 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9796 && ix86_match_ccmode (insn, CCNOmode)
9797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798 "or{b}\t{%1, %0|%0, %1}"
9799 [(set_attr "type" "alu1")
9800 (set_attr "mode" "QI")])
9802 (define_insn "*iorqi_3"
9803 [(set (reg FLAGS_REG)
9804 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9805 (match_operand:QI 2 "general_operand" "qmn"))
9807 (clobber (match_scratch:QI 0 "=q"))]
9808 "ix86_match_ccmode (insn, CCNOmode)
9809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9810 "or{b}\t{%2, %0|%0, %2}"
9811 [(set_attr "type" "alu")
9812 (set_attr "mode" "QI")])
9814 (define_insn "*iorqi_ext_0"
9815 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9820 (match_operand 1 "ext_register_operand" "0")
9823 (match_operand 2 "const_int_operand" "n")))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9826 "or{b}\t{%2, %h0|%h0, %2}"
9827 [(set_attr "type" "alu")
9828 (set_attr "length_immediate" "1")
9829 (set_attr "mode" "QI")])
9831 (define_insn "*iorqi_ext_1"
9832 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9837 (match_operand 1 "ext_register_operand" "0")
9841 (match_operand:QI 2 "general_operand" "Qm"))))
9842 (clobber (reg:CC FLAGS_REG))]
9844 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9845 "or{b}\t{%2, %h0|%h0, %2}"
9846 [(set_attr "type" "alu")
9847 (set_attr "length_immediate" "0")
9848 (set_attr "mode" "QI")])
9850 (define_insn "*iorqi_ext_1_rex64"
9851 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9856 (match_operand 1 "ext_register_operand" "0")
9860 (match_operand 2 "ext_register_operand" "Q"))))
9861 (clobber (reg:CC FLAGS_REG))]
9863 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9864 "or{b}\t{%2, %h0|%h0, %2}"
9865 [(set_attr "type" "alu")
9866 (set_attr "length_immediate" "0")
9867 (set_attr "mode" "QI")])
9869 (define_insn "*iorqi_ext_2"
9870 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9874 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9877 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9880 (clobber (reg:CC FLAGS_REG))]
9881 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9882 "ior{b}\t{%h2, %h0|%h0, %h2}"
9883 [(set_attr "type" "alu")
9884 (set_attr "length_immediate" "0")
9885 (set_attr "mode" "QI")])
9888 [(set (match_operand 0 "register_operand" "")
9889 (ior (match_operand 1 "register_operand" "")
9890 (match_operand 2 "const_int_operand" "")))
9891 (clobber (reg:CC FLAGS_REG))]
9893 && QI_REG_P (operands[0])
9894 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9895 && !(INTVAL (operands[2]) & ~(255 << 8))
9896 && GET_MODE (operands[0]) != QImode"
9897 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9898 (ior:SI (zero_extract:SI (match_dup 1)
9899 (const_int 8) (const_int 8))
9901 (clobber (reg:CC FLAGS_REG))])]
9902 "operands[0] = gen_lowpart (SImode, operands[0]);
9903 operands[1] = gen_lowpart (SImode, operands[1]);
9904 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9906 ;; Since OR can be encoded with sign extended immediate, this is only
9907 ;; profitable when 7th bit is set.
9909 [(set (match_operand 0 "register_operand" "")
9910 (ior (match_operand 1 "general_operand" "")
9911 (match_operand 2 "const_int_operand" "")))
9912 (clobber (reg:CC FLAGS_REG))]
9914 && ANY_QI_REG_P (operands[0])
9915 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9916 && !(INTVAL (operands[2]) & ~255)
9917 && (INTVAL (operands[2]) & 128)
9918 && GET_MODE (operands[0]) != QImode"
9919 [(parallel [(set (strict_low_part (match_dup 0))
9920 (ior:QI (match_dup 1)
9922 (clobber (reg:CC FLAGS_REG))])]
9923 "operands[0] = gen_lowpart (QImode, operands[0]);
9924 operands[1] = gen_lowpart (QImode, operands[1]);
9925 operands[2] = gen_lowpart (QImode, operands[2]);")
9927 ;; Logical XOR instructions
9929 ;; %%% This used to optimize known byte-wide and operations to memory.
9930 ;; If this is considered useful, it should be done with splitters.
9932 (define_expand "xordi3"
9933 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9934 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9935 (match_operand:DI 2 "x86_64_general_operand" "")))]
9937 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9939 (define_insn "*xordi_1_rex64"
9940 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9941 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9942 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9943 (clobber (reg:CC FLAGS_REG))]
9945 && ix86_binary_operator_ok (XOR, DImode, operands)"
9946 "xor{q}\t{%2, %0|%0, %2}"
9947 [(set_attr "type" "alu")
9948 (set_attr "mode" "DI")])
9950 (define_insn "*xordi_2_rex64"
9951 [(set (reg FLAGS_REG)
9952 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9953 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9955 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9956 (xor:DI (match_dup 1) (match_dup 2)))]
9958 && ix86_match_ccmode (insn, CCNOmode)
9959 && ix86_binary_operator_ok (XOR, DImode, operands)"
9960 "xor{q}\t{%2, %0|%0, %2}"
9961 [(set_attr "type" "alu")
9962 (set_attr "mode" "DI")])
9964 (define_insn "*xordi_3_rex64"
9965 [(set (reg FLAGS_REG)
9966 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9967 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9969 (clobber (match_scratch:DI 0 "=r"))]
9971 && ix86_match_ccmode (insn, CCNOmode)
9972 && ix86_binary_operator_ok (XOR, DImode, operands)"
9973 "xor{q}\t{%2, %0|%0, %2}"
9974 [(set_attr "type" "alu")
9975 (set_attr "mode" "DI")])
9977 (define_expand "xorsi3"
9978 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9979 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9980 (match_operand:SI 2 "general_operand" "")))]
9982 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9984 (define_insn "*xorsi_1"
9985 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9986 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9987 (match_operand:SI 2 "general_operand" "ri,rm")))
9988 (clobber (reg:CC FLAGS_REG))]
9989 "ix86_binary_operator_ok (XOR, SImode, operands)"
9990 "xor{l}\t{%2, %0|%0, %2}"
9991 [(set_attr "type" "alu")
9992 (set_attr "mode" "SI")])
9994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9995 ;; Add speccase for immediates
9996 (define_insn "*xorsi_1_zext"
9997 [(set (match_operand:DI 0 "register_operand" "=r")
9999 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10000 (match_operand:SI 2 "general_operand" "g"))))
10001 (clobber (reg:CC FLAGS_REG))]
10002 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10003 "xor{l}\t{%2, %k0|%k0, %2}"
10004 [(set_attr "type" "alu")
10005 (set_attr "mode" "SI")])
10007 (define_insn "*xorsi_1_zext_imm"
10008 [(set (match_operand:DI 0 "register_operand" "=r")
10009 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10010 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10011 (clobber (reg:CC FLAGS_REG))]
10012 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10013 "xor{l}\t{%2, %k0|%k0, %2}"
10014 [(set_attr "type" "alu")
10015 (set_attr "mode" "SI")])
10017 (define_insn "*xorsi_2"
10018 [(set (reg FLAGS_REG)
10019 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10020 (match_operand:SI 2 "general_operand" "g,ri"))
10022 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10023 (xor:SI (match_dup 1) (match_dup 2)))]
10024 "ix86_match_ccmode (insn, CCNOmode)
10025 && ix86_binary_operator_ok (XOR, SImode, operands)"
10026 "xor{l}\t{%2, %0|%0, %2}"
10027 [(set_attr "type" "alu")
10028 (set_attr "mode" "SI")])
10030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10031 ;; ??? Special case for immediate operand is missing - it is tricky.
10032 (define_insn "*xorsi_2_zext"
10033 [(set (reg FLAGS_REG)
10034 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10035 (match_operand:SI 2 "general_operand" "g"))
10037 (set (match_operand:DI 0 "register_operand" "=r")
10038 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10039 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10040 && ix86_binary_operator_ok (XOR, SImode, operands)"
10041 "xor{l}\t{%2, %k0|%k0, %2}"
10042 [(set_attr "type" "alu")
10043 (set_attr "mode" "SI")])
10045 (define_insn "*xorsi_2_zext_imm"
10046 [(set (reg FLAGS_REG)
10047 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10048 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10050 (set (match_operand:DI 0 "register_operand" "=r")
10051 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10052 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10053 && ix86_binary_operator_ok (XOR, SImode, operands)"
10054 "xor{l}\t{%2, %k0|%k0, %2}"
10055 [(set_attr "type" "alu")
10056 (set_attr "mode" "SI")])
10058 (define_insn "*xorsi_3"
10059 [(set (reg FLAGS_REG)
10060 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10061 (match_operand:SI 2 "general_operand" "g"))
10063 (clobber (match_scratch:SI 0 "=r"))]
10064 "ix86_match_ccmode (insn, CCNOmode)
10065 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10066 "xor{l}\t{%2, %0|%0, %2}"
10067 [(set_attr "type" "alu")
10068 (set_attr "mode" "SI")])
10070 (define_expand "xorhi3"
10071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10072 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10073 (match_operand:HI 2 "general_operand" "")))]
10074 "TARGET_HIMODE_MATH"
10075 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10077 (define_insn "*xorhi_1"
10078 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10079 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10080 (match_operand:HI 2 "general_operand" "rmn,rn")))
10081 (clobber (reg:CC FLAGS_REG))]
10082 "ix86_binary_operator_ok (XOR, HImode, operands)"
10083 "xor{w}\t{%2, %0|%0, %2}"
10084 [(set_attr "type" "alu")
10085 (set_attr "mode" "HI")])
10087 (define_insn "*xorhi_2"
10088 [(set (reg FLAGS_REG)
10089 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10090 (match_operand:HI 2 "general_operand" "rmn,rn"))
10092 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10093 (xor:HI (match_dup 1) (match_dup 2)))]
10094 "ix86_match_ccmode (insn, CCNOmode)
10095 && ix86_binary_operator_ok (XOR, HImode, operands)"
10096 "xor{w}\t{%2, %0|%0, %2}"
10097 [(set_attr "type" "alu")
10098 (set_attr "mode" "HI")])
10100 (define_insn "*xorhi_3"
10101 [(set (reg FLAGS_REG)
10102 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10103 (match_operand:HI 2 "general_operand" "rmn"))
10105 (clobber (match_scratch:HI 0 "=r"))]
10106 "ix86_match_ccmode (insn, CCNOmode)
10107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10108 "xor{w}\t{%2, %0|%0, %2}"
10109 [(set_attr "type" "alu")
10110 (set_attr "mode" "HI")])
10112 (define_expand "xorqi3"
10113 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10114 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10115 (match_operand:QI 2 "general_operand" "")))]
10116 "TARGET_QIMODE_MATH"
10117 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10119 ;; %%% Potential partial reg stall on alternative 2. What to do?
10120 (define_insn "*xorqi_1"
10121 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10122 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10123 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "ix86_binary_operator_ok (XOR, QImode, operands)"
10127 xor{b}\t{%2, %0|%0, %2}
10128 xor{b}\t{%2, %0|%0, %2}
10129 xor{l}\t{%k2, %k0|%k0, %k2}"
10130 [(set_attr "type" "alu")
10131 (set_attr "mode" "QI,QI,SI")])
10133 (define_insn "*xorqi_1_slp"
10134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10135 (xor:QI (match_dup 0)
10136 (match_operand:QI 1 "general_operand" "qn,qmn")))
10137 (clobber (reg:CC FLAGS_REG))]
10138 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10139 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10140 "xor{b}\t{%1, %0|%0, %1}"
10141 [(set_attr "type" "alu1")
10142 (set_attr "mode" "QI")])
10144 (define_insn "*xorqi_ext_0"
10145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10150 (match_operand 1 "ext_register_operand" "0")
10153 (match_operand 2 "const_int_operand" "n")))
10154 (clobber (reg:CC FLAGS_REG))]
10155 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10156 "xor{b}\t{%2, %h0|%h0, %2}"
10157 [(set_attr "type" "alu")
10158 (set_attr "length_immediate" "1")
10159 (set_attr "mode" "QI")])
10161 (define_insn "*xorqi_ext_1"
10162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10167 (match_operand 1 "ext_register_operand" "0")
10171 (match_operand:QI 2 "general_operand" "Qm"))))
10172 (clobber (reg:CC FLAGS_REG))]
10174 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10175 "xor{b}\t{%2, %h0|%h0, %2}"
10176 [(set_attr "type" "alu")
10177 (set_attr "length_immediate" "0")
10178 (set_attr "mode" "QI")])
10180 (define_insn "*xorqi_ext_1_rex64"
10181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10186 (match_operand 1 "ext_register_operand" "0")
10190 (match_operand 2 "ext_register_operand" "Q"))))
10191 (clobber (reg:CC FLAGS_REG))]
10193 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10194 "xor{b}\t{%2, %h0|%h0, %2}"
10195 [(set_attr "type" "alu")
10196 (set_attr "length_immediate" "0")
10197 (set_attr "mode" "QI")])
10199 (define_insn "*xorqi_ext_2"
10200 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10204 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10207 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10210 (clobber (reg:CC FLAGS_REG))]
10211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10212 "xor{b}\t{%h2, %h0|%h0, %h2}"
10213 [(set_attr "type" "alu")
10214 (set_attr "length_immediate" "0")
10215 (set_attr "mode" "QI")])
10217 (define_insn "*xorqi_cc_1"
10218 [(set (reg FLAGS_REG)
10220 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10221 (match_operand:QI 2 "general_operand" "qmn,qn"))
10223 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10224 (xor:QI (match_dup 1) (match_dup 2)))]
10225 "ix86_match_ccmode (insn, CCNOmode)
10226 && ix86_binary_operator_ok (XOR, QImode, operands)"
10227 "xor{b}\t{%2, %0|%0, %2}"
10228 [(set_attr "type" "alu")
10229 (set_attr "mode" "QI")])
10231 (define_insn "*xorqi_2_slp"
10232 [(set (reg FLAGS_REG)
10233 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10234 (match_operand:QI 1 "general_operand" "qmn,qn"))
10236 (set (strict_low_part (match_dup 0))
10237 (xor:QI (match_dup 0) (match_dup 1)))]
10238 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10239 && ix86_match_ccmode (insn, CCNOmode)
10240 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10241 "xor{b}\t{%1, %0|%0, %1}"
10242 [(set_attr "type" "alu1")
10243 (set_attr "mode" "QI")])
10245 (define_insn "*xorqi_cc_2"
10246 [(set (reg FLAGS_REG)
10248 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10249 (match_operand:QI 2 "general_operand" "qmn"))
10251 (clobber (match_scratch:QI 0 "=q"))]
10252 "ix86_match_ccmode (insn, CCNOmode)
10253 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10254 "xor{b}\t{%2, %0|%0, %2}"
10255 [(set_attr "type" "alu")
10256 (set_attr "mode" "QI")])
10258 (define_insn "*xorqi_cc_ext_1"
10259 [(set (reg FLAGS_REG)
10263 (match_operand 1 "ext_register_operand" "0")
10266 (match_operand:QI 2 "general_operand" "qmn"))
10268 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10272 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10274 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10275 "xor{b}\t{%2, %h0|%h0, %2}"
10276 [(set_attr "type" "alu")
10277 (set_attr "mode" "QI")])
10279 (define_insn "*xorqi_cc_ext_1_rex64"
10280 [(set (reg FLAGS_REG)
10284 (match_operand 1 "ext_register_operand" "0")
10287 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10289 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10293 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10295 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10296 "xor{b}\t{%2, %h0|%h0, %2}"
10297 [(set_attr "type" "alu")
10298 (set_attr "mode" "QI")])
10300 (define_expand "xorqi_cc_ext_1"
10302 (set (reg:CCNO FLAGS_REG)
10306 (match_operand 1 "ext_register_operand" "")
10309 (match_operand:QI 2 "general_operand" ""))
10311 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10315 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10321 [(set (match_operand 0 "register_operand" "")
10322 (xor (match_operand 1 "register_operand" "")
10323 (match_operand 2 "const_int_operand" "")))
10324 (clobber (reg:CC FLAGS_REG))]
10326 && QI_REG_P (operands[0])
10327 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10328 && !(INTVAL (operands[2]) & ~(255 << 8))
10329 && GET_MODE (operands[0]) != QImode"
10330 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10331 (xor:SI (zero_extract:SI (match_dup 1)
10332 (const_int 8) (const_int 8))
10334 (clobber (reg:CC FLAGS_REG))])]
10335 "operands[0] = gen_lowpart (SImode, operands[0]);
10336 operands[1] = gen_lowpart (SImode, operands[1]);
10337 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10339 ;; Since XOR can be encoded with sign extended immediate, this is only
10340 ;; profitable when 7th bit is set.
10342 [(set (match_operand 0 "register_operand" "")
10343 (xor (match_operand 1 "general_operand" "")
10344 (match_operand 2 "const_int_operand" "")))
10345 (clobber (reg:CC FLAGS_REG))]
10347 && ANY_QI_REG_P (operands[0])
10348 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10349 && !(INTVAL (operands[2]) & ~255)
10350 && (INTVAL (operands[2]) & 128)
10351 && GET_MODE (operands[0]) != QImode"
10352 [(parallel [(set (strict_low_part (match_dup 0))
10353 (xor:QI (match_dup 1)
10355 (clobber (reg:CC FLAGS_REG))])]
10356 "operands[0] = gen_lowpart (QImode, operands[0]);
10357 operands[1] = gen_lowpart (QImode, operands[1]);
10358 operands[2] = gen_lowpart (QImode, operands[2]);")
10360 ;; Negation instructions
10362 (define_expand "negti2"
10363 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10364 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10366 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10368 (define_insn "*negti2_1"
10369 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10370 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10371 (clobber (reg:CC FLAGS_REG))]
10373 && ix86_unary_operator_ok (NEG, TImode, operands)"
10377 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10378 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && reload_completed"
10382 [(set (reg:CCZ FLAGS_REG)
10383 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10384 (set (match_dup 0) (neg:DI (match_dup 1)))])
10386 [(set (match_dup 2)
10387 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10390 (clobber (reg:CC FLAGS_REG))])
10392 [(set (match_dup 2)
10393 (neg:DI (match_dup 2)))
10394 (clobber (reg:CC FLAGS_REG))])]
10395 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10397 (define_expand "negdi2"
10398 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10399 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10401 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10403 (define_insn "*negdi2_1"
10404 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10405 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10406 (clobber (reg:CC FLAGS_REG))]
10408 && ix86_unary_operator_ok (NEG, DImode, operands)"
10412 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10413 (neg:DI (match_operand:DI 1 "general_operand" "")))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "!TARGET_64BIT && reload_completed"
10417 [(set (reg:CCZ FLAGS_REG)
10418 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10419 (set (match_dup 0) (neg:SI (match_dup 1)))])
10421 [(set (match_dup 2)
10422 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10425 (clobber (reg:CC FLAGS_REG))])
10427 [(set (match_dup 2)
10428 (neg:SI (match_dup 2)))
10429 (clobber (reg:CC FLAGS_REG))])]
10430 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10432 (define_insn "*negdi2_1_rex64"
10433 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10438 [(set_attr "type" "negnot")
10439 (set_attr "mode" "DI")])
10441 ;; The problem with neg is that it does not perform (compare x 0),
10442 ;; it really performs (compare 0 x), which leaves us with the zero
10443 ;; flag being the only useful item.
10445 (define_insn "*negdi2_cmpz_rex64"
10446 [(set (reg:CCZ FLAGS_REG)
10447 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10449 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10450 (neg:DI (match_dup 1)))]
10451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10453 [(set_attr "type" "negnot")
10454 (set_attr "mode" "DI")])
10457 (define_expand "negsi2"
10458 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10459 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10461 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10463 (define_insn "*negsi2_1"
10464 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10465 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10466 (clobber (reg:CC FLAGS_REG))]
10467 "ix86_unary_operator_ok (NEG, SImode, operands)"
10469 [(set_attr "type" "negnot")
10470 (set_attr "mode" "SI")])
10472 ;; Combine is quite creative about this pattern.
10473 (define_insn "*negsi2_1_zext"
10474 [(set (match_operand:DI 0 "register_operand" "=r")
10475 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10481 [(set_attr "type" "negnot")
10482 (set_attr "mode" "SI")])
10484 ;; The problem with neg is that it does not perform (compare x 0),
10485 ;; it really performs (compare 0 x), which leaves us with the zero
10486 ;; flag being the only useful item.
10488 (define_insn "*negsi2_cmpz"
10489 [(set (reg:CCZ FLAGS_REG)
10490 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10492 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10493 (neg:SI (match_dup 1)))]
10494 "ix86_unary_operator_ok (NEG, SImode, operands)"
10496 [(set_attr "type" "negnot")
10497 (set_attr "mode" "SI")])
10499 (define_insn "*negsi2_cmpz_zext"
10500 [(set (reg:CCZ FLAGS_REG)
10501 (compare:CCZ (lshiftrt:DI
10503 (match_operand:DI 1 "register_operand" "0")
10507 (set (match_operand:DI 0 "register_operand" "=r")
10508 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10511 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10513 [(set_attr "type" "negnot")
10514 (set_attr "mode" "SI")])
10516 (define_expand "neghi2"
10517 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10518 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10519 "TARGET_HIMODE_MATH"
10520 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10522 (define_insn "*neghi2_1"
10523 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10524 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "ix86_unary_operator_ok (NEG, HImode, operands)"
10528 [(set_attr "type" "negnot")
10529 (set_attr "mode" "HI")])
10531 (define_insn "*neghi2_cmpz"
10532 [(set (reg:CCZ FLAGS_REG)
10533 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10535 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10536 (neg:HI (match_dup 1)))]
10537 "ix86_unary_operator_ok (NEG, HImode, operands)"
10539 [(set_attr "type" "negnot")
10540 (set_attr "mode" "HI")])
10542 (define_expand "negqi2"
10543 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10544 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10545 "TARGET_QIMODE_MATH"
10546 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10548 (define_insn "*negqi2_1"
10549 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10550 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "ix86_unary_operator_ok (NEG, QImode, operands)"
10554 [(set_attr "type" "negnot")
10555 (set_attr "mode" "QI")])
10557 (define_insn "*negqi2_cmpz"
10558 [(set (reg:CCZ FLAGS_REG)
10559 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10561 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562 (neg:QI (match_dup 1)))]
10563 "ix86_unary_operator_ok (NEG, QImode, operands)"
10565 [(set_attr "type" "negnot")
10566 (set_attr "mode" "QI")])
10568 ;; Changing of sign for FP values is doable using integer unit too.
10570 (define_expand "<code><mode>2"
10571 [(set (match_operand:X87MODEF 0 "register_operand" "")
10572 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10573 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10574 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10576 (define_insn "*absneg<mode>2_mixed"
10577 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10578 (match_operator:MODEF 3 "absneg_operator"
10579 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10580 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10581 (clobber (reg:CC FLAGS_REG))]
10582 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10585 (define_insn "*absneg<mode>2_sse"
10586 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10587 (match_operator:MODEF 3 "absneg_operator"
10588 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10589 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10590 (clobber (reg:CC FLAGS_REG))]
10591 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10594 (define_insn "*absneg<mode>2_i387"
10595 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10596 (match_operator:X87MODEF 3 "absneg_operator"
10597 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10598 (use (match_operand 2 "" ""))
10599 (clobber (reg:CC FLAGS_REG))]
10600 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10603 (define_expand "<code>tf2"
10604 [(set (match_operand:TF 0 "register_operand" "")
10605 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10607 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10609 (define_insn "*absnegtf2_sse"
10610 [(set (match_operand:TF 0 "register_operand" "=x,x")
10611 (match_operator:TF 3 "absneg_operator"
10612 [(match_operand:TF 1 "register_operand" "0,x")]))
10613 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10614 (clobber (reg:CC FLAGS_REG))]
10618 ;; Splitters for fp abs and neg.
10621 [(set (match_operand 0 "fp_register_operand" "")
10622 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10623 (use (match_operand 2 "" ""))
10624 (clobber (reg:CC FLAGS_REG))]
10626 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10629 [(set (match_operand 0 "register_operand" "")
10630 (match_operator 3 "absneg_operator"
10631 [(match_operand 1 "register_operand" "")]))
10632 (use (match_operand 2 "nonimmediate_operand" ""))
10633 (clobber (reg:CC FLAGS_REG))]
10634 "reload_completed && SSE_REG_P (operands[0])"
10635 [(set (match_dup 0) (match_dup 3))]
10637 enum machine_mode mode = GET_MODE (operands[0]);
10638 enum machine_mode vmode = GET_MODE (operands[2]);
10641 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10642 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10643 if (operands_match_p (operands[0], operands[2]))
10646 operands[1] = operands[2];
10649 if (GET_CODE (operands[3]) == ABS)
10650 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10652 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10657 [(set (match_operand:SF 0 "register_operand" "")
10658 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10659 (use (match_operand:V4SF 2 "" ""))
10660 (clobber (reg:CC FLAGS_REG))]
10662 [(parallel [(set (match_dup 0) (match_dup 1))
10663 (clobber (reg:CC FLAGS_REG))])]
10666 operands[0] = gen_lowpart (SImode, operands[0]);
10667 if (GET_CODE (operands[1]) == ABS)
10669 tmp = gen_int_mode (0x7fffffff, SImode);
10670 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10674 tmp = gen_int_mode (0x80000000, SImode);
10675 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10681 [(set (match_operand:DF 0 "register_operand" "")
10682 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10683 (use (match_operand 2 "" ""))
10684 (clobber (reg:CC FLAGS_REG))]
10686 [(parallel [(set (match_dup 0) (match_dup 1))
10687 (clobber (reg:CC FLAGS_REG))])]
10692 tmp = gen_lowpart (DImode, operands[0]);
10693 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10696 if (GET_CODE (operands[1]) == ABS)
10699 tmp = gen_rtx_NOT (DImode, tmp);
10703 operands[0] = gen_highpart (SImode, operands[0]);
10704 if (GET_CODE (operands[1]) == ABS)
10706 tmp = gen_int_mode (0x7fffffff, SImode);
10707 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10711 tmp = gen_int_mode (0x80000000, SImode);
10712 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10719 [(set (match_operand:XF 0 "register_operand" "")
10720 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10721 (use (match_operand 2 "" ""))
10722 (clobber (reg:CC FLAGS_REG))]
10724 [(parallel [(set (match_dup 0) (match_dup 1))
10725 (clobber (reg:CC FLAGS_REG))])]
10728 operands[0] = gen_rtx_REG (SImode,
10729 true_regnum (operands[0])
10730 + (TARGET_64BIT ? 1 : 2));
10731 if (GET_CODE (operands[1]) == ABS)
10733 tmp = GEN_INT (0x7fff);
10734 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10738 tmp = GEN_INT (0x8000);
10739 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10744 ;; Conditionalize these after reload. If they match before reload, we
10745 ;; lose the clobber and ability to use integer instructions.
10747 (define_insn "*<code><mode>2_1"
10748 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10749 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10751 && (reload_completed
10752 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10754 [(set_attr "type" "fsgn")
10755 (set_attr "mode" "<MODE>")])
10757 (define_insn "*<code>extendsfdf2"
10758 [(set (match_operand:DF 0 "register_operand" "=f")
10759 (absneg:DF (float_extend:DF
10760 (match_operand:SF 1 "register_operand" "0"))))]
10761 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10763 [(set_attr "type" "fsgn")
10764 (set_attr "mode" "DF")])
10766 (define_insn "*<code>extendsfxf2"
10767 [(set (match_operand:XF 0 "register_operand" "=f")
10768 (absneg:XF (float_extend:XF
10769 (match_operand:SF 1 "register_operand" "0"))))]
10772 [(set_attr "type" "fsgn")
10773 (set_attr "mode" "XF")])
10775 (define_insn "*<code>extenddfxf2"
10776 [(set (match_operand:XF 0 "register_operand" "=f")
10777 (absneg:XF (float_extend:XF
10778 (match_operand:DF 1 "register_operand" "0"))))]
10781 [(set_attr "type" "fsgn")
10782 (set_attr "mode" "XF")])
10784 ;; Copysign instructions
10786 (define_mode_iterator CSGNMODE [SF DF TF])
10787 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10789 (define_expand "copysign<mode>3"
10790 [(match_operand:CSGNMODE 0 "register_operand" "")
10791 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10792 (match_operand:CSGNMODE 2 "register_operand" "")]
10793 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10794 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10796 ix86_expand_copysign (operands);
10800 (define_insn_and_split "copysign<mode>3_const"
10801 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10803 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10804 (match_operand:CSGNMODE 2 "register_operand" "0")
10805 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10807 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10808 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10810 "&& reload_completed"
10813 ix86_split_copysign_const (operands);
10817 (define_insn "copysign<mode>3_var"
10818 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10820 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10821 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10822 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10823 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10825 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10826 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10827 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10831 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10833 [(match_operand:CSGNMODE 2 "register_operand" "")
10834 (match_operand:CSGNMODE 3 "register_operand" "")
10835 (match_operand:<CSGNVMODE> 4 "" "")
10836 (match_operand:<CSGNVMODE> 5 "" "")]
10838 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10839 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10840 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10841 && reload_completed"
10844 ix86_split_copysign_var (operands);
10848 ;; One complement instructions
10850 (define_expand "one_cmpldi2"
10851 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10852 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10854 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10856 (define_insn "*one_cmpldi2_1_rex64"
10857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10858 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10859 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10861 [(set_attr "type" "negnot")
10862 (set_attr "mode" "DI")])
10864 (define_insn "*one_cmpldi2_2_rex64"
10865 [(set (reg FLAGS_REG)
10866 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10868 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10869 (not:DI (match_dup 1)))]
10870 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10871 && ix86_unary_operator_ok (NOT, DImode, operands)"
10873 [(set_attr "type" "alu1")
10874 (set_attr "mode" "DI")])
10877 [(set (match_operand 0 "flags_reg_operand" "")
10878 (match_operator 2 "compare_operator"
10879 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10881 (set (match_operand:DI 1 "nonimmediate_operand" "")
10882 (not:DI (match_dup 3)))]
10883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10884 [(parallel [(set (match_dup 0)
10886 [(xor:DI (match_dup 3) (const_int -1))
10889 (xor:DI (match_dup 3) (const_int -1)))])]
10892 (define_expand "one_cmplsi2"
10893 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10894 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10896 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10898 (define_insn "*one_cmplsi2_1"
10899 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10900 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10901 "ix86_unary_operator_ok (NOT, SImode, operands)"
10903 [(set_attr "type" "negnot")
10904 (set_attr "mode" "SI")])
10906 ;; ??? Currently never generated - xor is used instead.
10907 (define_insn "*one_cmplsi2_1_zext"
10908 [(set (match_operand:DI 0 "register_operand" "=r")
10909 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10910 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10912 [(set_attr "type" "negnot")
10913 (set_attr "mode" "SI")])
10915 (define_insn "*one_cmplsi2_2"
10916 [(set (reg FLAGS_REG)
10917 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10919 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10920 (not:SI (match_dup 1)))]
10921 "ix86_match_ccmode (insn, CCNOmode)
10922 && ix86_unary_operator_ok (NOT, SImode, operands)"
10924 [(set_attr "type" "alu1")
10925 (set_attr "mode" "SI")])
10928 [(set (match_operand 0 "flags_reg_operand" "")
10929 (match_operator 2 "compare_operator"
10930 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10932 (set (match_operand:SI 1 "nonimmediate_operand" "")
10933 (not:SI (match_dup 3)))]
10934 "ix86_match_ccmode (insn, CCNOmode)"
10935 [(parallel [(set (match_dup 0)
10936 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10939 (xor:SI (match_dup 3) (const_int -1)))])]
10942 ;; ??? Currently never generated - xor is used instead.
10943 (define_insn "*one_cmplsi2_2_zext"
10944 [(set (reg FLAGS_REG)
10945 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10947 (set (match_operand:DI 0 "register_operand" "=r")
10948 (zero_extend:DI (not:SI (match_dup 1))))]
10949 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10950 && ix86_unary_operator_ok (NOT, SImode, operands)"
10952 [(set_attr "type" "alu1")
10953 (set_attr "mode" "SI")])
10956 [(set (match_operand 0 "flags_reg_operand" "")
10957 (match_operator 2 "compare_operator"
10958 [(not:SI (match_operand:SI 3 "register_operand" ""))
10960 (set (match_operand:DI 1 "register_operand" "")
10961 (zero_extend:DI (not:SI (match_dup 3))))]
10962 "ix86_match_ccmode (insn, CCNOmode)"
10963 [(parallel [(set (match_dup 0)
10964 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10967 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10970 (define_expand "one_cmplhi2"
10971 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10972 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10973 "TARGET_HIMODE_MATH"
10974 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10976 (define_insn "*one_cmplhi2_1"
10977 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10978 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10979 "ix86_unary_operator_ok (NOT, HImode, operands)"
10981 [(set_attr "type" "negnot")
10982 (set_attr "mode" "HI")])
10984 (define_insn "*one_cmplhi2_2"
10985 [(set (reg FLAGS_REG)
10986 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10988 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989 (not:HI (match_dup 1)))]
10990 "ix86_match_ccmode (insn, CCNOmode)
10991 && ix86_unary_operator_ok (NEG, HImode, operands)"
10993 [(set_attr "type" "alu1")
10994 (set_attr "mode" "HI")])
10997 [(set (match_operand 0 "flags_reg_operand" "")
10998 (match_operator 2 "compare_operator"
10999 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11001 (set (match_operand:HI 1 "nonimmediate_operand" "")
11002 (not:HI (match_dup 3)))]
11003 "ix86_match_ccmode (insn, CCNOmode)"
11004 [(parallel [(set (match_dup 0)
11005 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11008 (xor:HI (match_dup 3) (const_int -1)))])]
11011 ;; %%% Potential partial reg stall on alternative 1. What to do?
11012 (define_expand "one_cmplqi2"
11013 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11014 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11015 "TARGET_QIMODE_MATH"
11016 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11018 (define_insn "*one_cmplqi2_1"
11019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11020 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11021 "ix86_unary_operator_ok (NOT, QImode, operands)"
11025 [(set_attr "type" "negnot")
11026 (set_attr "mode" "QI,SI")])
11028 (define_insn "*one_cmplqi2_2"
11029 [(set (reg FLAGS_REG)
11030 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11032 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11033 (not:QI (match_dup 1)))]
11034 "ix86_match_ccmode (insn, CCNOmode)
11035 && ix86_unary_operator_ok (NOT, QImode, operands)"
11037 [(set_attr "type" "alu1")
11038 (set_attr "mode" "QI")])
11041 [(set (match_operand 0 "flags_reg_operand" "")
11042 (match_operator 2 "compare_operator"
11043 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11045 (set (match_operand:QI 1 "nonimmediate_operand" "")
11046 (not:QI (match_dup 3)))]
11047 "ix86_match_ccmode (insn, CCNOmode)"
11048 [(parallel [(set (match_dup 0)
11049 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11052 (xor:QI (match_dup 3) (const_int -1)))])]
11055 ;; Arithmetic shift instructions
11057 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11058 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11059 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11060 ;; from the assembler input.
11062 ;; This instruction shifts the target reg/mem as usual, but instead of
11063 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11064 ;; is a left shift double, bits are taken from the high order bits of
11065 ;; reg, else if the insn is a shift right double, bits are taken from the
11066 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11067 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11069 ;; Since sh[lr]d does not change the `reg' operand, that is done
11070 ;; separately, making all shifts emit pairs of shift double and normal
11071 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11072 ;; support a 63 bit shift, each shift where the count is in a reg expands
11073 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11075 ;; If the shift count is a constant, we need never emit more than one
11076 ;; shift pair, instead using moves and sign extension for counts greater
11079 (define_expand "ashlti3"
11080 [(set (match_operand:TI 0 "register_operand" "")
11081 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11082 (match_operand:QI 2 "nonmemory_operand" "")))]
11084 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11086 ;; This pattern must be defined before *ashlti3_1 to prevent
11087 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11089 (define_insn "*avx_ashlti3"
11090 [(set (match_operand:TI 0 "register_operand" "=x")
11091 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11092 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11095 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11096 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11098 [(set_attr "type" "sseishft")
11099 (set_attr "prefix" "vex")
11100 (set_attr "mode" "TI")])
11102 (define_insn "sse2_ashlti3"
11103 [(set (match_operand:TI 0 "register_operand" "=x")
11104 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11105 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11108 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11109 return "pslldq\t{%2, %0|%0, %2}";
11111 [(set_attr "type" "sseishft")
11112 (set_attr "prefix_data16" "1")
11113 (set_attr "mode" "TI")])
11115 (define_insn "*ashlti3_1"
11116 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11117 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11118 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11119 (clobber (reg:CC FLAGS_REG))]
11122 [(set_attr "type" "multi")])
11125 [(match_scratch:DI 3 "r")
11126 (parallel [(set (match_operand:TI 0 "register_operand" "")
11127 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11128 (match_operand:QI 2 "nonmemory_operand" "")))
11129 (clobber (reg:CC FLAGS_REG))])
11133 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11136 [(set (match_operand:TI 0 "register_operand" "")
11137 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11138 (match_operand:QI 2 "nonmemory_operand" "")))
11139 (clobber (reg:CC FLAGS_REG))]
11140 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11141 ? epilogue_completed : reload_completed)"
11143 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11145 (define_insn "x86_64_shld"
11146 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11147 (ior:DI (ashift:DI (match_dup 0)
11148 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11149 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11150 (minus:QI (const_int 64) (match_dup 2)))))
11151 (clobber (reg:CC FLAGS_REG))]
11153 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11154 [(set_attr "type" "ishift")
11155 (set_attr "prefix_0f" "1")
11156 (set_attr "mode" "DI")
11157 (set_attr "athlon_decode" "vector")
11158 (set_attr "amdfam10_decode" "vector")])
11160 (define_expand "x86_64_shift_adj_1"
11161 [(set (reg:CCZ FLAGS_REG)
11162 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11165 (set (match_operand:DI 0 "register_operand" "")
11166 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167 (match_operand:DI 1 "register_operand" "")
11170 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11171 (match_operand:DI 3 "register_operand" "r")
11176 (define_expand "x86_64_shift_adj_2"
11177 [(use (match_operand:DI 0 "register_operand" ""))
11178 (use (match_operand:DI 1 "register_operand" ""))
11179 (use (match_operand:QI 2 "register_operand" ""))]
11182 rtx label = gen_label_rtx ();
11185 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11187 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11188 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11189 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11190 gen_rtx_LABEL_REF (VOIDmode, label),
11192 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11193 JUMP_LABEL (tmp) = label;
11195 emit_move_insn (operands[0], operands[1]);
11196 ix86_expand_clear (operands[1]);
11198 emit_label (label);
11199 LABEL_NUSES (label) = 1;
11204 (define_expand "ashldi3"
11205 [(set (match_operand:DI 0 "shiftdi_operand" "")
11206 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11207 (match_operand:QI 2 "nonmemory_operand" "")))]
11209 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11211 (define_insn "*ashldi3_1_rex64"
11212 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11213 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11214 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11215 (clobber (reg:CC FLAGS_REG))]
11216 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11218 switch (get_attr_type (insn))
11221 gcc_assert (operands[2] == const1_rtx);
11222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11223 return "add{q}\t%0, %0";
11226 gcc_assert (CONST_INT_P (operands[2]));
11227 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11228 operands[1] = gen_rtx_MULT (DImode, operands[1],
11229 GEN_INT (1 << INTVAL (operands[2])));
11230 return "lea{q}\t{%a1, %0|%0, %a1}";
11233 if (REG_P (operands[2]))
11234 return "sal{q}\t{%b2, %0|%0, %b2}";
11235 else if (operands[2] == const1_rtx
11236 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11237 return "sal{q}\t%0";
11239 return "sal{q}\t{%2, %0|%0, %2}";
11242 [(set (attr "type")
11243 (cond [(eq_attr "alternative" "1")
11244 (const_string "lea")
11245 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11247 (match_operand 0 "register_operand" ""))
11248 (match_operand 2 "const1_operand" ""))
11249 (const_string "alu")
11251 (const_string "ishift")))
11252 (set_attr "mode" "DI")])
11254 ;; Convert lea to the lea pattern to avoid flags dependency.
11256 [(set (match_operand:DI 0 "register_operand" "")
11257 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11258 (match_operand:QI 2 "immediate_operand" "")))
11259 (clobber (reg:CC FLAGS_REG))]
11260 "TARGET_64BIT && reload_completed
11261 && true_regnum (operands[0]) != true_regnum (operands[1])"
11262 [(set (match_dup 0)
11263 (mult:DI (match_dup 1)
11265 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11267 ;; This pattern can't accept a variable shift count, since shifts by
11268 ;; zero don't affect the flags. We assume that shifts by constant
11269 ;; zero are optimized away.
11270 (define_insn "*ashldi3_cmp_rex64"
11271 [(set (reg FLAGS_REG)
11273 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11274 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11276 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11277 (ashift:DI (match_dup 1) (match_dup 2)))]
11279 && (optimize_function_for_size_p (cfun)
11280 || !TARGET_PARTIAL_FLAG_REG_STALL
11281 || (operands[2] == const1_rtx
11283 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11284 && ix86_match_ccmode (insn, CCGOCmode)
11285 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11287 switch (get_attr_type (insn))
11290 gcc_assert (operands[2] == const1_rtx);
11291 return "add{q}\t%0, %0";
11294 if (REG_P (operands[2]))
11295 return "sal{q}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298 return "sal{q}\t%0";
11300 return "sal{q}\t{%2, %0|%0, %2}";
11303 [(set (attr "type")
11304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306 (match_operand 0 "register_operand" ""))
11307 (match_operand 2 "const1_operand" ""))
11308 (const_string "alu")
11310 (const_string "ishift")))
11311 (set_attr "mode" "DI")])
11313 (define_insn "*ashldi3_cconly_rex64"
11314 [(set (reg FLAGS_REG)
11316 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11319 (clobber (match_scratch:DI 0 "=r"))]
11321 && (optimize_function_for_size_p (cfun)
11322 || !TARGET_PARTIAL_FLAG_REG_STALL
11323 || (operands[2] == const1_rtx
11325 || TARGET_DOUBLE_WITH_ADD)))
11326 && ix86_match_ccmode (insn, CCGOCmode)
11327 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11329 switch (get_attr_type (insn))
11332 gcc_assert (operands[2] == const1_rtx);
11333 return "add{q}\t%0, %0";
11336 if (REG_P (operands[2]))
11337 return "sal{q}\t{%b2, %0|%0, %b2}";
11338 else if (operands[2] == const1_rtx
11339 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11340 return "sal{q}\t%0";
11342 return "sal{q}\t{%2, %0|%0, %2}";
11345 [(set (attr "type")
11346 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11348 (match_operand 0 "register_operand" ""))
11349 (match_operand 2 "const1_operand" ""))
11350 (const_string "alu")
11352 (const_string "ishift")))
11353 (set_attr "mode" "DI")])
11355 (define_insn "*ashldi3_1"
11356 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11357 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11358 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11359 (clobber (reg:CC FLAGS_REG))]
11362 [(set_attr "type" "multi")])
11364 ;; By default we don't ask for a scratch register, because when DImode
11365 ;; values are manipulated, registers are already at a premium. But if
11366 ;; we have one handy, we won't turn it away.
11368 [(match_scratch:SI 3 "r")
11369 (parallel [(set (match_operand:DI 0 "register_operand" "")
11370 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11371 (match_operand:QI 2 "nonmemory_operand" "")))
11372 (clobber (reg:CC FLAGS_REG))])
11374 "!TARGET_64BIT && TARGET_CMOVE"
11376 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11379 [(set (match_operand:DI 0 "register_operand" "")
11380 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11381 (match_operand:QI 2 "nonmemory_operand" "")))
11382 (clobber (reg:CC FLAGS_REG))]
11383 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11384 ? epilogue_completed : reload_completed)"
11386 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11388 (define_insn "x86_shld"
11389 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11390 (ior:SI (ashift:SI (match_dup 0)
11391 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11392 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11393 (minus:QI (const_int 32) (match_dup 2)))))
11394 (clobber (reg:CC FLAGS_REG))]
11396 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11397 [(set_attr "type" "ishift")
11398 (set_attr "prefix_0f" "1")
11399 (set_attr "mode" "SI")
11400 (set_attr "pent_pair" "np")
11401 (set_attr "athlon_decode" "vector")
11402 (set_attr "amdfam10_decode" "vector")])
11404 (define_expand "x86_shift_adj_1"
11405 [(set (reg:CCZ FLAGS_REG)
11406 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11409 (set (match_operand:SI 0 "register_operand" "")
11410 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11411 (match_operand:SI 1 "register_operand" "")
11414 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11415 (match_operand:SI 3 "register_operand" "r")
11420 (define_expand "x86_shift_adj_2"
11421 [(use (match_operand:SI 0 "register_operand" ""))
11422 (use (match_operand:SI 1 "register_operand" ""))
11423 (use (match_operand:QI 2 "register_operand" ""))]
11426 rtx label = gen_label_rtx ();
11429 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11431 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11432 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11433 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11434 gen_rtx_LABEL_REF (VOIDmode, label),
11436 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11437 JUMP_LABEL (tmp) = label;
11439 emit_move_insn (operands[0], operands[1]);
11440 ix86_expand_clear (operands[1]);
11442 emit_label (label);
11443 LABEL_NUSES (label) = 1;
11448 (define_expand "ashlsi3"
11449 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11450 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11451 (match_operand:QI 2 "nonmemory_operand" "")))]
11453 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11455 (define_insn "*ashlsi3_1"
11456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11457 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11458 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11459 (clobber (reg:CC FLAGS_REG))]
11460 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11462 switch (get_attr_type (insn))
11465 gcc_assert (operands[2] == const1_rtx);
11466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11467 return "add{l}\t%0, %0";
11473 if (REG_P (operands[2]))
11474 return "sal{l}\t{%b2, %0|%0, %b2}";
11475 else if (operands[2] == const1_rtx
11476 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11477 return "sal{l}\t%0";
11479 return "sal{l}\t{%2, %0|%0, %2}";
11482 [(set (attr "type")
11483 (cond [(eq_attr "alternative" "1")
11484 (const_string "lea")
11485 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11487 (match_operand 0 "register_operand" ""))
11488 (match_operand 2 "const1_operand" ""))
11489 (const_string "alu")
11491 (const_string "ishift")))
11492 (set_attr "mode" "SI")])
11494 ;; Convert lea to the lea pattern to avoid flags dependency.
11496 [(set (match_operand 0 "register_operand" "")
11497 (ashift (match_operand 1 "index_register_operand" "")
11498 (match_operand:QI 2 "const_int_operand" "")))
11499 (clobber (reg:CC FLAGS_REG))]
11501 && true_regnum (operands[0]) != true_regnum (operands[1])
11502 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11506 enum machine_mode mode = GET_MODE (operands[0]);
11508 if (GET_MODE_SIZE (mode) < 4)
11509 operands[0] = gen_lowpart (SImode, operands[0]);
11511 operands[1] = gen_lowpart (Pmode, operands[1]);
11512 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11514 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11515 if (Pmode != SImode)
11516 pat = gen_rtx_SUBREG (SImode, pat, 0);
11517 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11521 ;; Rare case of shifting RSP is handled by generating move and shift
11523 [(set (match_operand 0 "register_operand" "")
11524 (ashift (match_operand 1 "register_operand" "")
11525 (match_operand:QI 2 "const_int_operand" "")))
11526 (clobber (reg:CC FLAGS_REG))]
11528 && true_regnum (operands[0]) != true_regnum (operands[1])"
11532 emit_move_insn (operands[0], operands[1]);
11533 pat = gen_rtx_SET (VOIDmode, operands[0],
11534 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11535 operands[0], operands[2]));
11536 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11537 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11541 (define_insn "*ashlsi3_1_zext"
11542 [(set (match_operand:DI 0 "register_operand" "=r,r")
11543 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11544 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11545 (clobber (reg:CC FLAGS_REG))]
11546 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11548 switch (get_attr_type (insn))
11551 gcc_assert (operands[2] == const1_rtx);
11552 return "add{l}\t%k0, %k0";
11558 if (REG_P (operands[2]))
11559 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11560 else if (operands[2] == const1_rtx
11561 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11562 return "sal{l}\t%k0";
11564 return "sal{l}\t{%2, %k0|%k0, %2}";
11567 [(set (attr "type")
11568 (cond [(eq_attr "alternative" "1")
11569 (const_string "lea")
11570 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11572 (match_operand 2 "const1_operand" ""))
11573 (const_string "alu")
11575 (const_string "ishift")))
11576 (set_attr "mode" "SI")])
11578 ;; Convert lea to the lea pattern to avoid flags dependency.
11580 [(set (match_operand:DI 0 "register_operand" "")
11581 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11582 (match_operand:QI 2 "const_int_operand" ""))))
11583 (clobber (reg:CC FLAGS_REG))]
11584 "TARGET_64BIT && reload_completed
11585 && true_regnum (operands[0]) != true_regnum (operands[1])"
11586 [(set (match_dup 0) (zero_extend:DI
11587 (subreg:SI (mult:SI (match_dup 1)
11588 (match_dup 2)) 0)))]
11590 operands[1] = gen_lowpart (Pmode, operands[1]);
11591 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11594 ;; This pattern can't accept a variable shift count, since shifts by
11595 ;; zero don't affect the flags. We assume that shifts by constant
11596 ;; zero are optimized away.
11597 (define_insn "*ashlsi3_cmp"
11598 [(set (reg FLAGS_REG)
11600 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11603 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11604 (ashift:SI (match_dup 1) (match_dup 2)))]
11605 "(optimize_function_for_size_p (cfun)
11606 || !TARGET_PARTIAL_FLAG_REG_STALL
11607 || (operands[2] == const1_rtx
11609 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11610 && ix86_match_ccmode (insn, CCGOCmode)
11611 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11613 switch (get_attr_type (insn))
11616 gcc_assert (operands[2] == const1_rtx);
11617 return "add{l}\t%0, %0";
11620 if (REG_P (operands[2]))
11621 return "sal{l}\t{%b2, %0|%0, %b2}";
11622 else if (operands[2] == const1_rtx
11623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11624 return "sal{l}\t%0";
11626 return "sal{l}\t{%2, %0|%0, %2}";
11629 [(set (attr "type")
11630 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11632 (match_operand 0 "register_operand" ""))
11633 (match_operand 2 "const1_operand" ""))
11634 (const_string "alu")
11636 (const_string "ishift")))
11637 (set_attr "mode" "SI")])
11639 (define_insn "*ashlsi3_cconly"
11640 [(set (reg FLAGS_REG)
11642 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11643 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11645 (clobber (match_scratch:SI 0 "=r"))]
11646 "(optimize_function_for_size_p (cfun)
11647 || !TARGET_PARTIAL_FLAG_REG_STALL
11648 || (operands[2] == const1_rtx
11650 || TARGET_DOUBLE_WITH_ADD)))
11651 && ix86_match_ccmode (insn, CCGOCmode)
11652 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11654 switch (get_attr_type (insn))
11657 gcc_assert (operands[2] == const1_rtx);
11658 return "add{l}\t%0, %0";
11661 if (REG_P (operands[2]))
11662 return "sal{l}\t{%b2, %0|%0, %b2}";
11663 else if (operands[2] == const1_rtx
11664 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11665 return "sal{l}\t%0";
11667 return "sal{l}\t{%2, %0|%0, %2}";
11670 [(set (attr "type")
11671 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11673 (match_operand 0 "register_operand" ""))
11674 (match_operand 2 "const1_operand" ""))
11675 (const_string "alu")
11677 (const_string "ishift")))
11678 (set_attr "mode" "SI")])
11680 (define_insn "*ashlsi3_cmp_zext"
11681 [(set (reg FLAGS_REG)
11683 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11684 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11686 (set (match_operand:DI 0 "register_operand" "=r")
11687 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11689 && (optimize_function_for_size_p (cfun)
11690 || !TARGET_PARTIAL_FLAG_REG_STALL
11691 || (operands[2] == const1_rtx
11693 || TARGET_DOUBLE_WITH_ADD)))
11694 && ix86_match_ccmode (insn, CCGOCmode)
11695 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11697 switch (get_attr_type (insn))
11700 gcc_assert (operands[2] == const1_rtx);
11701 return "add{l}\t%k0, %k0";
11704 if (REG_P (operands[2]))
11705 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11706 else if (operands[2] == const1_rtx
11707 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11708 return "sal{l}\t%k0";
11710 return "sal{l}\t{%2, %k0|%k0, %2}";
11713 [(set (attr "type")
11714 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11716 (match_operand 2 "const1_operand" ""))
11717 (const_string "alu")
11719 (const_string "ishift")))
11720 (set_attr "mode" "SI")])
11722 (define_expand "ashlhi3"
11723 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11724 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11725 (match_operand:QI 2 "nonmemory_operand" "")))]
11726 "TARGET_HIMODE_MATH"
11727 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11729 (define_insn "*ashlhi3_1_lea"
11730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11731 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11732 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11733 (clobber (reg:CC FLAGS_REG))]
11734 "!TARGET_PARTIAL_REG_STALL
11735 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11737 switch (get_attr_type (insn))
11742 gcc_assert (operands[2] == const1_rtx);
11743 return "add{w}\t%0, %0";
11746 if (REG_P (operands[2]))
11747 return "sal{w}\t{%b2, %0|%0, %b2}";
11748 else if (operands[2] == const1_rtx
11749 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11750 return "sal{w}\t%0";
11752 return "sal{w}\t{%2, %0|%0, %2}";
11755 [(set (attr "type")
11756 (cond [(eq_attr "alternative" "1")
11757 (const_string "lea")
11758 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11760 (match_operand 0 "register_operand" ""))
11761 (match_operand 2 "const1_operand" ""))
11762 (const_string "alu")
11764 (const_string "ishift")))
11765 (set_attr "mode" "HI,SI")])
11767 (define_insn "*ashlhi3_1"
11768 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11769 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11770 (match_operand:QI 2 "nonmemory_operand" "cI")))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "TARGET_PARTIAL_REG_STALL
11773 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11775 switch (get_attr_type (insn))
11778 gcc_assert (operands[2] == const1_rtx);
11779 return "add{w}\t%0, %0";
11782 if (REG_P (operands[2]))
11783 return "sal{w}\t{%b2, %0|%0, %b2}";
11784 else if (operands[2] == const1_rtx
11785 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11786 return "sal{w}\t%0";
11788 return "sal{w}\t{%2, %0|%0, %2}";
11791 [(set (attr "type")
11792 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11794 (match_operand 0 "register_operand" ""))
11795 (match_operand 2 "const1_operand" ""))
11796 (const_string "alu")
11798 (const_string "ishift")))
11799 (set_attr "mode" "HI")])
11801 ;; This pattern can't accept a variable shift count, since shifts by
11802 ;; zero don't affect the flags. We assume that shifts by constant
11803 ;; zero are optimized away.
11804 (define_insn "*ashlhi3_cmp"
11805 [(set (reg FLAGS_REG)
11807 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11811 (ashift:HI (match_dup 1) (match_dup 2)))]
11812 "(optimize_function_for_size_p (cfun)
11813 || !TARGET_PARTIAL_FLAG_REG_STALL
11814 || (operands[2] == const1_rtx
11816 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11817 && ix86_match_ccmode (insn, CCGOCmode)
11818 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11820 switch (get_attr_type (insn))
11823 gcc_assert (operands[2] == const1_rtx);
11824 return "add{w}\t%0, %0";
11827 if (REG_P (operands[2]))
11828 return "sal{w}\t{%b2, %0|%0, %b2}";
11829 else if (operands[2] == const1_rtx
11830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11831 return "sal{w}\t%0";
11833 return "sal{w}\t{%2, %0|%0, %2}";
11836 [(set (attr "type")
11837 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11839 (match_operand 0 "register_operand" ""))
11840 (match_operand 2 "const1_operand" ""))
11841 (const_string "alu")
11843 (const_string "ishift")))
11844 (set_attr "mode" "HI")])
11846 (define_insn "*ashlhi3_cconly"
11847 [(set (reg FLAGS_REG)
11849 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11850 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11852 (clobber (match_scratch:HI 0 "=r"))]
11853 "(optimize_function_for_size_p (cfun)
11854 || !TARGET_PARTIAL_FLAG_REG_STALL
11855 || (operands[2] == const1_rtx
11857 || TARGET_DOUBLE_WITH_ADD)))
11858 && ix86_match_ccmode (insn, CCGOCmode)
11859 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11861 switch (get_attr_type (insn))
11864 gcc_assert (operands[2] == const1_rtx);
11865 return "add{w}\t%0, %0";
11868 if (REG_P (operands[2]))
11869 return "sal{w}\t{%b2, %0|%0, %b2}";
11870 else if (operands[2] == const1_rtx
11871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11872 return "sal{w}\t%0";
11874 return "sal{w}\t{%2, %0|%0, %2}";
11877 [(set (attr "type")
11878 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11880 (match_operand 0 "register_operand" ""))
11881 (match_operand 2 "const1_operand" ""))
11882 (const_string "alu")
11884 (const_string "ishift")))
11885 (set_attr "mode" "HI")])
11887 (define_expand "ashlqi3"
11888 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11889 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11890 (match_operand:QI 2 "nonmemory_operand" "")))]
11891 "TARGET_QIMODE_MATH"
11892 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11894 ;; %%% Potential partial reg stall on alternative 2. What to do?
11896 (define_insn "*ashlqi3_1_lea"
11897 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11898 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11899 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "!TARGET_PARTIAL_REG_STALL
11902 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11904 switch (get_attr_type (insn))
11909 gcc_assert (operands[2] == const1_rtx);
11910 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11911 return "add{l}\t%k0, %k0";
11913 return "add{b}\t%0, %0";
11916 if (REG_P (operands[2]))
11918 if (get_attr_mode (insn) == MODE_SI)
11919 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11921 return "sal{b}\t{%b2, %0|%0, %b2}";
11923 else if (operands[2] == const1_rtx
11924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11926 if (get_attr_mode (insn) == MODE_SI)
11927 return "sal{l}\t%0";
11929 return "sal{b}\t%0";
11933 if (get_attr_mode (insn) == MODE_SI)
11934 return "sal{l}\t{%2, %k0|%k0, %2}";
11936 return "sal{b}\t{%2, %0|%0, %2}";
11940 [(set (attr "type")
11941 (cond [(eq_attr "alternative" "2")
11942 (const_string "lea")
11943 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11945 (match_operand 0 "register_operand" ""))
11946 (match_operand 2 "const1_operand" ""))
11947 (const_string "alu")
11949 (const_string "ishift")))
11950 (set_attr "mode" "QI,SI,SI")])
11952 (define_insn "*ashlqi3_1"
11953 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11954 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11955 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11956 (clobber (reg:CC FLAGS_REG))]
11957 "TARGET_PARTIAL_REG_STALL
11958 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11960 switch (get_attr_type (insn))
11963 gcc_assert (operands[2] == const1_rtx);
11964 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11965 return "add{l}\t%k0, %k0";
11967 return "add{b}\t%0, %0";
11970 if (REG_P (operands[2]))
11972 if (get_attr_mode (insn) == MODE_SI)
11973 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11975 return "sal{b}\t{%b2, %0|%0, %b2}";
11977 else if (operands[2] == const1_rtx
11978 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11980 if (get_attr_mode (insn) == MODE_SI)
11981 return "sal{l}\t%0";
11983 return "sal{b}\t%0";
11987 if (get_attr_mode (insn) == MODE_SI)
11988 return "sal{l}\t{%2, %k0|%k0, %2}";
11990 return "sal{b}\t{%2, %0|%0, %2}";
11994 [(set (attr "type")
11995 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11997 (match_operand 0 "register_operand" ""))
11998 (match_operand 2 "const1_operand" ""))
11999 (const_string "alu")
12001 (const_string "ishift")))
12002 (set_attr "mode" "QI,SI")])
12004 ;; This pattern can't accept a variable shift count, since shifts by
12005 ;; zero don't affect the flags. We assume that shifts by constant
12006 ;; zero are optimized away.
12007 (define_insn "*ashlqi3_cmp"
12008 [(set (reg FLAGS_REG)
12010 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12011 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12013 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12014 (ashift:QI (match_dup 1) (match_dup 2)))]
12015 "(optimize_function_for_size_p (cfun)
12016 || !TARGET_PARTIAL_FLAG_REG_STALL
12017 || (operands[2] == const1_rtx
12019 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12020 && ix86_match_ccmode (insn, CCGOCmode)
12021 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12023 switch (get_attr_type (insn))
12026 gcc_assert (operands[2] == const1_rtx);
12027 return "add{b}\t%0, %0";
12030 if (REG_P (operands[2]))
12031 return "sal{b}\t{%b2, %0|%0, %b2}";
12032 else if (operands[2] == const1_rtx
12033 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12034 return "sal{b}\t%0";
12036 return "sal{b}\t{%2, %0|%0, %2}";
12039 [(set (attr "type")
12040 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12042 (match_operand 0 "register_operand" ""))
12043 (match_operand 2 "const1_operand" ""))
12044 (const_string "alu")
12046 (const_string "ishift")))
12047 (set_attr "mode" "QI")])
12049 (define_insn "*ashlqi3_cconly"
12050 [(set (reg FLAGS_REG)
12052 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12055 (clobber (match_scratch:QI 0 "=q"))]
12056 "(optimize_function_for_size_p (cfun)
12057 || !TARGET_PARTIAL_FLAG_REG_STALL
12058 || (operands[2] == const1_rtx
12060 || TARGET_DOUBLE_WITH_ADD)))
12061 && ix86_match_ccmode (insn, CCGOCmode)
12062 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12064 switch (get_attr_type (insn))
12067 gcc_assert (operands[2] == const1_rtx);
12068 return "add{b}\t%0, %0";
12071 if (REG_P (operands[2]))
12072 return "sal{b}\t{%b2, %0|%0, %b2}";
12073 else if (operands[2] == const1_rtx
12074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12075 return "sal{b}\t%0";
12077 return "sal{b}\t{%2, %0|%0, %2}";
12080 [(set (attr "type")
12081 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12083 (match_operand 0 "register_operand" ""))
12084 (match_operand 2 "const1_operand" ""))
12085 (const_string "alu")
12087 (const_string "ishift")))
12088 (set_attr "mode" "QI")])
12090 ;; See comment above `ashldi3' about how this works.
12092 (define_expand "ashrti3"
12093 [(set (match_operand:TI 0 "register_operand" "")
12094 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12095 (match_operand:QI 2 "nonmemory_operand" "")))]
12097 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12099 (define_insn "*ashrti3_1"
12100 [(set (match_operand:TI 0 "register_operand" "=r")
12101 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12102 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12103 (clobber (reg:CC FLAGS_REG))]
12106 [(set_attr "type" "multi")])
12109 [(match_scratch:DI 3 "r")
12110 (parallel [(set (match_operand:TI 0 "register_operand" "")
12111 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12112 (match_operand:QI 2 "nonmemory_operand" "")))
12113 (clobber (reg:CC FLAGS_REG))])
12117 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12120 [(set (match_operand:TI 0 "register_operand" "")
12121 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12122 (match_operand:QI 2 "nonmemory_operand" "")))
12123 (clobber (reg:CC FLAGS_REG))]
12124 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12125 ? epilogue_completed : reload_completed)"
12127 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12129 (define_insn "x86_64_shrd"
12130 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12131 (ior:DI (ashiftrt:DI (match_dup 0)
12132 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12133 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12134 (minus:QI (const_int 64) (match_dup 2)))))
12135 (clobber (reg:CC FLAGS_REG))]
12137 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12138 [(set_attr "type" "ishift")
12139 (set_attr "prefix_0f" "1")
12140 (set_attr "mode" "DI")
12141 (set_attr "athlon_decode" "vector")
12142 (set_attr "amdfam10_decode" "vector")])
12144 (define_expand "ashrdi3"
12145 [(set (match_operand:DI 0 "shiftdi_operand" "")
12146 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12147 (match_operand:QI 2 "nonmemory_operand" "")))]
12149 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12151 (define_expand "x86_64_shift_adj_3"
12152 [(use (match_operand:DI 0 "register_operand" ""))
12153 (use (match_operand:DI 1 "register_operand" ""))
12154 (use (match_operand:QI 2 "register_operand" ""))]
12157 rtx label = gen_label_rtx ();
12160 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12162 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12163 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12164 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12165 gen_rtx_LABEL_REF (VOIDmode, label),
12167 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12168 JUMP_LABEL (tmp) = label;
12170 emit_move_insn (operands[0], operands[1]);
12171 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12173 emit_label (label);
12174 LABEL_NUSES (label) = 1;
12179 (define_insn "ashrdi3_63_rex64"
12180 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12181 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12182 (match_operand:DI 2 "const_int_operand" "i,i")))
12183 (clobber (reg:CC FLAGS_REG))]
12184 "TARGET_64BIT && INTVAL (operands[2]) == 63
12185 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12186 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189 sar{q}\t{%2, %0|%0, %2}"
12190 [(set_attr "type" "imovx,ishift")
12191 (set_attr "prefix_0f" "0,*")
12192 (set_attr "length_immediate" "0,*")
12193 (set_attr "modrm" "0,1")
12194 (set_attr "mode" "DI")])
12196 (define_insn "*ashrdi3_1_one_bit_rex64"
12197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12198 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12199 (match_operand:QI 2 "const1_operand" "")))
12200 (clobber (reg:CC FLAGS_REG))]
12202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12203 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12205 [(set_attr "type" "ishift")
12206 (set (attr "length")
12207 (if_then_else (match_operand:DI 0 "register_operand" "")
12209 (const_string "*")))])
12211 (define_insn "*ashrdi3_1_rex64"
12212 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12213 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12214 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12218 sar{q}\t{%2, %0|%0, %2}
12219 sar{q}\t{%b2, %0|%0, %b2}"
12220 [(set_attr "type" "ishift")
12221 (set_attr "mode" "DI")])
12223 ;; This pattern can't accept a variable shift count, since shifts by
12224 ;; zero don't affect the flags. We assume that shifts by constant
12225 ;; zero are optimized away.
12226 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12227 [(set (reg FLAGS_REG)
12229 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12230 (match_operand:QI 2 "const1_operand" ""))
12232 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12236 && ix86_match_ccmode (insn, CCGOCmode)
12237 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12239 [(set_attr "type" "ishift")
12240 (set (attr "length")
12241 (if_then_else (match_operand:DI 0 "register_operand" "")
12243 (const_string "*")))])
12245 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12246 [(set (reg FLAGS_REG)
12248 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12249 (match_operand:QI 2 "const1_operand" ""))
12251 (clobber (match_scratch:DI 0 "=r"))]
12253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12254 && ix86_match_ccmode (insn, CCGOCmode)
12255 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12257 [(set_attr "type" "ishift")
12258 (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags. We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*ashrdi3_cmp_rex64"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12270 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12272 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273 && ix86_match_ccmode (insn, CCGOCmode)
12274 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275 "sar{q}\t{%2, %0|%0, %2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "DI")])
12279 (define_insn "*ashrdi3_cconly_rex64"
12280 [(set (reg FLAGS_REG)
12282 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12283 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12285 (clobber (match_scratch:DI 0 "=r"))]
12287 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12288 && ix86_match_ccmode (insn, CCGOCmode)
12289 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12290 "sar{q}\t{%2, %0|%0, %2}"
12291 [(set_attr "type" "ishift")
12292 (set_attr "mode" "DI")])
12294 (define_insn "*ashrdi3_1"
12295 [(set (match_operand:DI 0 "register_operand" "=r")
12296 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12297 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12298 (clobber (reg:CC FLAGS_REG))]
12301 [(set_attr "type" "multi")])
12303 ;; By default we don't ask for a scratch register, because when DImode
12304 ;; values are manipulated, registers are already at a premium. But if
12305 ;; we have one handy, we won't turn it away.
12307 [(match_scratch:SI 3 "r")
12308 (parallel [(set (match_operand:DI 0 "register_operand" "")
12309 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12310 (match_operand:QI 2 "nonmemory_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))])
12313 "!TARGET_64BIT && TARGET_CMOVE"
12315 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12318 [(set (match_operand:DI 0 "register_operand" "")
12319 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12320 (match_operand:QI 2 "nonmemory_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12323 ? epilogue_completed : reload_completed)"
12325 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12327 (define_insn "x86_shrd"
12328 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12329 (ior:SI (ashiftrt:SI (match_dup 0)
12330 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12331 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12332 (minus:QI (const_int 32) (match_dup 2)))))
12333 (clobber (reg:CC FLAGS_REG))]
12335 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12336 [(set_attr "type" "ishift")
12337 (set_attr "prefix_0f" "1")
12338 (set_attr "pent_pair" "np")
12339 (set_attr "mode" "SI")])
12341 (define_expand "x86_shift_adj_3"
12342 [(use (match_operand:SI 0 "register_operand" ""))
12343 (use (match_operand:SI 1 "register_operand" ""))
12344 (use (match_operand:QI 2 "register_operand" ""))]
12347 rtx label = gen_label_rtx ();
12350 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12352 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12353 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12354 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12355 gen_rtx_LABEL_REF (VOIDmode, label),
12357 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12358 JUMP_LABEL (tmp) = label;
12360 emit_move_insn (operands[0], operands[1]);
12361 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12363 emit_label (label);
12364 LABEL_NUSES (label) = 1;
12369 (define_expand "ashrsi3_31"
12370 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12371 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12372 (match_operand:SI 2 "const_int_operand" "i,i")))
12373 (clobber (reg:CC FLAGS_REG))])]
12376 (define_insn "*ashrsi3_31"
12377 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12378 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12379 (match_operand:SI 2 "const_int_operand" "i,i")))
12380 (clobber (reg:CC FLAGS_REG))]
12381 "INTVAL (operands[2]) == 31
12382 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12386 sar{l}\t{%2, %0|%0, %2}"
12387 [(set_attr "type" "imovx,ishift")
12388 (set_attr "prefix_0f" "0,*")
12389 (set_attr "length_immediate" "0,*")
12390 (set_attr "modrm" "0,1")
12391 (set_attr "mode" "SI")])
12393 (define_insn "*ashrsi3_31_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12395 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12396 (match_operand:SI 2 "const_int_operand" "i,i"))))
12397 (clobber (reg:CC FLAGS_REG))]
12398 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12399 && INTVAL (operands[2]) == 31
12400 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12403 sar{l}\t{%2, %k0|%k0, %2}"
12404 [(set_attr "type" "imovx,ishift")
12405 (set_attr "prefix_0f" "0,*")
12406 (set_attr "length_immediate" "0,*")
12407 (set_attr "modrm" "0,1")
12408 (set_attr "mode" "SI")])
12410 (define_expand "ashrsi3"
12411 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12412 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12413 (match_operand:QI 2 "nonmemory_operand" "")))]
12415 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12417 (define_insn "*ashrsi3_1_one_bit"
12418 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12419 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12420 (match_operand:QI 2 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12425 [(set_attr "type" "ishift")
12426 (set (attr "length")
12427 (if_then_else (match_operand:SI 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*ashrsi3_1_one_bit_zext"
12432 [(set (match_operand:DI 0 "register_operand" "=r")
12433 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12434 (match_operand:QI 2 "const1_operand" ""))))
12435 (clobber (reg:CC FLAGS_REG))]
12437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12438 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12440 [(set_attr "type" "ishift")
12441 (set_attr "length" "2")])
12443 (define_insn "*ashrsi3_1"
12444 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12445 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12446 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12450 sar{l}\t{%2, %0|%0, %2}
12451 sar{l}\t{%b2, %0|%0, %b2}"
12452 [(set_attr "type" "ishift")
12453 (set_attr "mode" "SI")])
12455 (define_insn "*ashrsi3_1_zext"
12456 [(set (match_operand:DI 0 "register_operand" "=r,r")
12457 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12458 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12459 (clobber (reg:CC FLAGS_REG))]
12460 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12462 sar{l}\t{%2, %k0|%k0, %2}
12463 sar{l}\t{%b2, %k0|%k0, %b2}"
12464 [(set_attr "type" "ishift")
12465 (set_attr "mode" "SI")])
12467 ;; This pattern can't accept a variable shift count, since shifts by
12468 ;; zero don't affect the flags. We assume that shifts by constant
12469 ;; zero are optimized away.
12470 (define_insn "*ashrsi3_one_bit_cmp"
12471 [(set (reg FLAGS_REG)
12473 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12474 (match_operand:QI 2 "const1_operand" ""))
12476 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12477 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12478 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12479 && ix86_match_ccmode (insn, CCGOCmode)
12480 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12482 [(set_attr "type" "ishift")
12483 (set (attr "length")
12484 (if_then_else (match_operand:SI 0 "register_operand" "")
12486 (const_string "*")))])
12488 (define_insn "*ashrsi3_one_bit_cconly"
12489 [(set (reg FLAGS_REG)
12491 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12492 (match_operand:QI 2 "const1_operand" ""))
12494 (clobber (match_scratch:SI 0 "=r"))]
12495 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496 && ix86_match_ccmode (insn, CCGOCmode)
12497 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499 [(set_attr "type" "ishift")
12500 (set_attr "length" "2")])
12502 (define_insn "*ashrsi3_one_bit_cmp_zext"
12503 [(set (reg FLAGS_REG)
12505 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12506 (match_operand:QI 2 "const1_operand" ""))
12508 (set (match_operand:DI 0 "register_operand" "=r")
12509 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12511 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12512 && ix86_match_ccmode (insn, CCmode)
12513 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12515 [(set_attr "type" "ishift")
12516 (set_attr "length" "2")])
12518 ;; This pattern can't accept a variable shift count, since shifts by
12519 ;; zero don't affect the flags. We assume that shifts by constant
12520 ;; zero are optimized away.
12521 (define_insn "*ashrsi3_cmp"
12522 [(set (reg FLAGS_REG)
12524 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12527 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12528 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12529 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12530 && ix86_match_ccmode (insn, CCGOCmode)
12531 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12532 "sar{l}\t{%2, %0|%0, %2}"
12533 [(set_attr "type" "ishift")
12534 (set_attr "mode" "SI")])
12536 (define_insn "*ashrsi3_cconly"
12537 [(set (reg FLAGS_REG)
12539 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12540 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12542 (clobber (match_scratch:SI 0 "=r"))]
12543 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544 && ix86_match_ccmode (insn, CCGOCmode)
12545 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546 "sar{l}\t{%2, %0|%0, %2}"
12547 [(set_attr "type" "ishift")
12548 (set_attr "mode" "SI")])
12550 (define_insn "*ashrsi3_cmp_zext"
12551 [(set (reg FLAGS_REG)
12553 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12554 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12556 (set (match_operand:DI 0 "register_operand" "=r")
12557 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12559 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12560 && ix86_match_ccmode (insn, CCGOCmode)
12561 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12562 "sar{l}\t{%2, %k0|%k0, %2}"
12563 [(set_attr "type" "ishift")
12564 (set_attr "mode" "SI")])
12566 (define_expand "ashrhi3"
12567 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12568 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12569 (match_operand:QI 2 "nonmemory_operand" "")))]
12570 "TARGET_HIMODE_MATH"
12571 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12573 (define_insn "*ashrhi3_1_one_bit"
12574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12575 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const1_operand" "")))
12577 (clobber (reg:CC FLAGS_REG))]
12578 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12579 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12581 [(set_attr "type" "ishift")
12582 (set (attr "length")
12583 (if_then_else (match_operand 0 "register_operand" "")
12585 (const_string "*")))])
12587 (define_insn "*ashrhi3_1"
12588 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12589 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12590 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12591 (clobber (reg:CC FLAGS_REG))]
12592 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12594 sar{w}\t{%2, %0|%0, %2}
12595 sar{w}\t{%b2, %0|%0, %b2}"
12596 [(set_attr "type" "ishift")
12597 (set_attr "mode" "HI")])
12599 ;; This pattern can't accept a variable shift count, since shifts by
12600 ;; zero don't affect the flags. We assume that shifts by constant
12601 ;; zero are optimized away.
12602 (define_insn "*ashrhi3_one_bit_cmp"
12603 [(set (reg FLAGS_REG)
12605 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12606 (match_operand:QI 2 "const1_operand" ""))
12608 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12609 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12610 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12611 && ix86_match_ccmode (insn, CCGOCmode)
12612 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12614 [(set_attr "type" "ishift")
12615 (set (attr "length")
12616 (if_then_else (match_operand 0 "register_operand" "")
12618 (const_string "*")))])
12620 (define_insn "*ashrhi3_one_bit_cconly"
12621 [(set (reg FLAGS_REG)
12623 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624 (match_operand:QI 2 "const1_operand" ""))
12626 (clobber (match_scratch:HI 0 "=r"))]
12627 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12628 && ix86_match_ccmode (insn, CCGOCmode)
12629 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12631 [(set_attr "type" "ishift")
12632 (set_attr "length" "2")])
12634 ;; This pattern can't accept a variable shift count, since shifts by
12635 ;; zero don't affect the flags. We assume that shifts by constant
12636 ;; zero are optimized away.
12637 (define_insn "*ashrhi3_cmp"
12638 [(set (reg FLAGS_REG)
12640 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12643 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12645 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12646 && ix86_match_ccmode (insn, CCGOCmode)
12647 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12648 "sar{w}\t{%2, %0|%0, %2}"
12649 [(set_attr "type" "ishift")
12650 (set_attr "mode" "HI")])
12652 (define_insn "*ashrhi3_cconly"
12653 [(set (reg FLAGS_REG)
12655 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12656 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12658 (clobber (match_scratch:HI 0 "=r"))]
12659 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12660 && ix86_match_ccmode (insn, CCGOCmode)
12661 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12662 "sar{w}\t{%2, %0|%0, %2}"
12663 [(set_attr "type" "ishift")
12664 (set_attr "mode" "HI")])
12666 (define_expand "ashrqi3"
12667 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12668 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12669 (match_operand:QI 2 "nonmemory_operand" "")))]
12670 "TARGET_QIMODE_MATH"
12671 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12673 (define_insn "*ashrqi3_1_one_bit"
12674 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12675 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12676 (match_operand:QI 2 "const1_operand" "")))
12677 (clobber (reg:CC FLAGS_REG))]
12678 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12681 [(set_attr "type" "ishift")
12682 (set (attr "length")
12683 (if_then_else (match_operand 0 "register_operand" "")
12685 (const_string "*")))])
12687 (define_insn "*ashrqi3_1_one_bit_slp"
12688 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12689 (ashiftrt:QI (match_dup 0)
12690 (match_operand:QI 1 "const1_operand" "")))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12693 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12694 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12696 [(set_attr "type" "ishift1")
12697 (set (attr "length")
12698 (if_then_else (match_operand 0 "register_operand" "")
12700 (const_string "*")))])
12702 (define_insn "*ashrqi3_1"
12703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706 (clobber (reg:CC FLAGS_REG))]
12707 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12709 sar{b}\t{%2, %0|%0, %2}
12710 sar{b}\t{%b2, %0|%0, %b2}"
12711 [(set_attr "type" "ishift")
12712 (set_attr "mode" "QI")])
12714 (define_insn "*ashrqi3_1_slp"
12715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12716 (ashiftrt:QI (match_dup 0)
12717 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12720 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12722 sar{b}\t{%1, %0|%0, %1}
12723 sar{b}\t{%b1, %0|%0, %b1}"
12724 [(set_attr "type" "ishift1")
12725 (set_attr "mode" "QI")])
12727 ;; This pattern can't accept a variable shift count, since shifts by
12728 ;; zero don't affect the flags. We assume that shifts by constant
12729 ;; zero are optimized away.
12730 (define_insn "*ashrqi3_one_bit_cmp"
12731 [(set (reg FLAGS_REG)
12733 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12734 (match_operand:QI 2 "const1_operand" "I"))
12736 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12737 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12738 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12739 && ix86_match_ccmode (insn, CCGOCmode)
12740 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12742 [(set_attr "type" "ishift")
12743 (set (attr "length")
12744 (if_then_else (match_operand 0 "register_operand" "")
12746 (const_string "*")))])
12748 (define_insn "*ashrqi3_one_bit_cconly"
12749 [(set (reg FLAGS_REG)
12751 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752 (match_operand:QI 2 "const1_operand" ""))
12754 (clobber (match_scratch:QI 0 "=q"))]
12755 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12756 && ix86_match_ccmode (insn, CCGOCmode)
12757 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12759 [(set_attr "type" "ishift")
12760 (set_attr "length" "2")])
12762 ;; This pattern can't accept a variable shift count, since shifts by
12763 ;; zero don't affect the flags. We assume that shifts by constant
12764 ;; zero are optimized away.
12765 (define_insn "*ashrqi3_cmp"
12766 [(set (reg FLAGS_REG)
12768 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12771 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12772 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12773 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12774 && ix86_match_ccmode (insn, CCGOCmode)
12775 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12776 "sar{b}\t{%2, %0|%0, %2}"
12777 [(set_attr "type" "ishift")
12778 (set_attr "mode" "QI")])
12780 (define_insn "*ashrqi3_cconly"
12781 [(set (reg FLAGS_REG)
12783 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12784 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12786 (clobber (match_scratch:QI 0 "=q"))]
12787 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12788 && ix86_match_ccmode (insn, CCGOCmode)
12789 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12790 "sar{b}\t{%2, %0|%0, %2}"
12791 [(set_attr "type" "ishift")
12792 (set_attr "mode" "QI")])
12795 ;; Logical shift instructions
12797 ;; See comment above `ashldi3' about how this works.
12799 (define_expand "lshrti3"
12800 [(set (match_operand:TI 0 "register_operand" "")
12801 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12802 (match_operand:QI 2 "nonmemory_operand" "")))]
12804 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12806 ;; This pattern must be defined before *lshrti3_1 to prevent
12807 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12809 (define_insn "*avx_lshrti3"
12810 [(set (match_operand:TI 0 "register_operand" "=x")
12811 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12812 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12815 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12816 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12818 [(set_attr "type" "sseishft")
12819 (set_attr "prefix" "vex")
12820 (set_attr "mode" "TI")])
12822 (define_insn "sse2_lshrti3"
12823 [(set (match_operand:TI 0 "register_operand" "=x")
12824 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12825 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12828 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12829 return "psrldq\t{%2, %0|%0, %2}";
12831 [(set_attr "type" "sseishft")
12832 (set_attr "prefix_data16" "1")
12833 (set_attr "mode" "TI")])
12835 (define_insn "*lshrti3_1"
12836 [(set (match_operand:TI 0 "register_operand" "=r")
12837 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12838 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12839 (clobber (reg:CC FLAGS_REG))]
12842 [(set_attr "type" "multi")])
12845 [(match_scratch:DI 3 "r")
12846 (parallel [(set (match_operand:TI 0 "register_operand" "")
12847 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12848 (match_operand:QI 2 "nonmemory_operand" "")))
12849 (clobber (reg:CC FLAGS_REG))])
12853 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12856 [(set (match_operand:TI 0 "register_operand" "")
12857 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12858 (match_operand:QI 2 "nonmemory_operand" "")))
12859 (clobber (reg:CC FLAGS_REG))]
12860 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12861 ? epilogue_completed : reload_completed)"
12863 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12865 (define_expand "lshrdi3"
12866 [(set (match_operand:DI 0 "shiftdi_operand" "")
12867 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12868 (match_operand:QI 2 "nonmemory_operand" "")))]
12870 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12872 (define_insn "*lshrdi3_1_one_bit_rex64"
12873 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12874 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12875 (match_operand:QI 2 "const1_operand" "")))
12876 (clobber (reg:CC FLAGS_REG))]
12878 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12879 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12881 [(set_attr "type" "ishift")
12882 (set (attr "length")
12883 (if_then_else (match_operand:DI 0 "register_operand" "")
12885 (const_string "*")))])
12887 (define_insn "*lshrdi3_1_rex64"
12888 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12889 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12890 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12891 (clobber (reg:CC FLAGS_REG))]
12892 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12894 shr{q}\t{%2, %0|%0, %2}
12895 shr{q}\t{%b2, %0|%0, %b2}"
12896 [(set_attr "type" "ishift")
12897 (set_attr "mode" "DI")])
12899 ;; This pattern can't accept a variable shift count, since shifts by
12900 ;; zero don't affect the flags. We assume that shifts by constant
12901 ;; zero are optimized away.
12902 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12903 [(set (reg FLAGS_REG)
12905 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906 (match_operand:QI 2 "const1_operand" ""))
12908 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12909 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12911 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12912 && ix86_match_ccmode (insn, CCGOCmode)
12913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12915 [(set_attr "type" "ishift")
12916 (set (attr "length")
12917 (if_then_else (match_operand:DI 0 "register_operand" "")
12919 (const_string "*")))])
12921 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12922 [(set (reg FLAGS_REG)
12924 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const1_operand" ""))
12927 (clobber (match_scratch:DI 0 "=r"))]
12929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12930 && ix86_match_ccmode (insn, CCGOCmode)
12931 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12933 [(set_attr "type" "ishift")
12934 (set_attr "length" "2")])
12936 ;; This pattern can't accept a variable shift count, since shifts by
12937 ;; zero don't affect the flags. We assume that shifts by constant
12938 ;; zero are optimized away.
12939 (define_insn "*lshrdi3_cmp_rex64"
12940 [(set (reg FLAGS_REG)
12942 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12946 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12948 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949 && ix86_match_ccmode (insn, CCGOCmode)
12950 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951 "shr{q}\t{%2, %0|%0, %2}"
12952 [(set_attr "type" "ishift")
12953 (set_attr "mode" "DI")])
12955 (define_insn "*lshrdi3_cconly_rex64"
12956 [(set (reg FLAGS_REG)
12958 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12959 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12961 (clobber (match_scratch:DI 0 "=r"))]
12963 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12964 && ix86_match_ccmode (insn, CCGOCmode)
12965 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12966 "shr{q}\t{%2, %0|%0, %2}"
12967 [(set_attr "type" "ishift")
12968 (set_attr "mode" "DI")])
12970 (define_insn "*lshrdi3_1"
12971 [(set (match_operand:DI 0 "register_operand" "=r")
12972 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12973 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12974 (clobber (reg:CC FLAGS_REG))]
12977 [(set_attr "type" "multi")])
12979 ;; By default we don't ask for a scratch register, because when DImode
12980 ;; values are manipulated, registers are already at a premium. But if
12981 ;; we have one handy, we won't turn it away.
12983 [(match_scratch:SI 3 "r")
12984 (parallel [(set (match_operand:DI 0 "register_operand" "")
12985 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12986 (match_operand:QI 2 "nonmemory_operand" "")))
12987 (clobber (reg:CC FLAGS_REG))])
12989 "!TARGET_64BIT && TARGET_CMOVE"
12991 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12994 [(set (match_operand:DI 0 "register_operand" "")
12995 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12996 (match_operand:QI 2 "nonmemory_operand" "")))
12997 (clobber (reg:CC FLAGS_REG))]
12998 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12999 ? epilogue_completed : reload_completed)"
13001 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13003 (define_expand "lshrsi3"
13004 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13005 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13006 (match_operand:QI 2 "nonmemory_operand" "")))]
13008 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13010 (define_insn "*lshrsi3_1_one_bit"
13011 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13012 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13013 (match_operand:QI 2 "const1_operand" "")))
13014 (clobber (reg:CC FLAGS_REG))]
13015 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13018 [(set_attr "type" "ishift")
13019 (set (attr "length")
13020 (if_then_else (match_operand:SI 0 "register_operand" "")
13022 (const_string "*")))])
13024 (define_insn "*lshrsi3_1_one_bit_zext"
13025 [(set (match_operand:DI 0 "register_operand" "=r")
13026 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13027 (match_operand:QI 2 "const1_operand" "")))
13028 (clobber (reg:CC FLAGS_REG))]
13030 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13031 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13033 [(set_attr "type" "ishift")
13034 (set_attr "length" "2")])
13036 (define_insn "*lshrsi3_1"
13037 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13038 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13039 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13040 (clobber (reg:CC FLAGS_REG))]
13041 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13043 shr{l}\t{%2, %0|%0, %2}
13044 shr{l}\t{%b2, %0|%0, %b2}"
13045 [(set_attr "type" "ishift")
13046 (set_attr "mode" "SI")])
13048 (define_insn "*lshrsi3_1_zext"
13049 [(set (match_operand:DI 0 "register_operand" "=r,r")
13051 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13052 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13053 (clobber (reg:CC FLAGS_REG))]
13054 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13056 shr{l}\t{%2, %k0|%k0, %2}
13057 shr{l}\t{%b2, %k0|%k0, %b2}"
13058 [(set_attr "type" "ishift")
13059 (set_attr "mode" "SI")])
13061 ;; This pattern can't accept a variable shift count, since shifts by
13062 ;; zero don't affect the flags. We assume that shifts by constant
13063 ;; zero are optimized away.
13064 (define_insn "*lshrsi3_one_bit_cmp"
13065 [(set (reg FLAGS_REG)
13067 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13068 (match_operand:QI 2 "const1_operand" ""))
13070 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13071 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13072 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13073 && ix86_match_ccmode (insn, CCGOCmode)
13074 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13076 [(set_attr "type" "ishift")
13077 (set (attr "length")
13078 (if_then_else (match_operand:SI 0 "register_operand" "")
13080 (const_string "*")))])
13082 (define_insn "*lshrsi3_one_bit_cconly"
13083 [(set (reg FLAGS_REG)
13085 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086 (match_operand:QI 2 "const1_operand" ""))
13088 (clobber (match_scratch:SI 0 "=r"))]
13089 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090 && ix86_match_ccmode (insn, CCGOCmode)
13091 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093 [(set_attr "type" "ishift")
13094 (set_attr "length" "2")])
13096 (define_insn "*lshrsi3_cmp_one_bit_zext"
13097 [(set (reg FLAGS_REG)
13099 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13100 (match_operand:QI 2 "const1_operand" ""))
13102 (set (match_operand:DI 0 "register_operand" "=r")
13103 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13106 && ix86_match_ccmode (insn, CCGOCmode)
13107 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13109 [(set_attr "type" "ishift")
13110 (set_attr "length" "2")])
13112 ;; This pattern can't accept a variable shift count, since shifts by
13113 ;; zero don't affect the flags. We assume that shifts by constant
13114 ;; zero are optimized away.
13115 (define_insn "*lshrsi3_cmp"
13116 [(set (reg FLAGS_REG)
13118 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13121 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13122 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13123 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13124 && ix86_match_ccmode (insn, CCGOCmode)
13125 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13126 "shr{l}\t{%2, %0|%0, %2}"
13127 [(set_attr "type" "ishift")
13128 (set_attr "mode" "SI")])
13130 (define_insn "*lshrsi3_cconly"
13131 [(set (reg FLAGS_REG)
13133 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13134 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13136 (clobber (match_scratch:SI 0 "=r"))]
13137 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138 && ix86_match_ccmode (insn, CCGOCmode)
13139 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140 "shr{l}\t{%2, %0|%0, %2}"
13141 [(set_attr "type" "ishift")
13142 (set_attr "mode" "SI")])
13144 (define_insn "*lshrsi3_cmp_zext"
13145 [(set (reg FLAGS_REG)
13147 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13148 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13150 (set (match_operand:DI 0 "register_operand" "=r")
13151 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13153 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13154 && ix86_match_ccmode (insn, CCGOCmode)
13155 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13156 "shr{l}\t{%2, %k0|%k0, %2}"
13157 [(set_attr "type" "ishift")
13158 (set_attr "mode" "SI")])
13160 (define_expand "lshrhi3"
13161 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13162 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13163 (match_operand:QI 2 "nonmemory_operand" "")))]
13164 "TARGET_HIMODE_MATH"
13165 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13167 (define_insn "*lshrhi3_1_one_bit"
13168 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13169 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13170 (match_operand:QI 2 "const1_operand" "")))
13171 (clobber (reg:CC FLAGS_REG))]
13172 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13173 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13175 [(set_attr "type" "ishift")
13176 (set (attr "length")
13177 (if_then_else (match_operand 0 "register_operand" "")
13179 (const_string "*")))])
13181 (define_insn "*lshrhi3_1"
13182 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13183 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13184 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13185 (clobber (reg:CC FLAGS_REG))]
13186 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13188 shr{w}\t{%2, %0|%0, %2}
13189 shr{w}\t{%b2, %0|%0, %b2}"
13190 [(set_attr "type" "ishift")
13191 (set_attr "mode" "HI")])
13193 ;; This pattern can't accept a variable shift count, since shifts by
13194 ;; zero don't affect the flags. We assume that shifts by constant
13195 ;; zero are optimized away.
13196 (define_insn "*lshrhi3_one_bit_cmp"
13197 [(set (reg FLAGS_REG)
13199 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13200 (match_operand:QI 2 "const1_operand" ""))
13202 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13203 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13204 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13205 && ix86_match_ccmode (insn, CCGOCmode)
13206 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13208 [(set_attr "type" "ishift")
13209 (set (attr "length")
13210 (if_then_else (match_operand:SI 0 "register_operand" "")
13212 (const_string "*")))])
13214 (define_insn "*lshrhi3_one_bit_cconly"
13215 [(set (reg FLAGS_REG)
13217 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13218 (match_operand:QI 2 "const1_operand" ""))
13220 (clobber (match_scratch:HI 0 "=r"))]
13221 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13222 && ix86_match_ccmode (insn, CCGOCmode)
13223 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13225 [(set_attr "type" "ishift")
13226 (set_attr "length" "2")])
13228 ;; This pattern can't accept a variable shift count, since shifts by
13229 ;; zero don't affect the flags. We assume that shifts by constant
13230 ;; zero are optimized away.
13231 (define_insn "*lshrhi3_cmp"
13232 [(set (reg FLAGS_REG)
13234 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13237 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13238 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13239 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13240 && ix86_match_ccmode (insn, CCGOCmode)
13241 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13242 "shr{w}\t{%2, %0|%0, %2}"
13243 [(set_attr "type" "ishift")
13244 (set_attr "mode" "HI")])
13246 (define_insn "*lshrhi3_cconly"
13247 [(set (reg FLAGS_REG)
13249 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13250 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13252 (clobber (match_scratch:HI 0 "=r"))]
13253 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13254 && ix86_match_ccmode (insn, CCGOCmode)
13255 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13256 "shr{w}\t{%2, %0|%0, %2}"
13257 [(set_attr "type" "ishift")
13258 (set_attr "mode" "HI")])
13260 (define_expand "lshrqi3"
13261 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13262 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13263 (match_operand:QI 2 "nonmemory_operand" "")))]
13264 "TARGET_QIMODE_MATH"
13265 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13267 (define_insn "*lshrqi3_1_one_bit"
13268 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13269 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13270 (match_operand:QI 2 "const1_operand" "")))
13271 (clobber (reg:CC FLAGS_REG))]
13272 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13273 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13275 [(set_attr "type" "ishift")
13276 (set (attr "length")
13277 (if_then_else (match_operand 0 "register_operand" "")
13279 (const_string "*")))])
13281 (define_insn "*lshrqi3_1_one_bit_slp"
13282 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13283 (lshiftrt:QI (match_dup 0)
13284 (match_operand:QI 1 "const1_operand" "")))
13285 (clobber (reg:CC FLAGS_REG))]
13286 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13289 [(set_attr "type" "ishift1")
13290 (set (attr "length")
13291 (if_then_else (match_operand 0 "register_operand" "")
13293 (const_string "*")))])
13295 (define_insn "*lshrqi3_1"
13296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13297 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13298 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13299 (clobber (reg:CC FLAGS_REG))]
13300 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13302 shr{b}\t{%2, %0|%0, %2}
13303 shr{b}\t{%b2, %0|%0, %b2}"
13304 [(set_attr "type" "ishift")
13305 (set_attr "mode" "QI")])
13307 (define_insn "*lshrqi3_1_slp"
13308 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13309 (lshiftrt:QI (match_dup 0)
13310 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13311 (clobber (reg:CC FLAGS_REG))]
13312 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13313 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13315 shr{b}\t{%1, %0|%0, %1}
13316 shr{b}\t{%b1, %0|%0, %b1}"
13317 [(set_attr "type" "ishift1")
13318 (set_attr "mode" "QI")])
13320 ;; This pattern can't accept a variable shift count, since shifts by
13321 ;; zero don't affect the flags. We assume that shifts by constant
13322 ;; zero are optimized away.
13323 (define_insn "*lshrqi2_one_bit_cmp"
13324 [(set (reg FLAGS_REG)
13326 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13327 (match_operand:QI 2 "const1_operand" ""))
13329 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13330 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13331 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13332 && ix86_match_ccmode (insn, CCGOCmode)
13333 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13335 [(set_attr "type" "ishift")
13336 (set (attr "length")
13337 (if_then_else (match_operand:SI 0 "register_operand" "")
13339 (const_string "*")))])
13341 (define_insn "*lshrqi2_one_bit_cconly"
13342 [(set (reg FLAGS_REG)
13344 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13345 (match_operand:QI 2 "const1_operand" ""))
13347 (clobber (match_scratch:QI 0 "=q"))]
13348 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13349 && ix86_match_ccmode (insn, CCGOCmode)
13350 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13352 [(set_attr "type" "ishift")
13353 (set_attr "length" "2")])
13355 ;; This pattern can't accept a variable shift count, since shifts by
13356 ;; zero don't affect the flags. We assume that shifts by constant
13357 ;; zero are optimized away.
13358 (define_insn "*lshrqi2_cmp"
13359 [(set (reg FLAGS_REG)
13361 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13364 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13365 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13366 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13367 && ix86_match_ccmode (insn, CCGOCmode)
13368 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13369 "shr{b}\t{%2, %0|%0, %2}"
13370 [(set_attr "type" "ishift")
13371 (set_attr "mode" "QI")])
13373 (define_insn "*lshrqi2_cconly"
13374 [(set (reg FLAGS_REG)
13376 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13377 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13379 (clobber (match_scratch:QI 0 "=q"))]
13380 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13381 && ix86_match_ccmode (insn, CCGOCmode)
13382 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13383 "shr{b}\t{%2, %0|%0, %2}"
13384 [(set_attr "type" "ishift")
13385 (set_attr "mode" "QI")])
13387 ;; Rotate instructions
13389 (define_expand "rotldi3"
13390 [(set (match_operand:DI 0 "shiftdi_operand" "")
13391 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13392 (match_operand:QI 2 "nonmemory_operand" "")))]
13397 ix86_expand_binary_operator (ROTATE, DImode, operands);
13400 if (!const_1_to_31_operand (operands[2], VOIDmode))
13402 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13406 ;; Implement rotation using two double-precision shift instructions
13407 ;; and a scratch register.
13408 (define_insn_and_split "ix86_rotldi3"
13409 [(set (match_operand:DI 0 "register_operand" "=r")
13410 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13411 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13412 (clobber (reg:CC FLAGS_REG))
13413 (clobber (match_scratch:SI 3 "=&r"))]
13416 "&& reload_completed"
13417 [(set (match_dup 3) (match_dup 4))
13419 [(set (match_dup 4)
13420 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13421 (lshiftrt:SI (match_dup 5)
13422 (minus:QI (const_int 32) (match_dup 2)))))
13423 (clobber (reg:CC FLAGS_REG))])
13425 [(set (match_dup 5)
13426 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13427 (lshiftrt:SI (match_dup 3)
13428 (minus:QI (const_int 32) (match_dup 2)))))
13429 (clobber (reg:CC FLAGS_REG))])]
13430 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13432 (define_insn "*rotlsi3_1_one_bit_rex64"
13433 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13434 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13435 (match_operand:QI 2 "const1_operand" "")))
13436 (clobber (reg:CC FLAGS_REG))]
13438 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13439 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13441 [(set_attr "type" "rotate")
13442 (set (attr "length")
13443 (if_then_else (match_operand:DI 0 "register_operand" "")
13445 (const_string "*")))])
13447 (define_insn "*rotldi3_1_rex64"
13448 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13449 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13450 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13451 (clobber (reg:CC FLAGS_REG))]
13452 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13454 rol{q}\t{%2, %0|%0, %2}
13455 rol{q}\t{%b2, %0|%0, %b2}"
13456 [(set_attr "type" "rotate")
13457 (set_attr "mode" "DI")])
13459 (define_expand "rotlsi3"
13460 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13461 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13462 (match_operand:QI 2 "nonmemory_operand" "")))]
13464 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13466 (define_insn "*rotlsi3_1_one_bit"
13467 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13468 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13469 (match_operand:QI 2 "const1_operand" "")))
13470 (clobber (reg:CC FLAGS_REG))]
13471 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474 [(set_attr "type" "rotate")
13475 (set (attr "length")
13476 (if_then_else (match_operand:SI 0 "register_operand" "")
13478 (const_string "*")))])
13480 (define_insn "*rotlsi3_1_one_bit_zext"
13481 [(set (match_operand:DI 0 "register_operand" "=r")
13483 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13484 (match_operand:QI 2 "const1_operand" ""))))
13485 (clobber (reg:CC FLAGS_REG))]
13487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13488 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13490 [(set_attr "type" "rotate")
13491 (set_attr "length" "2")])
13493 (define_insn "*rotlsi3_1"
13494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13495 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13496 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13497 (clobber (reg:CC FLAGS_REG))]
13498 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13500 rol{l}\t{%2, %0|%0, %2}
13501 rol{l}\t{%b2, %0|%0, %b2}"
13502 [(set_attr "type" "rotate")
13503 (set_attr "mode" "SI")])
13505 (define_insn "*rotlsi3_1_zext"
13506 [(set (match_operand:DI 0 "register_operand" "=r,r")
13508 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13509 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13510 (clobber (reg:CC FLAGS_REG))]
13511 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13513 rol{l}\t{%2, %k0|%k0, %2}
13514 rol{l}\t{%b2, %k0|%k0, %b2}"
13515 [(set_attr "type" "rotate")
13516 (set_attr "mode" "SI")])
13518 (define_expand "rotlhi3"
13519 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13520 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13521 (match_operand:QI 2 "nonmemory_operand" "")))]
13522 "TARGET_HIMODE_MATH"
13523 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13525 (define_insn "*rotlhi3_1_one_bit"
13526 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13527 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13528 (match_operand:QI 2 "const1_operand" "")))
13529 (clobber (reg:CC FLAGS_REG))]
13530 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13531 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13533 [(set_attr "type" "rotate")
13534 (set (attr "length")
13535 (if_then_else (match_operand 0 "register_operand" "")
13537 (const_string "*")))])
13539 (define_insn "*rotlhi3_1"
13540 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13541 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13542 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13543 (clobber (reg:CC FLAGS_REG))]
13544 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13546 rol{w}\t{%2, %0|%0, %2}
13547 rol{w}\t{%b2, %0|%0, %b2}"
13548 [(set_attr "type" "rotate")
13549 (set_attr "mode" "HI")])
13552 [(set (match_operand:HI 0 "register_operand" "")
13553 (rotate:HI (match_dup 0) (const_int 8)))
13554 (clobber (reg:CC FLAGS_REG))]
13556 [(parallel [(set (strict_low_part (match_dup 0))
13557 (bswap:HI (match_dup 0)))
13558 (clobber (reg:CC FLAGS_REG))])]
13561 (define_expand "rotlqi3"
13562 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13563 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13564 (match_operand:QI 2 "nonmemory_operand" "")))]
13565 "TARGET_QIMODE_MATH"
13566 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13568 (define_insn "*rotlqi3_1_one_bit_slp"
13569 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13570 (rotate:QI (match_dup 0)
13571 (match_operand:QI 1 "const1_operand" "")))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13574 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13576 [(set_attr "type" "rotate1")
13577 (set (attr "length")
13578 (if_then_else (match_operand 0 "register_operand" "")
13580 (const_string "*")))])
13582 (define_insn "*rotlqi3_1_one_bit"
13583 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13584 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13585 (match_operand:QI 2 "const1_operand" "")))
13586 (clobber (reg:CC FLAGS_REG))]
13587 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13588 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13590 [(set_attr "type" "rotate")
13591 (set (attr "length")
13592 (if_then_else (match_operand 0 "register_operand" "")
13594 (const_string "*")))])
13596 (define_insn "*rotlqi3_1_slp"
13597 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13598 (rotate:QI (match_dup 0)
13599 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13600 (clobber (reg:CC FLAGS_REG))]
13601 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13602 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13604 rol{b}\t{%1, %0|%0, %1}
13605 rol{b}\t{%b1, %0|%0, %b1}"
13606 [(set_attr "type" "rotate1")
13607 (set_attr "mode" "QI")])
13609 (define_insn "*rotlqi3_1"
13610 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13611 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13612 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13613 (clobber (reg:CC FLAGS_REG))]
13614 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13616 rol{b}\t{%2, %0|%0, %2}
13617 rol{b}\t{%b2, %0|%0, %b2}"
13618 [(set_attr "type" "rotate")
13619 (set_attr "mode" "QI")])
13621 (define_expand "rotrdi3"
13622 [(set (match_operand:DI 0 "shiftdi_operand" "")
13623 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13624 (match_operand:QI 2 "nonmemory_operand" "")))]
13629 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13632 if (!const_1_to_31_operand (operands[2], VOIDmode))
13634 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13638 ;; Implement rotation using two double-precision shift instructions
13639 ;; and a scratch register.
13640 (define_insn_and_split "ix86_rotrdi3"
13641 [(set (match_operand:DI 0 "register_operand" "=r")
13642 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13643 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13644 (clobber (reg:CC FLAGS_REG))
13645 (clobber (match_scratch:SI 3 "=&r"))]
13648 "&& reload_completed"
13649 [(set (match_dup 3) (match_dup 4))
13651 [(set (match_dup 4)
13652 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13653 (ashift:SI (match_dup 5)
13654 (minus:QI (const_int 32) (match_dup 2)))))
13655 (clobber (reg:CC FLAGS_REG))])
13657 [(set (match_dup 5)
13658 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13659 (ashift:SI (match_dup 3)
13660 (minus:QI (const_int 32) (match_dup 2)))))
13661 (clobber (reg:CC FLAGS_REG))])]
13662 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13664 (define_insn "*rotrdi3_1_one_bit_rex64"
13665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13666 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13667 (match_operand:QI 2 "const1_operand" "")))
13668 (clobber (reg:CC FLAGS_REG))]
13670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13671 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13673 [(set_attr "type" "rotate")
13674 (set (attr "length")
13675 (if_then_else (match_operand:DI 0 "register_operand" "")
13677 (const_string "*")))])
13679 (define_insn "*rotrdi3_1_rex64"
13680 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13681 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13682 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13683 (clobber (reg:CC FLAGS_REG))]
13684 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13686 ror{q}\t{%2, %0|%0, %2}
13687 ror{q}\t{%b2, %0|%0, %b2}"
13688 [(set_attr "type" "rotate")
13689 (set_attr "mode" "DI")])
13691 (define_expand "rotrsi3"
13692 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13693 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13694 (match_operand:QI 2 "nonmemory_operand" "")))]
13696 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13698 (define_insn "*rotrsi3_1_one_bit"
13699 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13700 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13701 (match_operand:QI 2 "const1_operand" "")))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706 [(set_attr "type" "rotate")
13707 (set (attr "length")
13708 (if_then_else (match_operand:SI 0 "register_operand" "")
13710 (const_string "*")))])
13712 (define_insn "*rotrsi3_1_one_bit_zext"
13713 [(set (match_operand:DI 0 "register_operand" "=r")
13715 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13716 (match_operand:QI 2 "const1_operand" ""))))
13717 (clobber (reg:CC FLAGS_REG))]
13719 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13722 [(set_attr "type" "rotate")
13723 (set (attr "length")
13724 (if_then_else (match_operand:SI 0 "register_operand" "")
13726 (const_string "*")))])
13728 (define_insn "*rotrsi3_1"
13729 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13730 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13732 (clobber (reg:CC FLAGS_REG))]
13733 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13735 ror{l}\t{%2, %0|%0, %2}
13736 ror{l}\t{%b2, %0|%0, %b2}"
13737 [(set_attr "type" "rotate")
13738 (set_attr "mode" "SI")])
13740 (define_insn "*rotrsi3_1_zext"
13741 [(set (match_operand:DI 0 "register_operand" "=r,r")
13743 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13744 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13745 (clobber (reg:CC FLAGS_REG))]
13746 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13748 ror{l}\t{%2, %k0|%k0, %2}
13749 ror{l}\t{%b2, %k0|%k0, %b2}"
13750 [(set_attr "type" "rotate")
13751 (set_attr "mode" "SI")])
13753 (define_expand "rotrhi3"
13754 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13755 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13756 (match_operand:QI 2 "nonmemory_operand" "")))]
13757 "TARGET_HIMODE_MATH"
13758 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13760 (define_insn "*rotrhi3_one_bit"
13761 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13762 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13763 (match_operand:QI 2 "const1_operand" "")))
13764 (clobber (reg:CC FLAGS_REG))]
13765 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13766 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13768 [(set_attr "type" "rotate")
13769 (set (attr "length")
13770 (if_then_else (match_operand 0 "register_operand" "")
13772 (const_string "*")))])
13774 (define_insn "*rotrhi3_1"
13775 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13776 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13777 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13778 (clobber (reg:CC FLAGS_REG))]
13779 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13781 ror{w}\t{%2, %0|%0, %2}
13782 ror{w}\t{%b2, %0|%0, %b2}"
13783 [(set_attr "type" "rotate")
13784 (set_attr "mode" "HI")])
13787 [(set (match_operand:HI 0 "register_operand" "")
13788 (rotatert:HI (match_dup 0) (const_int 8)))
13789 (clobber (reg:CC FLAGS_REG))]
13791 [(parallel [(set (strict_low_part (match_dup 0))
13792 (bswap:HI (match_dup 0)))
13793 (clobber (reg:CC FLAGS_REG))])]
13796 (define_expand "rotrqi3"
13797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13798 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13799 (match_operand:QI 2 "nonmemory_operand" "")))]
13800 "TARGET_QIMODE_MATH"
13801 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13803 (define_insn "*rotrqi3_1_one_bit"
13804 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13805 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13806 (match_operand:QI 2 "const1_operand" "")))
13807 (clobber (reg:CC FLAGS_REG))]
13808 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13809 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13811 [(set_attr "type" "rotate")
13812 (set (attr "length")
13813 (if_then_else (match_operand 0 "register_operand" "")
13815 (const_string "*")))])
13817 (define_insn "*rotrqi3_1_one_bit_slp"
13818 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13819 (rotatert:QI (match_dup 0)
13820 (match_operand:QI 1 "const1_operand" "")))
13821 (clobber (reg:CC FLAGS_REG))]
13822 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13825 [(set_attr "type" "rotate1")
13826 (set (attr "length")
13827 (if_then_else (match_operand 0 "register_operand" "")
13829 (const_string "*")))])
13831 (define_insn "*rotrqi3_1"
13832 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13833 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13834 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13835 (clobber (reg:CC FLAGS_REG))]
13836 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13838 ror{b}\t{%2, %0|%0, %2}
13839 ror{b}\t{%b2, %0|%0, %b2}"
13840 [(set_attr "type" "rotate")
13841 (set_attr "mode" "QI")])
13843 (define_insn "*rotrqi3_1_slp"
13844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13845 (rotatert:QI (match_dup 0)
13846 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13847 (clobber (reg:CC FLAGS_REG))]
13848 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13851 ror{b}\t{%1, %0|%0, %1}
13852 ror{b}\t{%b1, %0|%0, %b1}"
13853 [(set_attr "type" "rotate1")
13854 (set_attr "mode" "QI")])
13856 ;; Bit set / bit test instructions
13858 (define_expand "extv"
13859 [(set (match_operand:SI 0 "register_operand" "")
13860 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13861 (match_operand:SI 2 "const8_operand" "")
13862 (match_operand:SI 3 "const8_operand" "")))]
13865 /* Handle extractions from %ah et al. */
13866 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13869 /* From mips.md: extract_bit_field doesn't verify that our source
13870 matches the predicate, so check it again here. */
13871 if (! ext_register_operand (operands[1], VOIDmode))
13875 (define_expand "extzv"
13876 [(set (match_operand:SI 0 "register_operand" "")
13877 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13878 (match_operand:SI 2 "const8_operand" "")
13879 (match_operand:SI 3 "const8_operand" "")))]
13882 /* Handle extractions from %ah et al. */
13883 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13886 /* From mips.md: extract_bit_field doesn't verify that our source
13887 matches the predicate, so check it again here. */
13888 if (! ext_register_operand (operands[1], VOIDmode))
13892 (define_expand "insv"
13893 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13894 (match_operand 1 "const8_operand" "")
13895 (match_operand 2 "const8_operand" ""))
13896 (match_operand 3 "register_operand" ""))]
13899 /* Handle insertions to %ah et al. */
13900 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13903 /* From mips.md: insert_bit_field doesn't verify that our source
13904 matches the predicate, so check it again here. */
13905 if (! ext_register_operand (operands[0], VOIDmode))
13909 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13911 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13916 ;; %%% bts, btr, btc, bt.
13917 ;; In general these instructions are *slow* when applied to memory,
13918 ;; since they enforce atomic operation. When applied to registers,
13919 ;; it depends on the cpu implementation. They're never faster than
13920 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13921 ;; no point. But in 64-bit, we can't hold the relevant immediates
13922 ;; within the instruction itself, so operating on bits in the high
13923 ;; 32-bits of a register becomes easier.
13925 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13926 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13927 ;; negdf respectively, so they can never be disabled entirely.
13929 (define_insn "*btsq"
13930 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13932 (match_operand:DI 1 "const_0_to_63_operand" ""))
13934 (clobber (reg:CC FLAGS_REG))]
13935 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13936 "bts{q}\t{%1, %0|%0, %1}"
13937 [(set_attr "type" "alu1")])
13939 (define_insn "*btrq"
13940 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13942 (match_operand:DI 1 "const_0_to_63_operand" ""))
13944 (clobber (reg:CC FLAGS_REG))]
13945 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13946 "btr{q}\t{%1, %0|%0, %1}"
13947 [(set_attr "type" "alu1")])
13949 (define_insn "*btcq"
13950 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13952 (match_operand:DI 1 "const_0_to_63_operand" ""))
13953 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13954 (clobber (reg:CC FLAGS_REG))]
13955 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13956 "btc{q}\t{%1, %0|%0, %1}"
13957 [(set_attr "type" "alu1")])
13959 ;; Allow Nocona to avoid these instructions if a register is available.
13962 [(match_scratch:DI 2 "r")
13963 (parallel [(set (zero_extract:DI
13964 (match_operand:DI 0 "register_operand" "")
13966 (match_operand:DI 1 "const_0_to_63_operand" ""))
13968 (clobber (reg:CC FLAGS_REG))])]
13969 "TARGET_64BIT && !TARGET_USE_BT"
13972 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13975 if (HOST_BITS_PER_WIDE_INT >= 64)
13976 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13977 else if (i < HOST_BITS_PER_WIDE_INT)
13978 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13980 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13982 op1 = immed_double_const (lo, hi, DImode);
13985 emit_move_insn (operands[2], op1);
13989 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13994 [(match_scratch:DI 2 "r")
13995 (parallel [(set (zero_extract:DI
13996 (match_operand:DI 0 "register_operand" "")
13998 (match_operand:DI 1 "const_0_to_63_operand" ""))
14000 (clobber (reg:CC FLAGS_REG))])]
14001 "TARGET_64BIT && !TARGET_USE_BT"
14004 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14007 if (HOST_BITS_PER_WIDE_INT >= 64)
14008 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14009 else if (i < HOST_BITS_PER_WIDE_INT)
14010 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14012 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14014 op1 = immed_double_const (~lo, ~hi, DImode);
14017 emit_move_insn (operands[2], op1);
14021 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14026 [(match_scratch:DI 2 "r")
14027 (parallel [(set (zero_extract:DI
14028 (match_operand:DI 0 "register_operand" "")
14030 (match_operand:DI 1 "const_0_to_63_operand" ""))
14031 (not:DI (zero_extract:DI
14032 (match_dup 0) (const_int 1) (match_dup 1))))
14033 (clobber (reg:CC FLAGS_REG))])]
14034 "TARGET_64BIT && !TARGET_USE_BT"
14037 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14040 if (HOST_BITS_PER_WIDE_INT >= 64)
14041 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14042 else if (i < HOST_BITS_PER_WIDE_INT)
14043 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14045 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14047 op1 = immed_double_const (lo, hi, DImode);
14050 emit_move_insn (operands[2], op1);
14054 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14058 (define_insn "*btdi_rex64"
14059 [(set (reg:CCC FLAGS_REG)
14062 (match_operand:DI 0 "register_operand" "r")
14064 (match_operand:DI 1 "nonmemory_operand" "rN"))
14066 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14067 "bt{q}\t{%1, %0|%0, %1}"
14068 [(set_attr "type" "alu1")])
14070 (define_insn "*btsi"
14071 [(set (reg:CCC FLAGS_REG)
14074 (match_operand:SI 0 "register_operand" "r")
14076 (match_operand:SI 1 "nonmemory_operand" "rN"))
14078 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14079 "bt{l}\t{%1, %0|%0, %1}"
14080 [(set_attr "type" "alu1")])
14082 ;; Store-flag instructions.
14084 ;; For all sCOND expanders, also expand the compare or test insn that
14085 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14087 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14088 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14089 ;; way, which can later delete the movzx if only QImode is needed.
14091 (define_expand "s<code>"
14092 [(set (match_operand:QI 0 "register_operand" "")
14093 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14095 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14097 (define_expand "s<code>"
14098 [(set (match_operand:QI 0 "register_operand" "")
14099 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14100 "TARGET_80387 || TARGET_SSE"
14101 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14103 (define_insn "*setcc_1"
14104 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14105 (match_operator:QI 1 "ix86_comparison_operator"
14106 [(reg FLAGS_REG) (const_int 0)]))]
14109 [(set_attr "type" "setcc")
14110 (set_attr "mode" "QI")])
14112 (define_insn "*setcc_2"
14113 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14114 (match_operator:QI 1 "ix86_comparison_operator"
14115 [(reg FLAGS_REG) (const_int 0)]))]
14118 [(set_attr "type" "setcc")
14119 (set_attr "mode" "QI")])
14121 ;; In general it is not safe to assume too much about CCmode registers,
14122 ;; so simplify-rtx stops when it sees a second one. Under certain
14123 ;; conditions this is safe on x86, so help combine not create
14130 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14131 (ne:QI (match_operator 1 "ix86_comparison_operator"
14132 [(reg FLAGS_REG) (const_int 0)])
14135 [(set (match_dup 0) (match_dup 1))]
14137 PUT_MODE (operands[1], QImode);
14141 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14142 (ne:QI (match_operator 1 "ix86_comparison_operator"
14143 [(reg FLAGS_REG) (const_int 0)])
14146 [(set (match_dup 0) (match_dup 1))]
14148 PUT_MODE (operands[1], QImode);
14152 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14153 (eq:QI (match_operator 1 "ix86_comparison_operator"
14154 [(reg FLAGS_REG) (const_int 0)])
14157 [(set (match_dup 0) (match_dup 1))]
14159 rtx new_op1 = copy_rtx (operands[1]);
14160 operands[1] = new_op1;
14161 PUT_MODE (new_op1, QImode);
14162 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14163 GET_MODE (XEXP (new_op1, 0))));
14165 /* Make sure that (a) the CCmode we have for the flags is strong
14166 enough for the reversed compare or (b) we have a valid FP compare. */
14167 if (! ix86_comparison_operator (new_op1, VOIDmode))
14172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14173 (eq:QI (match_operator 1 "ix86_comparison_operator"
14174 [(reg FLAGS_REG) (const_int 0)])
14177 [(set (match_dup 0) (match_dup 1))]
14179 rtx new_op1 = copy_rtx (operands[1]);
14180 operands[1] = new_op1;
14181 PUT_MODE (new_op1, QImode);
14182 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14183 GET_MODE (XEXP (new_op1, 0))));
14185 /* Make sure that (a) the CCmode we have for the flags is strong
14186 enough for the reversed compare or (b) we have a valid FP compare. */
14187 if (! ix86_comparison_operator (new_op1, VOIDmode))
14191 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14192 ;; subsequent logical operations are used to imitate conditional moves.
14193 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14196 (define_insn "*avx_setcc<mode>"
14197 [(set (match_operand:MODEF 0 "register_operand" "=x")
14198 (match_operator:MODEF 1 "avx_comparison_float_operator"
14199 [(match_operand:MODEF 2 "register_operand" "x")
14200 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14202 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14203 [(set_attr "type" "ssecmp")
14204 (set_attr "prefix" "vex")
14205 (set_attr "mode" "<MODE>")])
14207 (define_insn "*sse_setcc<mode>"
14208 [(set (match_operand:MODEF 0 "register_operand" "=x")
14209 (match_operator:MODEF 1 "sse_comparison_operator"
14210 [(match_operand:MODEF 2 "register_operand" "0")
14211 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14212 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14213 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14214 [(set_attr "type" "ssecmp")
14215 (set_attr "mode" "<MODE>")])
14217 (define_insn "*sse5_setcc<mode>"
14218 [(set (match_operand:MODEF 0 "register_operand" "=x")
14219 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14220 [(match_operand:MODEF 2 "register_operand" "x")
14221 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14223 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14224 [(set_attr "type" "sse4arg")
14225 (set_attr "mode" "<MODE>")])
14228 ;; Basic conditional jump instructions.
14229 ;; We ignore the overflow flag for signed branch instructions.
14231 ;; For all bCOND expanders, also expand the compare or test insn that
14232 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14234 (define_expand "b<code>"
14236 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14238 (label_ref (match_operand 0 ""))
14241 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14243 (define_expand "b<code>"
14245 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14247 (label_ref (match_operand 0 ""))
14249 "TARGET_80387 || TARGET_SSE_MATH"
14250 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14252 (define_insn "*jcc_1"
14254 (if_then_else (match_operator 1 "ix86_comparison_operator"
14255 [(reg FLAGS_REG) (const_int 0)])
14256 (label_ref (match_operand 0 "" ""))
14260 [(set_attr "type" "ibr")
14261 (set_attr "modrm" "0")
14262 (set (attr "length")
14263 (if_then_else (and (ge (minus (match_dup 0) (pc))
14265 (lt (minus (match_dup 0) (pc))
14270 (define_insn "*jcc_2"
14272 (if_then_else (match_operator 1 "ix86_comparison_operator"
14273 [(reg FLAGS_REG) (const_int 0)])
14275 (label_ref (match_operand 0 "" ""))))]
14278 [(set_attr "type" "ibr")
14279 (set_attr "modrm" "0")
14280 (set (attr "length")
14281 (if_then_else (and (ge (minus (match_dup 0) (pc))
14283 (lt (minus (match_dup 0) (pc))
14288 ;; In general it is not safe to assume too much about CCmode registers,
14289 ;; so simplify-rtx stops when it sees a second one. Under certain
14290 ;; conditions this is safe on x86, so help combine not create
14298 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14299 [(reg FLAGS_REG) (const_int 0)])
14301 (label_ref (match_operand 1 "" ""))
14305 (if_then_else (match_dup 0)
14306 (label_ref (match_dup 1))
14309 PUT_MODE (operands[0], VOIDmode);
14314 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14315 [(reg FLAGS_REG) (const_int 0)])
14317 (label_ref (match_operand 1 "" ""))
14321 (if_then_else (match_dup 0)
14322 (label_ref (match_dup 1))
14325 rtx new_op0 = copy_rtx (operands[0]);
14326 operands[0] = new_op0;
14327 PUT_MODE (new_op0, VOIDmode);
14328 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14329 GET_MODE (XEXP (new_op0, 0))));
14331 /* Make sure that (a) the CCmode we have for the flags is strong
14332 enough for the reversed compare or (b) we have a valid FP compare. */
14333 if (! ix86_comparison_operator (new_op0, VOIDmode))
14337 ;; zero_extend in SImode is correct, since this is what combine pass
14338 ;; generates from shift insn with QImode operand. Actually, the mode of
14339 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14340 ;; appropriate modulo of the bit offset value.
14342 (define_insn_and_split "*jcc_btdi_rex64"
14344 (if_then_else (match_operator 0 "bt_comparison_operator"
14346 (match_operand:DI 1 "register_operand" "r")
14349 (match_operand:QI 2 "register_operand" "r")))
14351 (label_ref (match_operand 3 "" ""))
14353 (clobber (reg:CC FLAGS_REG))]
14354 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14357 [(set (reg:CCC FLAGS_REG)
14365 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14366 (label_ref (match_dup 3))
14369 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14371 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14374 ;; avoid useless masking of bit offset operand
14375 (define_insn_and_split "*jcc_btdi_mask_rex64"
14377 (if_then_else (match_operator 0 "bt_comparison_operator"
14379 (match_operand:DI 1 "register_operand" "r")
14382 (match_operand:SI 2 "register_operand" "r")
14383 (match_operand:SI 3 "const_int_operand" "n")))])
14384 (label_ref (match_operand 4 "" ""))
14386 (clobber (reg:CC FLAGS_REG))]
14387 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14388 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14391 [(set (reg:CCC FLAGS_REG)
14399 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14400 (label_ref (match_dup 4))
14403 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14405 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14408 (define_insn_and_split "*jcc_btsi"
14410 (if_then_else (match_operator 0 "bt_comparison_operator"
14412 (match_operand:SI 1 "register_operand" "r")
14415 (match_operand:QI 2 "register_operand" "r")))
14417 (label_ref (match_operand 3 "" ""))
14419 (clobber (reg:CC FLAGS_REG))]
14420 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14423 [(set (reg:CCC FLAGS_REG)
14431 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14432 (label_ref (match_dup 3))
14435 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14437 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14440 ;; avoid useless masking of bit offset operand
14441 (define_insn_and_split "*jcc_btsi_mask"
14443 (if_then_else (match_operator 0 "bt_comparison_operator"
14445 (match_operand:SI 1 "register_operand" "r")
14448 (match_operand:SI 2 "register_operand" "r")
14449 (match_operand:SI 3 "const_int_operand" "n")))])
14450 (label_ref (match_operand 4 "" ""))
14452 (clobber (reg:CC FLAGS_REG))]
14453 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14454 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14457 [(set (reg:CCC FLAGS_REG)
14465 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14466 (label_ref (match_dup 4))
14468 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14470 (define_insn_and_split "*jcc_btsi_1"
14472 (if_then_else (match_operator 0 "bt_comparison_operator"
14475 (match_operand:SI 1 "register_operand" "r")
14476 (match_operand:QI 2 "register_operand" "r"))
14479 (label_ref (match_operand 3 "" ""))
14481 (clobber (reg:CC FLAGS_REG))]
14482 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14485 [(set (reg:CCC FLAGS_REG)
14493 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14494 (label_ref (match_dup 3))
14497 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14499 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14502 ;; avoid useless masking of bit offset operand
14503 (define_insn_and_split "*jcc_btsi_mask_1"
14506 (match_operator 0 "bt_comparison_operator"
14509 (match_operand:SI 1 "register_operand" "r")
14512 (match_operand:SI 2 "register_operand" "r")
14513 (match_operand:SI 3 "const_int_operand" "n")) 0))
14516 (label_ref (match_operand 4 "" ""))
14518 (clobber (reg:CC FLAGS_REG))]
14519 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14520 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14523 [(set (reg:CCC FLAGS_REG)
14531 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14532 (label_ref (match_dup 4))
14534 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14536 ;; Define combination compare-and-branch fp compare instructions to use
14537 ;; during early optimization. Splitting the operation apart early makes
14538 ;; for bad code when we want to reverse the operation.
14540 (define_insn "*fp_jcc_1_mixed"
14542 (if_then_else (match_operator 0 "comparison_operator"
14543 [(match_operand 1 "register_operand" "f,x")
14544 (match_operand 2 "nonimmediate_operand" "f,xm")])
14545 (label_ref (match_operand 3 "" ""))
14547 (clobber (reg:CCFP FPSR_REG))
14548 (clobber (reg:CCFP FLAGS_REG))]
14549 "TARGET_MIX_SSE_I387
14550 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14555 (define_insn "*fp_jcc_1_sse"
14557 (if_then_else (match_operator 0 "comparison_operator"
14558 [(match_operand 1 "register_operand" "x")
14559 (match_operand 2 "nonimmediate_operand" "xm")])
14560 (label_ref (match_operand 3 "" ""))
14562 (clobber (reg:CCFP FPSR_REG))
14563 (clobber (reg:CCFP FLAGS_REG))]
14565 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14566 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14570 (define_insn "*fp_jcc_1_387"
14572 (if_then_else (match_operator 0 "comparison_operator"
14573 [(match_operand 1 "register_operand" "f")
14574 (match_operand 2 "register_operand" "f")])
14575 (label_ref (match_operand 3 "" ""))
14577 (clobber (reg:CCFP FPSR_REG))
14578 (clobber (reg:CCFP FLAGS_REG))]
14579 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14581 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14585 (define_insn "*fp_jcc_2_mixed"
14587 (if_then_else (match_operator 0 "comparison_operator"
14588 [(match_operand 1 "register_operand" "f,x")
14589 (match_operand 2 "nonimmediate_operand" "f,xm")])
14591 (label_ref (match_operand 3 "" ""))))
14592 (clobber (reg:CCFP FPSR_REG))
14593 (clobber (reg:CCFP FLAGS_REG))]
14594 "TARGET_MIX_SSE_I387
14595 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14600 (define_insn "*fp_jcc_2_sse"
14602 (if_then_else (match_operator 0 "comparison_operator"
14603 [(match_operand 1 "register_operand" "x")
14604 (match_operand 2 "nonimmediate_operand" "xm")])
14606 (label_ref (match_operand 3 "" ""))))
14607 (clobber (reg:CCFP FPSR_REG))
14608 (clobber (reg:CCFP FLAGS_REG))]
14610 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14611 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14615 (define_insn "*fp_jcc_2_387"
14617 (if_then_else (match_operator 0 "comparison_operator"
14618 [(match_operand 1 "register_operand" "f")
14619 (match_operand 2 "register_operand" "f")])
14621 (label_ref (match_operand 3 "" ""))))
14622 (clobber (reg:CCFP FPSR_REG))
14623 (clobber (reg:CCFP FLAGS_REG))]
14624 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14626 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14630 (define_insn "*fp_jcc_3_387"
14632 (if_then_else (match_operator 0 "comparison_operator"
14633 [(match_operand 1 "register_operand" "f")
14634 (match_operand 2 "nonimmediate_operand" "fm")])
14635 (label_ref (match_operand 3 "" ""))
14637 (clobber (reg:CCFP FPSR_REG))
14638 (clobber (reg:CCFP FLAGS_REG))
14639 (clobber (match_scratch:HI 4 "=a"))]
14641 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14642 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14643 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14644 && SELECT_CC_MODE (GET_CODE (operands[0]),
14645 operands[1], operands[2]) == CCFPmode
14646 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14649 (define_insn "*fp_jcc_4_387"
14651 (if_then_else (match_operator 0 "comparison_operator"
14652 [(match_operand 1 "register_operand" "f")
14653 (match_operand 2 "nonimmediate_operand" "fm")])
14655 (label_ref (match_operand 3 "" ""))))
14656 (clobber (reg:CCFP FPSR_REG))
14657 (clobber (reg:CCFP FLAGS_REG))
14658 (clobber (match_scratch:HI 4 "=a"))]
14660 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14661 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14662 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14663 && SELECT_CC_MODE (GET_CODE (operands[0]),
14664 operands[1], operands[2]) == CCFPmode
14665 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14668 (define_insn "*fp_jcc_5_387"
14670 (if_then_else (match_operator 0 "comparison_operator"
14671 [(match_operand 1 "register_operand" "f")
14672 (match_operand 2 "register_operand" "f")])
14673 (label_ref (match_operand 3 "" ""))
14675 (clobber (reg:CCFP FPSR_REG))
14676 (clobber (reg:CCFP FLAGS_REG))
14677 (clobber (match_scratch:HI 4 "=a"))]
14678 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14683 (define_insn "*fp_jcc_6_387"
14685 (if_then_else (match_operator 0 "comparison_operator"
14686 [(match_operand 1 "register_operand" "f")
14687 (match_operand 2 "register_operand" "f")])
14689 (label_ref (match_operand 3 "" ""))))
14690 (clobber (reg:CCFP FPSR_REG))
14691 (clobber (reg:CCFP FLAGS_REG))
14692 (clobber (match_scratch:HI 4 "=a"))]
14693 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14698 (define_insn "*fp_jcc_7_387"
14700 (if_then_else (match_operator 0 "comparison_operator"
14701 [(match_operand 1 "register_operand" "f")
14702 (match_operand 2 "const0_operand" "")])
14703 (label_ref (match_operand 3 "" ""))
14705 (clobber (reg:CCFP FPSR_REG))
14706 (clobber (reg:CCFP FLAGS_REG))
14707 (clobber (match_scratch:HI 4 "=a"))]
14708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14709 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14710 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14711 && SELECT_CC_MODE (GET_CODE (operands[0]),
14712 operands[1], operands[2]) == CCFPmode
14713 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14716 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14717 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14718 ;; with a precedence over other operators and is always put in the first
14719 ;; place. Swap condition and operands to match ficom instruction.
14721 (define_insn "*fp_jcc_8<mode>_387"
14723 (if_then_else (match_operator 0 "comparison_operator"
14724 [(match_operator 1 "float_operator"
14725 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14726 (match_operand 3 "register_operand" "f,f")])
14727 (label_ref (match_operand 4 "" ""))
14729 (clobber (reg:CCFP FPSR_REG))
14730 (clobber (reg:CCFP FLAGS_REG))
14731 (clobber (match_scratch:HI 5 "=a,a"))]
14732 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14733 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14734 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14735 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14736 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14737 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14742 (if_then_else (match_operator 0 "comparison_operator"
14743 [(match_operand 1 "register_operand" "")
14744 (match_operand 2 "nonimmediate_operand" "")])
14745 (match_operand 3 "" "")
14746 (match_operand 4 "" "")))
14747 (clobber (reg:CCFP FPSR_REG))
14748 (clobber (reg:CCFP FLAGS_REG))]
14752 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14753 operands[3], operands[4], NULL_RTX, NULL_RTX);
14759 (if_then_else (match_operator 0 "comparison_operator"
14760 [(match_operand 1 "register_operand" "")
14761 (match_operand 2 "general_operand" "")])
14762 (match_operand 3 "" "")
14763 (match_operand 4 "" "")))
14764 (clobber (reg:CCFP FPSR_REG))
14765 (clobber (reg:CCFP FLAGS_REG))
14766 (clobber (match_scratch:HI 5 "=a"))]
14770 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14771 operands[3], operands[4], operands[5], NULL_RTX);
14777 (if_then_else (match_operator 0 "comparison_operator"
14778 [(match_operator 1 "float_operator"
14779 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14780 (match_operand 3 "register_operand" "")])
14781 (match_operand 4 "" "")
14782 (match_operand 5 "" "")))
14783 (clobber (reg:CCFP FPSR_REG))
14784 (clobber (reg:CCFP FLAGS_REG))
14785 (clobber (match_scratch:HI 6 "=a"))]
14789 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14790 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14791 operands[3], operands[7],
14792 operands[4], operands[5], operands[6], NULL_RTX);
14796 ;; %%% Kill this when reload knows how to do it.
14799 (if_then_else (match_operator 0 "comparison_operator"
14800 [(match_operator 1 "float_operator"
14801 [(match_operand:X87MODEI12 2 "register_operand" "")])
14802 (match_operand 3 "register_operand" "")])
14803 (match_operand 4 "" "")
14804 (match_operand 5 "" "")))
14805 (clobber (reg:CCFP FPSR_REG))
14806 (clobber (reg:CCFP FLAGS_REG))
14807 (clobber (match_scratch:HI 6 "=a"))]
14811 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14812 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14813 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14814 operands[3], operands[7],
14815 operands[4], operands[5], operands[6], operands[2]);
14819 ;; Unconditional and other jump instructions
14821 (define_insn "jump"
14823 (label_ref (match_operand 0 "" "")))]
14826 [(set_attr "type" "ibr")
14827 (set (attr "length")
14828 (if_then_else (and (ge (minus (match_dup 0) (pc))
14830 (lt (minus (match_dup 0) (pc))
14834 (set_attr "modrm" "0")])
14836 (define_expand "indirect_jump"
14837 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14841 (define_insn "*indirect_jump"
14842 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14845 [(set_attr "type" "ibr")
14846 (set_attr "length_immediate" "0")])
14848 (define_expand "tablejump"
14849 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14850 (use (label_ref (match_operand 1 "" "")))])]
14853 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14854 relative. Convert the relative address to an absolute address. */
14858 enum rtx_code code;
14860 /* We can't use @GOTOFF for text labels on VxWorks;
14861 see gotoff_operand. */
14862 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14866 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14868 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14872 op1 = pic_offset_table_rtx;
14877 op0 = pic_offset_table_rtx;
14881 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14886 (define_insn "*tablejump_1"
14887 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14888 (use (label_ref (match_operand 1 "" "")))]
14891 [(set_attr "type" "ibr")
14892 (set_attr "length_immediate" "0")])
14894 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14897 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14898 (set (match_operand:QI 1 "register_operand" "")
14899 (match_operator:QI 2 "ix86_comparison_operator"
14900 [(reg FLAGS_REG) (const_int 0)]))
14901 (set (match_operand 3 "q_regs_operand" "")
14902 (zero_extend (match_dup 1)))]
14903 "(peep2_reg_dead_p (3, operands[1])
14904 || operands_match_p (operands[1], operands[3]))
14905 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14906 [(set (match_dup 4) (match_dup 0))
14907 (set (strict_low_part (match_dup 5))
14910 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14911 operands[5] = gen_lowpart (QImode, operands[3]);
14912 ix86_expand_clear (operands[3]);
14915 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14918 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14919 (set (match_operand:QI 1 "register_operand" "")
14920 (match_operator:QI 2 "ix86_comparison_operator"
14921 [(reg FLAGS_REG) (const_int 0)]))
14922 (parallel [(set (match_operand 3 "q_regs_operand" "")
14923 (zero_extend (match_dup 1)))
14924 (clobber (reg:CC FLAGS_REG))])]
14925 "(peep2_reg_dead_p (3, operands[1])
14926 || operands_match_p (operands[1], operands[3]))
14927 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14928 [(set (match_dup 4) (match_dup 0))
14929 (set (strict_low_part (match_dup 5))
14932 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14933 operands[5] = gen_lowpart (QImode, operands[3]);
14934 ix86_expand_clear (operands[3]);
14937 ;; Call instructions.
14939 ;; The predicates normally associated with named expanders are not properly
14940 ;; checked for calls. This is a bug in the generic code, but it isn't that
14941 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14943 ;; Call subroutine returning no value.
14945 (define_expand "call_pop"
14946 [(parallel [(call (match_operand:QI 0 "" "")
14947 (match_operand:SI 1 "" ""))
14948 (set (reg:SI SP_REG)
14949 (plus:SI (reg:SI SP_REG)
14950 (match_operand:SI 3 "" "")))])]
14953 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14957 (define_insn "*call_pop_0"
14958 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14959 (match_operand:SI 1 "" ""))
14960 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14961 (match_operand:SI 2 "immediate_operand" "")))]
14964 if (SIBLING_CALL_P (insn))
14967 return "call\t%P0";
14969 [(set_attr "type" "call")])
14971 (define_insn "*call_pop_1"
14972 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14973 (match_operand:SI 1 "" ""))
14974 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14975 (match_operand:SI 2 "immediate_operand" "i")))]
14976 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14978 if (constant_call_address_operand (operands[0], Pmode))
14979 return "call\t%P0";
14980 return "call\t%A0";
14982 [(set_attr "type" "call")])
14984 (define_insn "*sibcall_pop_1"
14985 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14986 (match_operand:SI 1 "" ""))
14987 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14988 (match_operand:SI 2 "immediate_operand" "i,i")))]
14989 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14993 [(set_attr "type" "call")])
14995 (define_expand "call"
14996 [(call (match_operand:QI 0 "" "")
14997 (match_operand 1 "" ""))
14998 (use (match_operand 2 "" ""))]
15001 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15005 (define_expand "sibcall"
15006 [(call (match_operand:QI 0 "" "")
15007 (match_operand 1 "" ""))
15008 (use (match_operand 2 "" ""))]
15011 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15015 (define_insn "*call_0"
15016 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15017 (match_operand 1 "" ""))]
15020 if (SIBLING_CALL_P (insn))
15023 return "call\t%P0";
15025 [(set_attr "type" "call")])
15027 (define_insn "*call_1"
15028 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15029 (match_operand 1 "" ""))]
15030 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15032 if (constant_call_address_operand (operands[0], Pmode))
15033 return "call\t%P0";
15034 return "call\t%A0";
15036 [(set_attr "type" "call")])
15038 (define_insn "*sibcall_1"
15039 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15040 (match_operand 1 "" ""))]
15041 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15045 [(set_attr "type" "call")])
15047 (define_insn "*call_1_rex64"
15048 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15049 (match_operand 1 "" ""))]
15050 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15051 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15053 if (constant_call_address_operand (operands[0], Pmode))
15054 return "call\t%P0";
15055 return "call\t%A0";
15057 [(set_attr "type" "call")])
15059 (define_insn "*call_1_rex64_ms_sysv"
15060 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15061 (match_operand 1 "" ""))
15062 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15063 (clobber (reg:TI XMM6_REG))
15064 (clobber (reg:TI XMM7_REG))
15065 (clobber (reg:TI XMM8_REG))
15066 (clobber (reg:TI XMM9_REG))
15067 (clobber (reg:TI XMM10_REG))
15068 (clobber (reg:TI XMM11_REG))
15069 (clobber (reg:TI XMM12_REG))
15070 (clobber (reg:TI XMM13_REG))
15071 (clobber (reg:TI XMM14_REG))
15072 (clobber (reg:TI XMM15_REG))
15073 (clobber (reg:DI SI_REG))
15074 (clobber (reg:DI DI_REG))]
15075 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15077 if (constant_call_address_operand (operands[0], Pmode))
15078 return "call\t%P0";
15079 return "call\t%A0";
15081 [(set_attr "type" "call")])
15083 (define_insn "*call_1_rex64_large"
15084 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15085 (match_operand 1 "" ""))]
15086 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15088 [(set_attr "type" "call")])
15090 (define_insn "*sibcall_1_rex64"
15091 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15092 (match_operand 1 "" ""))]
15093 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15097 [(set_attr "type" "call")])
15099 ;; Call subroutine, returning value in operand 0
15100 (define_expand "call_value_pop"
15101 [(parallel [(set (match_operand 0 "" "")
15102 (call (match_operand:QI 1 "" "")
15103 (match_operand:SI 2 "" "")))
15104 (set (reg:SI SP_REG)
15105 (plus:SI (reg:SI SP_REG)
15106 (match_operand:SI 4 "" "")))])]
15109 ix86_expand_call (operands[0], operands[1], operands[2],
15110 operands[3], operands[4], 0);
15114 (define_expand "call_value"
15115 [(set (match_operand 0 "" "")
15116 (call (match_operand:QI 1 "" "")
15117 (match_operand:SI 2 "" "")))
15118 (use (match_operand:SI 3 "" ""))]
15119 ;; Operand 2 not used on the i386.
15122 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15126 (define_expand "sibcall_value"
15127 [(set (match_operand 0 "" "")
15128 (call (match_operand:QI 1 "" "")
15129 (match_operand:SI 2 "" "")))
15130 (use (match_operand:SI 3 "" ""))]
15131 ;; Operand 2 not used on the i386.
15134 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15138 ;; Call subroutine returning any type.
15140 (define_expand "untyped_call"
15141 [(parallel [(call (match_operand 0 "" "")
15143 (match_operand 1 "" "")
15144 (match_operand 2 "" "")])]
15149 /* In order to give reg-stack an easier job in validating two
15150 coprocessor registers as containing a possible return value,
15151 simply pretend the untyped call returns a complex long double
15154 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15155 and should have the default ABI. */
15157 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15158 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15159 operands[0], const0_rtx,
15160 GEN_INT ((TARGET_64BIT
15161 ? (DEFAULT_ABI == SYSV_ABI
15162 ? X86_64_SSE_REGPARM_MAX
15163 : X64_SSE_REGPARM_MAX)
15164 : X86_32_SSE_REGPARM_MAX)
15168 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15170 rtx set = XVECEXP (operands[2], 0, i);
15171 emit_move_insn (SET_DEST (set), SET_SRC (set));
15174 /* The optimizer does not know that the call sets the function value
15175 registers we stored in the result block. We avoid problems by
15176 claiming that all hard registers are used and clobbered at this
15178 emit_insn (gen_blockage ());
15183 ;; Prologue and epilogue instructions
15185 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15186 ;; all of memory. This blocks insns from being moved across this point.
15188 (define_insn "blockage"
15189 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15192 [(set_attr "length" "0")])
15194 ;; Do not schedule instructions accessing memory across this point.
15196 (define_expand "memory_blockage"
15197 [(set (match_dup 0)
15198 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15201 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15202 MEM_VOLATILE_P (operands[0]) = 1;
15205 (define_insn "*memory_blockage"
15206 [(set (match_operand:BLK 0 "" "")
15207 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15210 [(set_attr "length" "0")])
15212 ;; As USE insns aren't meaningful after reload, this is used instead
15213 ;; to prevent deleting instructions setting registers for PIC code
15214 (define_insn "prologue_use"
15215 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15218 [(set_attr "length" "0")])
15220 ;; Insn emitted into the body of a function to return from a function.
15221 ;; This is only done if the function's epilogue is known to be simple.
15222 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15224 (define_expand "return"
15226 "ix86_can_use_return_insn_p ()"
15228 if (crtl->args.pops_args)
15230 rtx popc = GEN_INT (crtl->args.pops_args);
15231 emit_jump_insn (gen_return_pop_internal (popc));
15236 (define_insn "return_internal"
15240 [(set_attr "length" "1")
15241 (set_attr "length_immediate" "0")
15242 (set_attr "modrm" "0")])
15244 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15245 ;; instruction Athlon and K8 have.
15247 (define_insn "return_internal_long"
15249 (unspec [(const_int 0)] UNSPEC_REP)]
15252 [(set_attr "length" "1")
15253 (set_attr "length_immediate" "0")
15254 (set_attr "prefix_rep" "1")
15255 (set_attr "modrm" "0")])
15257 (define_insn "return_pop_internal"
15259 (use (match_operand:SI 0 "const_int_operand" ""))]
15262 [(set_attr "length" "3")
15263 (set_attr "length_immediate" "2")
15264 (set_attr "modrm" "0")])
15266 (define_insn "return_indirect_internal"
15268 (use (match_operand:SI 0 "register_operand" "r"))]
15271 [(set_attr "type" "ibr")
15272 (set_attr "length_immediate" "0")])
15278 [(set_attr "length" "1")
15279 (set_attr "length_immediate" "0")
15280 (set_attr "modrm" "0")])
15282 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15283 ;; branch prediction penalty for the third jump in a 16-byte
15286 (define_insn "align"
15287 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15290 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15291 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15293 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15294 The align insn is used to avoid 3 jump instructions in the row to improve
15295 branch prediction and the benefits hardly outweigh the cost of extra 8
15296 nops on the average inserted by full alignment pseudo operation. */
15300 [(set_attr "length" "16")])
15302 (define_expand "prologue"
15305 "ix86_expand_prologue (); DONE;")
15307 (define_insn "set_got"
15308 [(set (match_operand:SI 0 "register_operand" "=r")
15309 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15310 (clobber (reg:CC FLAGS_REG))]
15312 { return output_set_got (operands[0], NULL_RTX); }
15313 [(set_attr "type" "multi")
15314 (set_attr "length" "12")])
15316 (define_insn "set_got_labelled"
15317 [(set (match_operand:SI 0 "register_operand" "=r")
15318 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15320 (clobber (reg:CC FLAGS_REG))]
15322 { return output_set_got (operands[0], operands[1]); }
15323 [(set_attr "type" "multi")
15324 (set_attr "length" "12")])
15326 (define_insn "set_got_rex64"
15327 [(set (match_operand:DI 0 "register_operand" "=r")
15328 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15330 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15331 [(set_attr "type" "lea")
15332 (set_attr "length" "6")])
15334 (define_insn "set_rip_rex64"
15335 [(set (match_operand:DI 0 "register_operand" "=r")
15336 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15338 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15339 [(set_attr "type" "lea")
15340 (set_attr "length" "6")])
15342 (define_insn "set_got_offset_rex64"
15343 [(set (match_operand:DI 0 "register_operand" "=r")
15345 [(label_ref (match_operand 1 "" ""))]
15346 UNSPEC_SET_GOT_OFFSET))]
15348 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15349 [(set_attr "type" "imov")
15350 (set_attr "length" "11")])
15352 (define_expand "epilogue"
15355 "ix86_expand_epilogue (1); DONE;")
15357 (define_expand "sibcall_epilogue"
15360 "ix86_expand_epilogue (0); DONE;")
15362 (define_expand "eh_return"
15363 [(use (match_operand 0 "register_operand" ""))]
15366 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15368 /* Tricky bit: we write the address of the handler to which we will
15369 be returning into someone else's stack frame, one word below the
15370 stack address we wish to restore. */
15371 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15372 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15373 tmp = gen_rtx_MEM (Pmode, tmp);
15374 emit_move_insn (tmp, ra);
15376 if (Pmode == SImode)
15377 emit_jump_insn (gen_eh_return_si (sa));
15379 emit_jump_insn (gen_eh_return_di (sa));
15384 (define_insn_and_split "eh_return_<mode>"
15386 (unspec [(match_operand:P 0 "register_operand" "c")]
15387 UNSPEC_EH_RETURN))]
15392 "ix86_expand_epilogue (2); DONE;")
15394 (define_insn "leave"
15395 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15396 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15397 (clobber (mem:BLK (scratch)))]
15400 [(set_attr "type" "leave")])
15402 (define_insn "leave_rex64"
15403 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15404 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15405 (clobber (mem:BLK (scratch)))]
15408 [(set_attr "type" "leave")])
15410 (define_expand "ffssi2"
15412 [(set (match_operand:SI 0 "register_operand" "")
15413 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15414 (clobber (match_scratch:SI 2 ""))
15415 (clobber (reg:CC FLAGS_REG))])]
15420 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15425 (define_expand "ffs_cmove"
15426 [(set (match_dup 2) (const_int -1))
15427 (parallel [(set (reg:CCZ FLAGS_REG)
15428 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15430 (set (match_operand:SI 0 "register_operand" "")
15431 (ctz:SI (match_dup 1)))])
15432 (set (match_dup 0) (if_then_else:SI
15433 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15436 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15437 (clobber (reg:CC FLAGS_REG))])]
15439 "operands[2] = gen_reg_rtx (SImode);")
15441 (define_insn_and_split "*ffs_no_cmove"
15442 [(set (match_operand:SI 0 "register_operand" "=r")
15443 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15444 (clobber (match_scratch:SI 2 "=&q"))
15445 (clobber (reg:CC FLAGS_REG))]
15448 "&& reload_completed"
15449 [(parallel [(set (reg:CCZ FLAGS_REG)
15450 (compare:CCZ (match_dup 1) (const_int 0)))
15451 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15452 (set (strict_low_part (match_dup 3))
15453 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15454 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15455 (clobber (reg:CC FLAGS_REG))])
15456 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15457 (clobber (reg:CC FLAGS_REG))])
15458 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15459 (clobber (reg:CC FLAGS_REG))])]
15461 operands[3] = gen_lowpart (QImode, operands[2]);
15462 ix86_expand_clear (operands[2]);
15465 (define_insn "*ffssi_1"
15466 [(set (reg:CCZ FLAGS_REG)
15467 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15469 (set (match_operand:SI 0 "register_operand" "=r")
15470 (ctz:SI (match_dup 1)))]
15472 "bsf{l}\t{%1, %0|%0, %1}"
15473 [(set_attr "prefix_0f" "1")])
15475 (define_expand "ffsdi2"
15476 [(set (match_dup 2) (const_int -1))
15477 (parallel [(set (reg:CCZ FLAGS_REG)
15478 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15480 (set (match_operand:DI 0 "register_operand" "")
15481 (ctz:DI (match_dup 1)))])
15482 (set (match_dup 0) (if_then_else:DI
15483 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15486 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15487 (clobber (reg:CC FLAGS_REG))])]
15489 "operands[2] = gen_reg_rtx (DImode);")
15491 (define_insn "*ffsdi_1"
15492 [(set (reg:CCZ FLAGS_REG)
15493 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15495 (set (match_operand:DI 0 "register_operand" "=r")
15496 (ctz:DI (match_dup 1)))]
15498 "bsf{q}\t{%1, %0|%0, %1}"
15499 [(set_attr "prefix_0f" "1")])
15501 (define_insn "ctzsi2"
15502 [(set (match_operand:SI 0 "register_operand" "=r")
15503 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15504 (clobber (reg:CC FLAGS_REG))]
15506 "bsf{l}\t{%1, %0|%0, %1}"
15507 [(set_attr "prefix_0f" "1")])
15509 (define_insn "ctzdi2"
15510 [(set (match_operand:DI 0 "register_operand" "=r")
15511 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15512 (clobber (reg:CC FLAGS_REG))]
15514 "bsf{q}\t{%1, %0|%0, %1}"
15515 [(set_attr "prefix_0f" "1")])
15517 (define_expand "clzsi2"
15519 [(set (match_operand:SI 0 "register_operand" "")
15520 (minus:SI (const_int 31)
15521 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15522 (clobber (reg:CC FLAGS_REG))])
15524 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15525 (clobber (reg:CC FLAGS_REG))])]
15530 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15535 (define_insn "clzsi2_abm"
15536 [(set (match_operand:SI 0 "register_operand" "=r")
15537 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15538 (clobber (reg:CC FLAGS_REG))]
15540 "lzcnt{l}\t{%1, %0|%0, %1}"
15541 [(set_attr "prefix_rep" "1")
15542 (set_attr "type" "bitmanip")
15543 (set_attr "mode" "SI")])
15545 (define_insn "*bsr"
15546 [(set (match_operand:SI 0 "register_operand" "=r")
15547 (minus:SI (const_int 31)
15548 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15549 (clobber (reg:CC FLAGS_REG))]
15551 "bsr{l}\t{%1, %0|%0, %1}"
15552 [(set_attr "prefix_0f" "1")
15553 (set_attr "mode" "SI")])
15555 (define_insn "popcount<mode>2"
15556 [(set (match_operand:SWI248 0 "register_operand" "=r")
15558 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15559 (clobber (reg:CC FLAGS_REG))]
15563 return "popcnt\t{%1, %0|%0, %1}";
15565 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15568 [(set_attr "prefix_rep" "1")
15569 (set_attr "type" "bitmanip")
15570 (set_attr "mode" "<MODE>")])
15572 (define_insn "*popcount<mode>2_cmp"
15573 [(set (reg FLAGS_REG)
15576 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15578 (set (match_operand:SWI248 0 "register_operand" "=r")
15579 (popcount:SWI248 (match_dup 1)))]
15580 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15583 return "popcnt\t{%1, %0|%0, %1}";
15585 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15588 [(set_attr "prefix_rep" "1")
15589 (set_attr "type" "bitmanip")
15590 (set_attr "mode" "<MODE>")])
15592 (define_insn "*popcountsi2_cmp_zext"
15593 [(set (reg FLAGS_REG)
15595 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15597 (set (match_operand:DI 0 "register_operand" "=r")
15598 (zero_extend:DI(popcount:SI (match_dup 1))))]
15599 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15602 return "popcnt\t{%1, %0|%0, %1}";
15604 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15607 [(set_attr "prefix_rep" "1")
15608 (set_attr "type" "bitmanip")
15609 (set_attr "mode" "SI")])
15611 (define_expand "bswapsi2"
15612 [(set (match_operand:SI 0 "register_operand" "")
15613 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15618 rtx x = operands[0];
15620 emit_move_insn (x, operands[1]);
15621 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15622 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15623 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15628 (define_insn "*bswapsi_1"
15629 [(set (match_operand:SI 0 "register_operand" "=r")
15630 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15633 [(set_attr "prefix_0f" "1")
15634 (set_attr "length" "2")])
15636 (define_insn "*bswaphi_lowpart_1"
15637 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15638 (bswap:HI (match_dup 0)))
15639 (clobber (reg:CC FLAGS_REG))]
15640 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15642 xchg{b}\t{%h0, %b0|%b0, %h0}
15643 rol{w}\t{$8, %0|%0, 8}"
15644 [(set_attr "length" "2,4")
15645 (set_attr "mode" "QI,HI")])
15647 (define_insn "bswaphi_lowpart"
15648 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15649 (bswap:HI (match_dup 0)))
15650 (clobber (reg:CC FLAGS_REG))]
15652 "rol{w}\t{$8, %0|%0, 8}"
15653 [(set_attr "length" "4")
15654 (set_attr "mode" "HI")])
15656 (define_insn "bswapdi2"
15657 [(set (match_operand:DI 0 "register_operand" "=r")
15658 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15661 [(set_attr "prefix_0f" "1")
15662 (set_attr "length" "3")])
15664 (define_expand "clzdi2"
15666 [(set (match_operand:DI 0 "register_operand" "")
15667 (minus:DI (const_int 63)
15668 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15669 (clobber (reg:CC FLAGS_REG))])
15671 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15672 (clobber (reg:CC FLAGS_REG))])]
15677 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15682 (define_insn "clzdi2_abm"
15683 [(set (match_operand:DI 0 "register_operand" "=r")
15684 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15685 (clobber (reg:CC FLAGS_REG))]
15686 "TARGET_64BIT && TARGET_ABM"
15687 "lzcnt{q}\t{%1, %0|%0, %1}"
15688 [(set_attr "prefix_rep" "1")
15689 (set_attr "type" "bitmanip")
15690 (set_attr "mode" "DI")])
15692 (define_insn "*bsr_rex64"
15693 [(set (match_operand:DI 0 "register_operand" "=r")
15694 (minus:DI (const_int 63)
15695 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15696 (clobber (reg:CC FLAGS_REG))]
15698 "bsr{q}\t{%1, %0|%0, %1}"
15699 [(set_attr "prefix_0f" "1")
15700 (set_attr "mode" "DI")])
15702 (define_expand "clzhi2"
15704 [(set (match_operand:HI 0 "register_operand" "")
15705 (minus:HI (const_int 15)
15706 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15707 (clobber (reg:CC FLAGS_REG))])
15709 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15710 (clobber (reg:CC FLAGS_REG))])]
15715 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15720 (define_insn "clzhi2_abm"
15721 [(set (match_operand:HI 0 "register_operand" "=r")
15722 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15723 (clobber (reg:CC FLAGS_REG))]
15725 "lzcnt{w}\t{%1, %0|%0, %1}"
15726 [(set_attr "prefix_rep" "1")
15727 (set_attr "type" "bitmanip")
15728 (set_attr "mode" "HI")])
15730 (define_insn "*bsrhi"
15731 [(set (match_operand:HI 0 "register_operand" "=r")
15732 (minus:HI (const_int 15)
15733 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15734 (clobber (reg:CC FLAGS_REG))]
15736 "bsr{w}\t{%1, %0|%0, %1}"
15737 [(set_attr "prefix_0f" "1")
15738 (set_attr "mode" "HI")])
15740 (define_expand "paritydi2"
15741 [(set (match_operand:DI 0 "register_operand" "")
15742 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15745 rtx scratch = gen_reg_rtx (QImode);
15748 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15749 NULL_RTX, operands[1]));
15751 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15752 gen_rtx_REG (CCmode, FLAGS_REG),
15754 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15757 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15760 rtx tmp = gen_reg_rtx (SImode);
15762 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15763 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15768 (define_insn_and_split "paritydi2_cmp"
15769 [(set (reg:CC FLAGS_REG)
15770 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15771 (clobber (match_scratch:DI 0 "=r"))
15772 (clobber (match_scratch:SI 1 "=&r"))
15773 (clobber (match_scratch:HI 2 "=Q"))]
15776 "&& reload_completed"
15778 [(set (match_dup 1)
15779 (xor:SI (match_dup 1) (match_dup 4)))
15780 (clobber (reg:CC FLAGS_REG))])
15782 [(set (reg:CC FLAGS_REG)
15783 (parity:CC (match_dup 1)))
15784 (clobber (match_dup 1))
15785 (clobber (match_dup 2))])]
15787 operands[4] = gen_lowpart (SImode, operands[3]);
15791 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15792 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15795 operands[1] = gen_highpart (SImode, operands[3]);
15798 (define_expand "paritysi2"
15799 [(set (match_operand:SI 0 "register_operand" "")
15800 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15803 rtx scratch = gen_reg_rtx (QImode);
15806 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15808 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15809 gen_rtx_REG (CCmode, FLAGS_REG),
15811 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15813 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15817 (define_insn_and_split "paritysi2_cmp"
15818 [(set (reg:CC FLAGS_REG)
15819 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15820 (clobber (match_scratch:SI 0 "=r"))
15821 (clobber (match_scratch:HI 1 "=&Q"))]
15824 "&& reload_completed"
15826 [(set (match_dup 1)
15827 (xor:HI (match_dup 1) (match_dup 3)))
15828 (clobber (reg:CC FLAGS_REG))])
15830 [(set (reg:CC FLAGS_REG)
15831 (parity:CC (match_dup 1)))
15832 (clobber (match_dup 1))])]
15834 operands[3] = gen_lowpart (HImode, operands[2]);
15836 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15837 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15840 (define_insn "*parityhi2_cmp"
15841 [(set (reg:CC FLAGS_REG)
15842 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15843 (clobber (match_scratch:HI 0 "=Q"))]
15845 "xor{b}\t{%h0, %b0|%b0, %h0}"
15846 [(set_attr "length" "2")
15847 (set_attr "mode" "HI")])
15849 (define_insn "*parityqi2_cmp"
15850 [(set (reg:CC FLAGS_REG)
15851 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15854 [(set_attr "length" "2")
15855 (set_attr "mode" "QI")])
15857 ;; Thread-local storage patterns for ELF.
15859 ;; Note that these code sequences must appear exactly as shown
15860 ;; in order to allow linker relaxation.
15862 (define_insn "*tls_global_dynamic_32_gnu"
15863 [(set (match_operand:SI 0 "register_operand" "=a")
15864 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15865 (match_operand:SI 2 "tls_symbolic_operand" "")
15866 (match_operand:SI 3 "call_insn_operand" "")]
15868 (clobber (match_scratch:SI 4 "=d"))
15869 (clobber (match_scratch:SI 5 "=c"))
15870 (clobber (reg:CC FLAGS_REG))]
15871 "!TARGET_64BIT && TARGET_GNU_TLS"
15872 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15873 [(set_attr "type" "multi")
15874 (set_attr "length" "12")])
15876 (define_insn "*tls_global_dynamic_32_sun"
15877 [(set (match_operand:SI 0 "register_operand" "=a")
15878 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15879 (match_operand:SI 2 "tls_symbolic_operand" "")
15880 (match_operand:SI 3 "call_insn_operand" "")]
15882 (clobber (match_scratch:SI 4 "=d"))
15883 (clobber (match_scratch:SI 5 "=c"))
15884 (clobber (reg:CC FLAGS_REG))]
15885 "!TARGET_64BIT && TARGET_SUN_TLS"
15886 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15887 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15888 [(set_attr "type" "multi")
15889 (set_attr "length" "14")])
15891 (define_expand "tls_global_dynamic_32"
15892 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15895 (match_operand:SI 1 "tls_symbolic_operand" "")
15898 (clobber (match_scratch:SI 4 ""))
15899 (clobber (match_scratch:SI 5 ""))
15900 (clobber (reg:CC FLAGS_REG))])]
15904 operands[2] = pic_offset_table_rtx;
15907 operands[2] = gen_reg_rtx (Pmode);
15908 emit_insn (gen_set_got (operands[2]));
15910 if (TARGET_GNU2_TLS)
15912 emit_insn (gen_tls_dynamic_gnu2_32
15913 (operands[0], operands[1], operands[2]));
15916 operands[3] = ix86_tls_get_addr ();
15919 (define_insn "*tls_global_dynamic_64"
15920 [(set (match_operand:DI 0 "register_operand" "=a")
15921 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15922 (match_operand:DI 3 "" "")))
15923 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15926 { return ".byte\t0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15927 [(set_attr "type" "multi")
15928 (set_attr "length" "16")])
15930 (define_expand "tls_global_dynamic_64"
15931 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15932 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15933 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15937 if (TARGET_GNU2_TLS)
15939 emit_insn (gen_tls_dynamic_gnu2_64
15940 (operands[0], operands[1]));
15943 operands[2] = ix86_tls_get_addr ();
15946 (define_insn "*tls_local_dynamic_base_32_gnu"
15947 [(set (match_operand:SI 0 "register_operand" "=a")
15948 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15949 (match_operand:SI 2 "call_insn_operand" "")]
15950 UNSPEC_TLS_LD_BASE))
15951 (clobber (match_scratch:SI 3 "=d"))
15952 (clobber (match_scratch:SI 4 "=c"))
15953 (clobber (reg:CC FLAGS_REG))]
15954 "!TARGET_64BIT && TARGET_GNU_TLS"
15955 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15956 [(set_attr "type" "multi")
15957 (set_attr "length" "11")])
15959 (define_insn "*tls_local_dynamic_base_32_sun"
15960 [(set (match_operand:SI 0 "register_operand" "=a")
15961 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15962 (match_operand:SI 2 "call_insn_operand" "")]
15963 UNSPEC_TLS_LD_BASE))
15964 (clobber (match_scratch:SI 3 "=d"))
15965 (clobber (match_scratch:SI 4 "=c"))
15966 (clobber (reg:CC FLAGS_REG))]
15967 "!TARGET_64BIT && TARGET_SUN_TLS"
15968 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15969 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15970 [(set_attr "type" "multi")
15971 (set_attr "length" "13")])
15973 (define_expand "tls_local_dynamic_base_32"
15974 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15975 (unspec:SI [(match_dup 1) (match_dup 2)]
15976 UNSPEC_TLS_LD_BASE))
15977 (clobber (match_scratch:SI 3 ""))
15978 (clobber (match_scratch:SI 4 ""))
15979 (clobber (reg:CC FLAGS_REG))])]
15983 operands[1] = pic_offset_table_rtx;
15986 operands[1] = gen_reg_rtx (Pmode);
15987 emit_insn (gen_set_got (operands[1]));
15989 if (TARGET_GNU2_TLS)
15991 emit_insn (gen_tls_dynamic_gnu2_32
15992 (operands[0], ix86_tls_module_base (), operands[1]));
15995 operands[2] = ix86_tls_get_addr ();
15998 (define_insn "*tls_local_dynamic_base_64"
15999 [(set (match_operand:DI 0 "register_operand" "=a")
16000 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16001 (match_operand:DI 2 "" "")))
16002 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16004 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16005 [(set_attr "type" "multi")
16006 (set_attr "length" "12")])
16008 (define_expand "tls_local_dynamic_base_64"
16009 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16010 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16011 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16014 if (TARGET_GNU2_TLS)
16016 emit_insn (gen_tls_dynamic_gnu2_64
16017 (operands[0], ix86_tls_module_base ()));
16020 operands[1] = ix86_tls_get_addr ();
16023 ;; Local dynamic of a single variable is a lose. Show combine how
16024 ;; to convert that back to global dynamic.
16026 (define_insn_and_split "*tls_local_dynamic_32_once"
16027 [(set (match_operand:SI 0 "register_operand" "=a")
16028 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16029 (match_operand:SI 2 "call_insn_operand" "")]
16030 UNSPEC_TLS_LD_BASE)
16031 (const:SI (unspec:SI
16032 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16034 (clobber (match_scratch:SI 4 "=d"))
16035 (clobber (match_scratch:SI 5 "=c"))
16036 (clobber (reg:CC FLAGS_REG))]
16040 [(parallel [(set (match_dup 0)
16041 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16043 (clobber (match_dup 4))
16044 (clobber (match_dup 5))
16045 (clobber (reg:CC FLAGS_REG))])]
16048 ;; Load and add the thread base pointer from %gs:0.
16050 (define_insn "*load_tp_si"
16051 [(set (match_operand:SI 0 "register_operand" "=r")
16052 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16054 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16055 [(set_attr "type" "imov")
16056 (set_attr "modrm" "0")
16057 (set_attr "length" "7")
16058 (set_attr "memory" "load")
16059 (set_attr "imm_disp" "false")])
16061 (define_insn "*add_tp_si"
16062 [(set (match_operand:SI 0 "register_operand" "=r")
16063 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16064 (match_operand:SI 1 "register_operand" "0")))
16065 (clobber (reg:CC FLAGS_REG))]
16067 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16068 [(set_attr "type" "alu")
16069 (set_attr "modrm" "0")
16070 (set_attr "length" "7")
16071 (set_attr "memory" "load")
16072 (set_attr "imm_disp" "false")])
16074 (define_insn "*load_tp_di"
16075 [(set (match_operand:DI 0 "register_operand" "=r")
16076 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16078 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16079 [(set_attr "type" "imov")
16080 (set_attr "modrm" "0")
16081 (set_attr "length" "7")
16082 (set_attr "memory" "load")
16083 (set_attr "imm_disp" "false")])
16085 (define_insn "*add_tp_di"
16086 [(set (match_operand:DI 0 "register_operand" "=r")
16087 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16088 (match_operand:DI 1 "register_operand" "0")))
16089 (clobber (reg:CC FLAGS_REG))]
16091 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16092 [(set_attr "type" "alu")
16093 (set_attr "modrm" "0")
16094 (set_attr "length" "7")
16095 (set_attr "memory" "load")
16096 (set_attr "imm_disp" "false")])
16098 ;; GNU2 TLS patterns can be split.
16100 (define_expand "tls_dynamic_gnu2_32"
16101 [(set (match_dup 3)
16102 (plus:SI (match_operand:SI 2 "register_operand" "")
16104 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16107 [(set (match_operand:SI 0 "register_operand" "")
16108 (unspec:SI [(match_dup 1) (match_dup 3)
16109 (match_dup 2) (reg:SI SP_REG)]
16111 (clobber (reg:CC FLAGS_REG))])]
16112 "!TARGET_64BIT && TARGET_GNU2_TLS"
16114 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16115 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16118 (define_insn "*tls_dynamic_lea_32"
16119 [(set (match_operand:SI 0 "register_operand" "=r")
16120 (plus:SI (match_operand:SI 1 "register_operand" "b")
16122 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16123 UNSPEC_TLSDESC))))]
16124 "!TARGET_64BIT && TARGET_GNU2_TLS"
16125 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16126 [(set_attr "type" "lea")
16127 (set_attr "mode" "SI")
16128 (set_attr "length" "6")
16129 (set_attr "length_address" "4")])
16131 (define_insn "*tls_dynamic_call_32"
16132 [(set (match_operand:SI 0 "register_operand" "=a")
16133 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16134 (match_operand:SI 2 "register_operand" "0")
16135 ;; we have to make sure %ebx still points to the GOT
16136 (match_operand:SI 3 "register_operand" "b")
16139 (clobber (reg:CC FLAGS_REG))]
16140 "!TARGET_64BIT && TARGET_GNU2_TLS"
16141 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16142 [(set_attr "type" "call")
16143 (set_attr "length" "2")
16144 (set_attr "length_address" "0")])
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16147 [(set (match_operand:SI 0 "register_operand" "=&a")
16149 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16150 (match_operand:SI 4 "" "")
16151 (match_operand:SI 2 "register_operand" "b")
16154 (const:SI (unspec:SI
16155 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16157 (clobber (reg:CC FLAGS_REG))]
16158 "!TARGET_64BIT && TARGET_GNU2_TLS"
16161 [(set (match_dup 0) (match_dup 5))]
16163 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16167 (define_expand "tls_dynamic_gnu2_64"
16168 [(set (match_dup 2)
16169 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16172 [(set (match_operand:DI 0 "register_operand" "")
16173 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16175 (clobber (reg:CC FLAGS_REG))])]
16176 "TARGET_64BIT && TARGET_GNU2_TLS"
16178 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16179 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16182 (define_insn "*tls_dynamic_lea_64"
16183 [(set (match_operand:DI 0 "register_operand" "=r")
16184 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16186 "TARGET_64BIT && TARGET_GNU2_TLS"
16187 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16188 [(set_attr "type" "lea")
16189 (set_attr "mode" "DI")
16190 (set_attr "length" "7")
16191 (set_attr "length_address" "4")])
16193 (define_insn "*tls_dynamic_call_64"
16194 [(set (match_operand:DI 0 "register_operand" "=a")
16195 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16196 (match_operand:DI 2 "register_operand" "0")
16199 (clobber (reg:CC FLAGS_REG))]
16200 "TARGET_64BIT && TARGET_GNU2_TLS"
16201 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16202 [(set_attr "type" "call")
16203 (set_attr "length" "2")
16204 (set_attr "length_address" "0")])
16206 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16207 [(set (match_operand:DI 0 "register_operand" "=&a")
16209 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16210 (match_operand:DI 3 "" "")
16213 (const:DI (unspec:DI
16214 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16216 (clobber (reg:CC FLAGS_REG))]
16217 "TARGET_64BIT && TARGET_GNU2_TLS"
16220 [(set (match_dup 0) (match_dup 4))]
16222 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16223 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16228 ;; These patterns match the binary 387 instructions for addM3, subM3,
16229 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16230 ;; SFmode. The first is the normal insn, the second the same insn but
16231 ;; with one operand a conversion, and the third the same insn but with
16232 ;; the other operand a conversion. The conversion may be SFmode or
16233 ;; SImode if the target mode DFmode, but only SImode if the target mode
16236 ;; Gcc is slightly more smart about handling normal two address instructions
16237 ;; so use special patterns for add and mull.
16239 (define_insn "*fop_<mode>_comm_mixed_avx"
16240 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16241 (match_operator:MODEF 3 "binary_fp_operator"
16242 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16243 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16244 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16245 && COMMUTATIVE_ARITH_P (operands[3])
16246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16247 "* return output_387_binary_op (insn, operands);"
16248 [(set (attr "type")
16249 (if_then_else (eq_attr "alternative" "1")
16250 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251 (const_string "ssemul")
16252 (const_string "sseadd"))
16253 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16254 (const_string "fmul")
16255 (const_string "fop"))))
16256 (set_attr "prefix" "orig,maybe_vex")
16257 (set_attr "mode" "<MODE>")])
16259 (define_insn "*fop_<mode>_comm_mixed"
16260 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16261 (match_operator:MODEF 3 "binary_fp_operator"
16262 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16264 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16265 && COMMUTATIVE_ARITH_P (operands[3])
16266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16267 "* return output_387_binary_op (insn, operands);"
16268 [(set (attr "type")
16269 (if_then_else (eq_attr "alternative" "1")
16270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271 (const_string "ssemul")
16272 (const_string "sseadd"))
16273 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274 (const_string "fmul")
16275 (const_string "fop"))))
16276 (set_attr "mode" "<MODE>")])
16278 (define_insn "*fop_<mode>_comm_avx"
16279 [(set (match_operand:MODEF 0 "register_operand" "=x")
16280 (match_operator:MODEF 3 "binary_fp_operator"
16281 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16282 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16283 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16284 && COMMUTATIVE_ARITH_P (operands[3])
16285 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286 "* return output_387_binary_op (insn, operands);"
16287 [(set (attr "type")
16288 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16289 (const_string "ssemul")
16290 (const_string "sseadd")))
16291 (set_attr "prefix" "vex")
16292 (set_attr "mode" "<MODE>")])
16294 (define_insn "*fop_<mode>_comm_sse"
16295 [(set (match_operand:MODEF 0 "register_operand" "=x")
16296 (match_operator:MODEF 3 "binary_fp_operator"
16297 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16299 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16300 && COMMUTATIVE_ARITH_P (operands[3])
16301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302 "* return output_387_binary_op (insn, operands);"
16303 [(set (attr "type")
16304 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305 (const_string "ssemul")
16306 (const_string "sseadd")))
16307 (set_attr "mode" "<MODE>")])
16309 (define_insn "*fop_<mode>_comm_i387"
16310 [(set (match_operand:MODEF 0 "register_operand" "=f")
16311 (match_operator:MODEF 3 "binary_fp_operator"
16312 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16313 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16315 && COMMUTATIVE_ARITH_P (operands[3])
16316 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317 "* return output_387_binary_op (insn, operands);"
16318 [(set (attr "type")
16319 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16320 (const_string "fmul")
16321 (const_string "fop")))
16322 (set_attr "mode" "<MODE>")])
16324 (define_insn "*fop_<mode>_1_mixed_avx"
16325 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16326 (match_operator:MODEF 3 "binary_fp_operator"
16327 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16328 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16329 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16330 && !COMMUTATIVE_ARITH_P (operands[3])
16331 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16332 "* return output_387_binary_op (insn, operands);"
16333 [(set (attr "type")
16334 (cond [(and (eq_attr "alternative" "2")
16335 (match_operand:MODEF 3 "mult_operator" ""))
16336 (const_string "ssemul")
16337 (and (eq_attr "alternative" "2")
16338 (match_operand:MODEF 3 "div_operator" ""))
16339 (const_string "ssediv")
16340 (eq_attr "alternative" "2")
16341 (const_string "sseadd")
16342 (match_operand:MODEF 3 "mult_operator" "")
16343 (const_string "fmul")
16344 (match_operand:MODEF 3 "div_operator" "")
16345 (const_string "fdiv")
16347 (const_string "fop")))
16348 (set_attr "prefix" "orig,orig,maybe_vex")
16349 (set_attr "mode" "<MODE>")])
16351 (define_insn "*fop_<mode>_1_mixed"
16352 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16353 (match_operator:MODEF 3 "binary_fp_operator"
16354 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16355 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16356 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16357 && !COMMUTATIVE_ARITH_P (operands[3])
16358 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16359 "* return output_387_binary_op (insn, operands);"
16360 [(set (attr "type")
16361 (cond [(and (eq_attr "alternative" "2")
16362 (match_operand:MODEF 3 "mult_operator" ""))
16363 (const_string "ssemul")
16364 (and (eq_attr "alternative" "2")
16365 (match_operand:MODEF 3 "div_operator" ""))
16366 (const_string "ssediv")
16367 (eq_attr "alternative" "2")
16368 (const_string "sseadd")
16369 (match_operand:MODEF 3 "mult_operator" "")
16370 (const_string "fmul")
16371 (match_operand:MODEF 3 "div_operator" "")
16372 (const_string "fdiv")
16374 (const_string "fop")))
16375 (set_attr "mode" "<MODE>")])
16377 (define_insn "*rcpsf2_sse"
16378 [(set (match_operand:SF 0 "register_operand" "=x")
16379 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16382 "%vrcpss\t{%1, %d0|%d0, %1}"
16383 [(set_attr "type" "sse")
16384 (set_attr "prefix" "maybe_vex")
16385 (set_attr "mode" "SF")])
16387 (define_insn "*fop_<mode>_1_avx"
16388 [(set (match_operand:MODEF 0 "register_operand" "=x")
16389 (match_operator:MODEF 3 "binary_fp_operator"
16390 [(match_operand:MODEF 1 "register_operand" "x")
16391 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16392 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16393 && !COMMUTATIVE_ARITH_P (operands[3])"
16394 "* return output_387_binary_op (insn, operands);"
16395 [(set (attr "type")
16396 (cond [(match_operand:MODEF 3 "mult_operator" "")
16397 (const_string "ssemul")
16398 (match_operand:MODEF 3 "div_operator" "")
16399 (const_string "ssediv")
16401 (const_string "sseadd")))
16402 (set_attr "prefix" "vex")
16403 (set_attr "mode" "<MODE>")])
16405 (define_insn "*fop_<mode>_1_sse"
16406 [(set (match_operand:MODEF 0 "register_operand" "=x")
16407 (match_operator:MODEF 3 "binary_fp_operator"
16408 [(match_operand:MODEF 1 "register_operand" "0")
16409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16410 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16411 && !COMMUTATIVE_ARITH_P (operands[3])"
16412 "* return output_387_binary_op (insn, operands);"
16413 [(set (attr "type")
16414 (cond [(match_operand:MODEF 3 "mult_operator" "")
16415 (const_string "ssemul")
16416 (match_operand:MODEF 3 "div_operator" "")
16417 (const_string "ssediv")
16419 (const_string "sseadd")))
16420 (set_attr "mode" "<MODE>")])
16422 ;; This pattern is not fully shadowed by the pattern above.
16423 (define_insn "*fop_<mode>_1_i387"
16424 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16425 (match_operator:MODEF 3 "binary_fp_operator"
16426 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16427 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16428 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429 && !COMMUTATIVE_ARITH_P (operands[3])
16430 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16431 "* return output_387_binary_op (insn, operands);"
16432 [(set (attr "type")
16433 (cond [(match_operand:MODEF 3 "mult_operator" "")
16434 (const_string "fmul")
16435 (match_operand:MODEF 3 "div_operator" "")
16436 (const_string "fdiv")
16438 (const_string "fop")))
16439 (set_attr "mode" "<MODE>")])
16441 ;; ??? Add SSE splitters for these!
16442 (define_insn "*fop_<MODEF:mode>_2_i387"
16443 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16444 (match_operator:MODEF 3 "binary_fp_operator"
16446 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16447 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16448 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16449 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16450 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16451 [(set (attr "type")
16452 (cond [(match_operand:MODEF 3 "mult_operator" "")
16453 (const_string "fmul")
16454 (match_operand:MODEF 3 "div_operator" "")
16455 (const_string "fdiv")
16457 (const_string "fop")))
16458 (set_attr "fp_int_src" "true")
16459 (set_attr "mode" "<X87MODEI12:MODE>")])
16461 (define_insn "*fop_<MODEF:mode>_3_i387"
16462 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16463 (match_operator:MODEF 3 "binary_fp_operator"
16464 [(match_operand:MODEF 1 "register_operand" "0,0")
16466 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16467 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16468 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16469 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16470 [(set (attr "type")
16471 (cond [(match_operand:MODEF 3 "mult_operator" "")
16472 (const_string "fmul")
16473 (match_operand:MODEF 3 "div_operator" "")
16474 (const_string "fdiv")
16476 (const_string "fop")))
16477 (set_attr "fp_int_src" "true")
16478 (set_attr "mode" "<MODE>")])
16480 (define_insn "*fop_df_4_i387"
16481 [(set (match_operand:DF 0 "register_operand" "=f,f")
16482 (match_operator:DF 3 "binary_fp_operator"
16484 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16485 (match_operand:DF 2 "register_operand" "0,f")]))]
16486 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16487 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16488 "* return output_387_binary_op (insn, operands);"
16489 [(set (attr "type")
16490 (cond [(match_operand:DF 3 "mult_operator" "")
16491 (const_string "fmul")
16492 (match_operand:DF 3 "div_operator" "")
16493 (const_string "fdiv")
16495 (const_string "fop")))
16496 (set_attr "mode" "SF")])
16498 (define_insn "*fop_df_5_i387"
16499 [(set (match_operand:DF 0 "register_operand" "=f,f")
16500 (match_operator:DF 3 "binary_fp_operator"
16501 [(match_operand:DF 1 "register_operand" "0,f")
16503 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16504 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16505 "* return output_387_binary_op (insn, operands);"
16506 [(set (attr "type")
16507 (cond [(match_operand:DF 3 "mult_operator" "")
16508 (const_string "fmul")
16509 (match_operand:DF 3 "div_operator" "")
16510 (const_string "fdiv")
16512 (const_string "fop")))
16513 (set_attr "mode" "SF")])
16515 (define_insn "*fop_df_6_i387"
16516 [(set (match_operand:DF 0 "register_operand" "=f,f")
16517 (match_operator:DF 3 "binary_fp_operator"
16519 (match_operand:SF 1 "register_operand" "0,f"))
16521 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16522 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16523 "* return output_387_binary_op (insn, operands);"
16524 [(set (attr "type")
16525 (cond [(match_operand:DF 3 "mult_operator" "")
16526 (const_string "fmul")
16527 (match_operand:DF 3 "div_operator" "")
16528 (const_string "fdiv")
16530 (const_string "fop")))
16531 (set_attr "mode" "SF")])
16533 (define_insn "*fop_xf_comm_i387"
16534 [(set (match_operand:XF 0 "register_operand" "=f")
16535 (match_operator:XF 3 "binary_fp_operator"
16536 [(match_operand:XF 1 "register_operand" "%0")
16537 (match_operand:XF 2 "register_operand" "f")]))]
16539 && COMMUTATIVE_ARITH_P (operands[3])"
16540 "* return output_387_binary_op (insn, operands);"
16541 [(set (attr "type")
16542 (if_then_else (match_operand:XF 3 "mult_operator" "")
16543 (const_string "fmul")
16544 (const_string "fop")))
16545 (set_attr "mode" "XF")])
16547 (define_insn "*fop_xf_1_i387"
16548 [(set (match_operand:XF 0 "register_operand" "=f,f")
16549 (match_operator:XF 3 "binary_fp_operator"
16550 [(match_operand:XF 1 "register_operand" "0,f")
16551 (match_operand:XF 2 "register_operand" "f,0")]))]
16553 && !COMMUTATIVE_ARITH_P (operands[3])"
16554 "* return output_387_binary_op (insn, operands);"
16555 [(set (attr "type")
16556 (cond [(match_operand:XF 3 "mult_operator" "")
16557 (const_string "fmul")
16558 (match_operand:XF 3 "div_operator" "")
16559 (const_string "fdiv")
16561 (const_string "fop")))
16562 (set_attr "mode" "XF")])
16564 (define_insn "*fop_xf_2_i387"
16565 [(set (match_operand:XF 0 "register_operand" "=f,f")
16566 (match_operator:XF 3 "binary_fp_operator"
16568 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16569 (match_operand:XF 2 "register_operand" "0,0")]))]
16570 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16571 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16572 [(set (attr "type")
16573 (cond [(match_operand:XF 3 "mult_operator" "")
16574 (const_string "fmul")
16575 (match_operand:XF 3 "div_operator" "")
16576 (const_string "fdiv")
16578 (const_string "fop")))
16579 (set_attr "fp_int_src" "true")
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "*fop_xf_3_i387"
16583 [(set (match_operand:XF 0 "register_operand" "=f,f")
16584 (match_operator:XF 3 "binary_fp_operator"
16585 [(match_operand:XF 1 "register_operand" "0,0")
16587 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16588 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16589 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16590 [(set (attr "type")
16591 (cond [(match_operand:XF 3 "mult_operator" "")
16592 (const_string "fmul")
16593 (match_operand:XF 3 "div_operator" "")
16594 (const_string "fdiv")
16596 (const_string "fop")))
16597 (set_attr "fp_int_src" "true")
16598 (set_attr "mode" "<MODE>")])
16600 (define_insn "*fop_xf_4_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f,f")
16602 (match_operator:XF 3 "binary_fp_operator"
16604 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16605 (match_operand:XF 2 "register_operand" "0,f")]))]
16607 "* return output_387_binary_op (insn, operands);"
16608 [(set (attr "type")
16609 (cond [(match_operand:XF 3 "mult_operator" "")
16610 (const_string "fmul")
16611 (match_operand:XF 3 "div_operator" "")
16612 (const_string "fdiv")
16614 (const_string "fop")))
16615 (set_attr "mode" "<MODE>")])
16617 (define_insn "*fop_xf_5_i387"
16618 [(set (match_operand:XF 0 "register_operand" "=f,f")
16619 (match_operator:XF 3 "binary_fp_operator"
16620 [(match_operand:XF 1 "register_operand" "0,f")
16622 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16624 "* return output_387_binary_op (insn, operands);"
16625 [(set (attr "type")
16626 (cond [(match_operand:XF 3 "mult_operator" "")
16627 (const_string "fmul")
16628 (match_operand:XF 3 "div_operator" "")
16629 (const_string "fdiv")
16631 (const_string "fop")))
16632 (set_attr "mode" "<MODE>")])
16634 (define_insn "*fop_xf_6_i387"
16635 [(set (match_operand:XF 0 "register_operand" "=f,f")
16636 (match_operator:XF 3 "binary_fp_operator"
16638 (match_operand:MODEF 1 "register_operand" "0,f"))
16640 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16642 "* return output_387_binary_op (insn, operands);"
16643 [(set (attr "type")
16644 (cond [(match_operand:XF 3 "mult_operator" "")
16645 (const_string "fmul")
16646 (match_operand:XF 3 "div_operator" "")
16647 (const_string "fdiv")
16649 (const_string "fop")))
16650 (set_attr "mode" "<MODE>")])
16653 [(set (match_operand 0 "register_operand" "")
16654 (match_operator 3 "binary_fp_operator"
16655 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16656 (match_operand 2 "register_operand" "")]))]
16658 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16661 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16662 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16663 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16664 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16665 GET_MODE (operands[3]),
16668 ix86_free_from_memory (GET_MODE (operands[1]));
16673 [(set (match_operand 0 "register_operand" "")
16674 (match_operator 3 "binary_fp_operator"
16675 [(match_operand 1 "register_operand" "")
16676 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16678 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16681 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16682 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16683 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16684 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16685 GET_MODE (operands[3]),
16688 ix86_free_from_memory (GET_MODE (operands[2]));
16692 ;; FPU special functions.
16694 ;; This pattern implements a no-op XFmode truncation for
16695 ;; all fancy i386 XFmode math functions.
16697 (define_insn "truncxf<mode>2_i387_noop_unspec"
16698 [(set (match_operand:MODEF 0 "register_operand" "=f")
16699 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16700 UNSPEC_TRUNC_NOOP))]
16701 "TARGET_USE_FANCY_MATH_387"
16702 "* return output_387_reg_move (insn, operands);"
16703 [(set_attr "type" "fmov")
16704 (set_attr "mode" "<MODE>")])
16706 (define_insn "sqrtxf2"
16707 [(set (match_operand:XF 0 "register_operand" "=f")
16708 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16709 "TARGET_USE_FANCY_MATH_387"
16711 [(set_attr "type" "fpspc")
16712 (set_attr "mode" "XF")
16713 (set_attr "athlon_decode" "direct")
16714 (set_attr "amdfam10_decode" "direct")])
16716 (define_insn "sqrt_extend<mode>xf2_i387"
16717 [(set (match_operand:XF 0 "register_operand" "=f")
16720 (match_operand:MODEF 1 "register_operand" "0"))))]
16721 "TARGET_USE_FANCY_MATH_387"
16723 [(set_attr "type" "fpspc")
16724 (set_attr "mode" "XF")
16725 (set_attr "athlon_decode" "direct")
16726 (set_attr "amdfam10_decode" "direct")])
16728 (define_insn "*rsqrtsf2_sse"
16729 [(set (match_operand:SF 0 "register_operand" "=x")
16730 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16733 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16734 [(set_attr "type" "sse")
16735 (set_attr "prefix" "maybe_vex")
16736 (set_attr "mode" "SF")])
16738 (define_expand "rsqrtsf2"
16739 [(set (match_operand:SF 0 "register_operand" "")
16740 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16744 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16748 (define_insn "*sqrt<mode>2_sse"
16749 [(set (match_operand:MODEF 0 "register_operand" "=x")
16751 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16752 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16753 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16754 [(set_attr "type" "sse")
16755 (set_attr "prefix" "maybe_vex")
16756 (set_attr "mode" "<MODE>")
16757 (set_attr "athlon_decode" "*")
16758 (set_attr "amdfam10_decode" "*")])
16760 (define_expand "sqrt<mode>2"
16761 [(set (match_operand:MODEF 0 "register_operand" "")
16763 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16764 "TARGET_USE_FANCY_MATH_387
16765 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16767 if (<MODE>mode == SFmode
16768 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16769 && flag_finite_math_only && !flag_trapping_math
16770 && flag_unsafe_math_optimizations)
16772 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16776 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16778 rtx op0 = gen_reg_rtx (XFmode);
16779 rtx op1 = force_reg (<MODE>mode, operands[1]);
16781 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16782 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16787 (define_insn "fpremxf4_i387"
16788 [(set (match_operand:XF 0 "register_operand" "=f")
16789 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16790 (match_operand:XF 3 "register_operand" "1")]
16792 (set (match_operand:XF 1 "register_operand" "=u")
16793 (unspec:XF [(match_dup 2) (match_dup 3)]
16795 (set (reg:CCFP FPSR_REG)
16796 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16798 "TARGET_USE_FANCY_MATH_387"
16800 [(set_attr "type" "fpspc")
16801 (set_attr "mode" "XF")])
16803 (define_expand "fmodxf3"
16804 [(use (match_operand:XF 0 "register_operand" ""))
16805 (use (match_operand:XF 1 "general_operand" ""))
16806 (use (match_operand:XF 2 "general_operand" ""))]
16807 "TARGET_USE_FANCY_MATH_387"
16809 rtx label = gen_label_rtx ();
16811 rtx op1 = gen_reg_rtx (XFmode);
16812 rtx op2 = gen_reg_rtx (XFmode);
16814 emit_move_insn (op2, operands[2]);
16815 emit_move_insn (op1, operands[1]);
16817 emit_label (label);
16818 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16819 ix86_emit_fp_unordered_jump (label);
16820 LABEL_NUSES (label) = 1;
16822 emit_move_insn (operands[0], op1);
16826 (define_expand "fmod<mode>3"
16827 [(use (match_operand:MODEF 0 "register_operand" ""))
16828 (use (match_operand:MODEF 1 "general_operand" ""))
16829 (use (match_operand:MODEF 2 "general_operand" ""))]
16830 "TARGET_USE_FANCY_MATH_387"
16832 rtx label = gen_label_rtx ();
16834 rtx op1 = gen_reg_rtx (XFmode);
16835 rtx op2 = gen_reg_rtx (XFmode);
16837 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16840 emit_label (label);
16841 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16842 ix86_emit_fp_unordered_jump (label);
16843 LABEL_NUSES (label) = 1;
16845 /* Truncate the result properly for strict SSE math. */
16846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16847 && !TARGET_MIX_SSE_I387)
16848 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16850 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16855 (define_insn "fprem1xf4_i387"
16856 [(set (match_operand:XF 0 "register_operand" "=f")
16857 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16858 (match_operand:XF 3 "register_operand" "1")]
16860 (set (match_operand:XF 1 "register_operand" "=u")
16861 (unspec:XF [(match_dup 2) (match_dup 3)]
16863 (set (reg:CCFP FPSR_REG)
16864 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16866 "TARGET_USE_FANCY_MATH_387"
16868 [(set_attr "type" "fpspc")
16869 (set_attr "mode" "XF")])
16871 (define_expand "remainderxf3"
16872 [(use (match_operand:XF 0 "register_operand" ""))
16873 (use (match_operand:XF 1 "general_operand" ""))
16874 (use (match_operand:XF 2 "general_operand" ""))]
16875 "TARGET_USE_FANCY_MATH_387"
16877 rtx label = gen_label_rtx ();
16879 rtx op1 = gen_reg_rtx (XFmode);
16880 rtx op2 = gen_reg_rtx (XFmode);
16882 emit_move_insn (op2, operands[2]);
16883 emit_move_insn (op1, operands[1]);
16885 emit_label (label);
16886 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16887 ix86_emit_fp_unordered_jump (label);
16888 LABEL_NUSES (label) = 1;
16890 emit_move_insn (operands[0], op1);
16894 (define_expand "remainder<mode>3"
16895 [(use (match_operand:MODEF 0 "register_operand" ""))
16896 (use (match_operand:MODEF 1 "general_operand" ""))
16897 (use (match_operand:MODEF 2 "general_operand" ""))]
16898 "TARGET_USE_FANCY_MATH_387"
16900 rtx label = gen_label_rtx ();
16902 rtx op1 = gen_reg_rtx (XFmode);
16903 rtx op2 = gen_reg_rtx (XFmode);
16905 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16908 emit_label (label);
16910 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16911 ix86_emit_fp_unordered_jump (label);
16912 LABEL_NUSES (label) = 1;
16914 /* Truncate the result properly for strict SSE math. */
16915 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16916 && !TARGET_MIX_SSE_I387)
16917 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16919 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16924 (define_insn "*sinxf2_i387"
16925 [(set (match_operand:XF 0 "register_operand" "=f")
16926 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && flag_unsafe_math_optimizations"
16930 [(set_attr "type" "fpspc")
16931 (set_attr "mode" "XF")])
16933 (define_insn "*sin_extend<mode>xf2_i387"
16934 [(set (match_operand:XF 0 "register_operand" "=f")
16935 (unspec:XF [(float_extend:XF
16936 (match_operand:MODEF 1 "register_operand" "0"))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16940 || TARGET_MIX_SSE_I387)
16941 && flag_unsafe_math_optimizations"
16943 [(set_attr "type" "fpspc")
16944 (set_attr "mode" "XF")])
16946 (define_insn "*cosxf2_i387"
16947 [(set (match_operand:XF 0 "register_operand" "=f")
16948 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations"
16952 [(set_attr "type" "fpspc")
16953 (set_attr "mode" "XF")])
16955 (define_insn "*cos_extend<mode>xf2_i387"
16956 [(set (match_operand:XF 0 "register_operand" "=f")
16957 (unspec:XF [(float_extend:XF
16958 (match_operand:MODEF 1 "register_operand" "0"))]
16960 "TARGET_USE_FANCY_MATH_387
16961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16962 || TARGET_MIX_SSE_I387)
16963 && flag_unsafe_math_optimizations"
16965 [(set_attr "type" "fpspc")
16966 (set_attr "mode" "XF")])
16968 ;; When sincos pattern is defined, sin and cos builtin functions will be
16969 ;; expanded to sincos pattern with one of its outputs left unused.
16970 ;; CSE pass will figure out if two sincos patterns can be combined,
16971 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16972 ;; depending on the unused output.
16974 (define_insn "sincosxf3"
16975 [(set (match_operand:XF 0 "register_operand" "=f")
16976 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16977 UNSPEC_SINCOS_COS))
16978 (set (match_operand:XF 1 "register_operand" "=u")
16979 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && flag_unsafe_math_optimizations"
16983 [(set_attr "type" "fpspc")
16984 (set_attr "mode" "XF")])
16987 [(set (match_operand:XF 0 "register_operand" "")
16988 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16989 UNSPEC_SINCOS_COS))
16990 (set (match_operand:XF 1 "register_operand" "")
16991 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16992 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16993 && !(reload_completed || reload_in_progress)"
16994 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16998 [(set (match_operand:XF 0 "register_operand" "")
16999 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17000 UNSPEC_SINCOS_COS))
17001 (set (match_operand:XF 1 "register_operand" "")
17002 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17003 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17004 && !(reload_completed || reload_in_progress)"
17005 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17008 (define_insn "sincos_extend<mode>xf3_i387"
17009 [(set (match_operand:XF 0 "register_operand" "=f")
17010 (unspec:XF [(float_extend:XF
17011 (match_operand:MODEF 2 "register_operand" "0"))]
17012 UNSPEC_SINCOS_COS))
17013 (set (match_operand:XF 1 "register_operand" "=u")
17014 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015 "TARGET_USE_FANCY_MATH_387
17016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017 || TARGET_MIX_SSE_I387)
17018 && flag_unsafe_math_optimizations"
17020 [(set_attr "type" "fpspc")
17021 (set_attr "mode" "XF")])
17024 [(set (match_operand:XF 0 "register_operand" "")
17025 (unspec:XF [(float_extend:XF
17026 (match_operand:MODEF 2 "register_operand" ""))]
17027 UNSPEC_SINCOS_COS))
17028 (set (match_operand:XF 1 "register_operand" "")
17029 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17030 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17031 && !(reload_completed || reload_in_progress)"
17032 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17036 [(set (match_operand:XF 0 "register_operand" "")
17037 (unspec:XF [(float_extend:XF
17038 (match_operand:MODEF 2 "register_operand" ""))]
17039 UNSPEC_SINCOS_COS))
17040 (set (match_operand:XF 1 "register_operand" "")
17041 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17042 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17043 && !(reload_completed || reload_in_progress)"
17044 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17047 (define_expand "sincos<mode>3"
17048 [(use (match_operand:MODEF 0 "register_operand" ""))
17049 (use (match_operand:MODEF 1 "register_operand" ""))
17050 (use (match_operand:MODEF 2 "register_operand" ""))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053 || TARGET_MIX_SSE_I387)
17054 && flag_unsafe_math_optimizations"
17056 rtx op0 = gen_reg_rtx (XFmode);
17057 rtx op1 = gen_reg_rtx (XFmode);
17059 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17065 (define_insn "fptanxf4_i387"
17066 [(set (match_operand:XF 0 "register_operand" "=f")
17067 (match_operand:XF 3 "const_double_operand" "F"))
17068 (set (match_operand:XF 1 "register_operand" "=u")
17069 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations
17073 && standard_80387_constant_p (operands[3]) == 2"
17075 [(set_attr "type" "fpspc")
17076 (set_attr "mode" "XF")])
17078 (define_insn "fptan_extend<mode>xf4_i387"
17079 [(set (match_operand:MODEF 0 "register_operand" "=f")
17080 (match_operand:MODEF 3 "const_double_operand" "F"))
17081 (set (match_operand:XF 1 "register_operand" "=u")
17082 (unspec:XF [(float_extend:XF
17083 (match_operand:MODEF 2 "register_operand" "0"))]
17085 "TARGET_USE_FANCY_MATH_387
17086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17087 || TARGET_MIX_SSE_I387)
17088 && flag_unsafe_math_optimizations
17089 && standard_80387_constant_p (operands[3]) == 2"
17091 [(set_attr "type" "fpspc")
17092 (set_attr "mode" "XF")])
17094 (define_expand "tanxf2"
17095 [(use (match_operand:XF 0 "register_operand" ""))
17096 (use (match_operand:XF 1 "register_operand" ""))]
17097 "TARGET_USE_FANCY_MATH_387
17098 && flag_unsafe_math_optimizations"
17100 rtx one = gen_reg_rtx (XFmode);
17101 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17103 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17107 (define_expand "tan<mode>2"
17108 [(use (match_operand:MODEF 0 "register_operand" ""))
17109 (use (match_operand:MODEF 1 "register_operand" ""))]
17110 "TARGET_USE_FANCY_MATH_387
17111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17112 || TARGET_MIX_SSE_I387)
17113 && flag_unsafe_math_optimizations"
17115 rtx op0 = gen_reg_rtx (XFmode);
17117 rtx one = gen_reg_rtx (<MODE>mode);
17118 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17120 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17121 operands[1], op2));
17122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17126 (define_insn "*fpatanxf3_i387"
17127 [(set (match_operand:XF 0 "register_operand" "=f")
17128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17129 (match_operand:XF 2 "register_operand" "u")]
17131 (clobber (match_scratch:XF 3 "=2"))]
17132 "TARGET_USE_FANCY_MATH_387
17133 && flag_unsafe_math_optimizations"
17135 [(set_attr "type" "fpspc")
17136 (set_attr "mode" "XF")])
17138 (define_insn "fpatan_extend<mode>xf3_i387"
17139 [(set (match_operand:XF 0 "register_operand" "=f")
17140 (unspec:XF [(float_extend:XF
17141 (match_operand:MODEF 1 "register_operand" "0"))
17143 (match_operand:MODEF 2 "register_operand" "u"))]
17145 (clobber (match_scratch:XF 3 "=2"))]
17146 "TARGET_USE_FANCY_MATH_387
17147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148 || TARGET_MIX_SSE_I387)
17149 && flag_unsafe_math_optimizations"
17151 [(set_attr "type" "fpspc")
17152 (set_attr "mode" "XF")])
17154 (define_expand "atan2xf3"
17155 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17156 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17157 (match_operand:XF 1 "register_operand" "")]
17159 (clobber (match_scratch:XF 3 ""))])]
17160 "TARGET_USE_FANCY_MATH_387
17161 && flag_unsafe_math_optimizations"
17164 (define_expand "atan2<mode>3"
17165 [(use (match_operand:MODEF 0 "register_operand" ""))
17166 (use (match_operand:MODEF 1 "register_operand" ""))
17167 (use (match_operand:MODEF 2 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17170 || TARGET_MIX_SSE_I387)
17171 && flag_unsafe_math_optimizations"
17173 rtx op0 = gen_reg_rtx (XFmode);
17175 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17176 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17180 (define_expand "atanxf2"
17181 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17182 (unspec:XF [(match_dup 2)
17183 (match_operand:XF 1 "register_operand" "")]
17185 (clobber (match_scratch:XF 3 ""))])]
17186 "TARGET_USE_FANCY_MATH_387
17187 && flag_unsafe_math_optimizations"
17189 operands[2] = gen_reg_rtx (XFmode);
17190 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17193 (define_expand "atan<mode>2"
17194 [(use (match_operand:MODEF 0 "register_operand" ""))
17195 (use (match_operand:MODEF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198 || TARGET_MIX_SSE_I387)
17199 && flag_unsafe_math_optimizations"
17201 rtx op0 = gen_reg_rtx (XFmode);
17203 rtx op2 = gen_reg_rtx (<MODE>mode);
17204 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17206 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17211 (define_expand "asinxf2"
17212 [(set (match_dup 2)
17213 (mult:XF (match_operand:XF 1 "register_operand" "")
17215 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17216 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17217 (parallel [(set (match_operand:XF 0 "register_operand" "")
17218 (unspec:XF [(match_dup 5) (match_dup 1)]
17220 (clobber (match_scratch:XF 6 ""))])]
17221 "TARGET_USE_FANCY_MATH_387
17222 && flag_unsafe_math_optimizations"
17226 if (optimize_insn_for_size_p ())
17229 for (i = 2; i < 6; i++)
17230 operands[i] = gen_reg_rtx (XFmode);
17232 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17235 (define_expand "asin<mode>2"
17236 [(use (match_operand:MODEF 0 "register_operand" ""))
17237 (use (match_operand:MODEF 1 "general_operand" ""))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17240 || TARGET_MIX_SSE_I387)
17241 && flag_unsafe_math_optimizations"
17243 rtx op0 = gen_reg_rtx (XFmode);
17244 rtx op1 = gen_reg_rtx (XFmode);
17246 if (optimize_insn_for_size_p ())
17249 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17250 emit_insn (gen_asinxf2 (op0, op1));
17251 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17255 (define_expand "acosxf2"
17256 [(set (match_dup 2)
17257 (mult:XF (match_operand:XF 1 "register_operand" "")
17259 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17260 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17261 (parallel [(set (match_operand:XF 0 "register_operand" "")
17262 (unspec:XF [(match_dup 1) (match_dup 5)]
17264 (clobber (match_scratch:XF 6 ""))])]
17265 "TARGET_USE_FANCY_MATH_387
17266 && flag_unsafe_math_optimizations"
17270 if (optimize_insn_for_size_p ())
17273 for (i = 2; i < 6; i++)
17274 operands[i] = gen_reg_rtx (XFmode);
17276 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17279 (define_expand "acos<mode>2"
17280 [(use (match_operand:MODEF 0 "register_operand" ""))
17281 (use (match_operand:MODEF 1 "general_operand" ""))]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284 || TARGET_MIX_SSE_I387)
17285 && flag_unsafe_math_optimizations"
17287 rtx op0 = gen_reg_rtx (XFmode);
17288 rtx op1 = gen_reg_rtx (XFmode);
17290 if (optimize_insn_for_size_p ())
17293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294 emit_insn (gen_acosxf2 (op0, op1));
17295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17299 (define_insn "fyl2xxf3_i387"
17300 [(set (match_operand:XF 0 "register_operand" "=f")
17301 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17302 (match_operand:XF 2 "register_operand" "u")]
17304 (clobber (match_scratch:XF 3 "=2"))]
17305 "TARGET_USE_FANCY_MATH_387
17306 && flag_unsafe_math_optimizations"
17308 [(set_attr "type" "fpspc")
17309 (set_attr "mode" "XF")])
17311 (define_insn "fyl2x_extend<mode>xf3_i387"
17312 [(set (match_operand:XF 0 "register_operand" "=f")
17313 (unspec:XF [(float_extend:XF
17314 (match_operand:MODEF 1 "register_operand" "0"))
17315 (match_operand:XF 2 "register_operand" "u")]
17317 (clobber (match_scratch:XF 3 "=2"))]
17318 "TARGET_USE_FANCY_MATH_387
17319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17320 || TARGET_MIX_SSE_I387)
17321 && flag_unsafe_math_optimizations"
17323 [(set_attr "type" "fpspc")
17324 (set_attr "mode" "XF")])
17326 (define_expand "logxf2"
17327 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329 (match_dup 2)] UNSPEC_FYL2X))
17330 (clobber (match_scratch:XF 3 ""))])]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations"
17334 operands[2] = gen_reg_rtx (XFmode);
17335 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17338 (define_expand "log<mode>2"
17339 [(use (match_operand:MODEF 0 "register_operand" ""))
17340 (use (match_operand:MODEF 1 "register_operand" ""))]
17341 "TARGET_USE_FANCY_MATH_387
17342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343 || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations"
17346 rtx op0 = gen_reg_rtx (XFmode);
17348 rtx op2 = gen_reg_rtx (XFmode);
17349 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17351 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17356 (define_expand "log10xf2"
17357 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359 (match_dup 2)] UNSPEC_FYL2X))
17360 (clobber (match_scratch:XF 3 ""))])]
17361 "TARGET_USE_FANCY_MATH_387
17362 && flag_unsafe_math_optimizations"
17364 operands[2] = gen_reg_rtx (XFmode);
17365 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17368 (define_expand "log10<mode>2"
17369 [(use (match_operand:MODEF 0 "register_operand" ""))
17370 (use (match_operand:MODEF 1 "register_operand" ""))]
17371 "TARGET_USE_FANCY_MATH_387
17372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373 || TARGET_MIX_SSE_I387)
17374 && flag_unsafe_math_optimizations"
17376 rtx op0 = gen_reg_rtx (XFmode);
17378 rtx op2 = gen_reg_rtx (XFmode);
17379 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17381 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17386 (define_expand "log2xf2"
17387 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17388 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17389 (match_dup 2)] UNSPEC_FYL2X))
17390 (clobber (match_scratch:XF 3 ""))])]
17391 "TARGET_USE_FANCY_MATH_387
17392 && flag_unsafe_math_optimizations"
17394 operands[2] = gen_reg_rtx (XFmode);
17395 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17398 (define_expand "log2<mode>2"
17399 [(use (match_operand:MODEF 0 "register_operand" ""))
17400 (use (match_operand:MODEF 1 "register_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403 || TARGET_MIX_SSE_I387)
17404 && flag_unsafe_math_optimizations"
17406 rtx op0 = gen_reg_rtx (XFmode);
17408 rtx op2 = gen_reg_rtx (XFmode);
17409 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17411 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17416 (define_insn "fyl2xp1xf3_i387"
17417 [(set (match_operand:XF 0 "register_operand" "=f")
17418 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17419 (match_operand:XF 2 "register_operand" "u")]
17421 (clobber (match_scratch:XF 3 "=2"))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && flag_unsafe_math_optimizations"
17425 [(set_attr "type" "fpspc")
17426 (set_attr "mode" "XF")])
17428 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17429 [(set (match_operand:XF 0 "register_operand" "=f")
17430 (unspec:XF [(float_extend:XF
17431 (match_operand:MODEF 1 "register_operand" "0"))
17432 (match_operand:XF 2 "register_operand" "u")]
17434 (clobber (match_scratch:XF 3 "=2"))]
17435 "TARGET_USE_FANCY_MATH_387
17436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437 || TARGET_MIX_SSE_I387)
17438 && flag_unsafe_math_optimizations"
17440 [(set_attr "type" "fpspc")
17441 (set_attr "mode" "XF")])
17443 (define_expand "log1pxf2"
17444 [(use (match_operand:XF 0 "register_operand" ""))
17445 (use (match_operand:XF 1 "register_operand" ""))]
17446 "TARGET_USE_FANCY_MATH_387
17447 && flag_unsafe_math_optimizations"
17449 if (optimize_insn_for_size_p ())
17452 ix86_emit_i387_log1p (operands[0], operands[1]);
17456 (define_expand "log1p<mode>2"
17457 [(use (match_operand:MODEF 0 "register_operand" ""))
17458 (use (match_operand:MODEF 1 "register_operand" ""))]
17459 "TARGET_USE_FANCY_MATH_387
17460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17461 || TARGET_MIX_SSE_I387)
17462 && flag_unsafe_math_optimizations"
17466 if (optimize_insn_for_size_p ())
17469 op0 = gen_reg_rtx (XFmode);
17471 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17473 ix86_emit_i387_log1p (op0, operands[1]);
17474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17478 (define_insn "fxtractxf3_i387"
17479 [(set (match_operand:XF 0 "register_operand" "=f")
17480 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17481 UNSPEC_XTRACT_FRACT))
17482 (set (match_operand:XF 1 "register_operand" "=u")
17483 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17484 "TARGET_USE_FANCY_MATH_387
17485 && flag_unsafe_math_optimizations"
17487 [(set_attr "type" "fpspc")
17488 (set_attr "mode" "XF")])
17490 (define_insn "fxtract_extend<mode>xf3_i387"
17491 [(set (match_operand:XF 0 "register_operand" "=f")
17492 (unspec:XF [(float_extend:XF
17493 (match_operand:MODEF 2 "register_operand" "0"))]
17494 UNSPEC_XTRACT_FRACT))
17495 (set (match_operand:XF 1 "register_operand" "=u")
17496 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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"
17502 [(set_attr "type" "fpspc")
17503 (set_attr "mode" "XF")])
17505 (define_expand "logbxf2"
17506 [(parallel [(set (match_dup 2)
17507 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17508 UNSPEC_XTRACT_FRACT))
17509 (set (match_operand:XF 0 "register_operand" "")
17510 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17511 "TARGET_USE_FANCY_MATH_387
17512 && flag_unsafe_math_optimizations"
17514 operands[2] = gen_reg_rtx (XFmode);
17517 (define_expand "logb<mode>2"
17518 [(use (match_operand:MODEF 0 "register_operand" ""))
17519 (use (match_operand:MODEF 1 "register_operand" ""))]
17520 "TARGET_USE_FANCY_MATH_387
17521 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17522 || TARGET_MIX_SSE_I387)
17523 && flag_unsafe_math_optimizations"
17525 rtx op0 = gen_reg_rtx (XFmode);
17526 rtx op1 = gen_reg_rtx (XFmode);
17528 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17529 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17533 (define_expand "ilogbxf2"
17534 [(use (match_operand:SI 0 "register_operand" ""))
17535 (use (match_operand:XF 1 "register_operand" ""))]
17536 "TARGET_USE_FANCY_MATH_387
17537 && flag_unsafe_math_optimizations"
17541 if (optimize_insn_for_size_p ())
17544 op0 = gen_reg_rtx (XFmode);
17545 op1 = gen_reg_rtx (XFmode);
17547 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17548 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17552 (define_expand "ilogb<mode>2"
17553 [(use (match_operand:SI 0 "register_operand" ""))
17554 (use (match_operand:MODEF 1 "register_operand" ""))]
17555 "TARGET_USE_FANCY_MATH_387
17556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17557 || TARGET_MIX_SSE_I387)
17558 && flag_unsafe_math_optimizations"
17562 if (optimize_insn_for_size_p ())
17565 op0 = gen_reg_rtx (XFmode);
17566 op1 = gen_reg_rtx (XFmode);
17568 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17569 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17573 (define_insn "*f2xm1xf2_i387"
17574 [(set (match_operand:XF 0 "register_operand" "=f")
17575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17577 "TARGET_USE_FANCY_MATH_387
17578 && flag_unsafe_math_optimizations"
17580 [(set_attr "type" "fpspc")
17581 (set_attr "mode" "XF")])
17583 (define_insn "*fscalexf4_i387"
17584 [(set (match_operand:XF 0 "register_operand" "=f")
17585 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17586 (match_operand:XF 3 "register_operand" "1")]
17587 UNSPEC_FSCALE_FRACT))
17588 (set (match_operand:XF 1 "register_operand" "=u")
17589 (unspec:XF [(match_dup 2) (match_dup 3)]
17590 UNSPEC_FSCALE_EXP))]
17591 "TARGET_USE_FANCY_MATH_387
17592 && flag_unsafe_math_optimizations"
17594 [(set_attr "type" "fpspc")
17595 (set_attr "mode" "XF")])
17597 (define_expand "expNcorexf3"
17598 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17599 (match_operand:XF 2 "register_operand" "")))
17600 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17601 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17602 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17603 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17604 (parallel [(set (match_operand:XF 0 "register_operand" "")
17605 (unspec:XF [(match_dup 8) (match_dup 4)]
17606 UNSPEC_FSCALE_FRACT))
17608 (unspec:XF [(match_dup 8) (match_dup 4)]
17609 UNSPEC_FSCALE_EXP))])]
17610 "TARGET_USE_FANCY_MATH_387
17611 && flag_unsafe_math_optimizations"
17615 if (optimize_insn_for_size_p ())
17618 for (i = 3; i < 10; i++)
17619 operands[i] = gen_reg_rtx (XFmode);
17621 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17624 (define_expand "expxf2"
17625 [(use (match_operand:XF 0 "register_operand" ""))
17626 (use (match_operand:XF 1 "register_operand" ""))]
17627 "TARGET_USE_FANCY_MATH_387
17628 && flag_unsafe_math_optimizations"
17632 if (optimize_insn_for_size_p ())
17635 op2 = gen_reg_rtx (XFmode);
17636 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17638 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17642 (define_expand "exp<mode>2"
17643 [(use (match_operand:MODEF 0 "register_operand" ""))
17644 (use (match_operand:MODEF 1 "general_operand" ""))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17647 || TARGET_MIX_SSE_I387)
17648 && flag_unsafe_math_optimizations"
17652 if (optimize_insn_for_size_p ())
17655 op0 = gen_reg_rtx (XFmode);
17656 op1 = gen_reg_rtx (XFmode);
17658 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17659 emit_insn (gen_expxf2 (op0, op1));
17660 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17664 (define_expand "exp10xf2"
17665 [(use (match_operand:XF 0 "register_operand" ""))
17666 (use (match_operand:XF 1 "register_operand" ""))]
17667 "TARGET_USE_FANCY_MATH_387
17668 && flag_unsafe_math_optimizations"
17672 if (optimize_insn_for_size_p ())
17675 op2 = gen_reg_rtx (XFmode);
17676 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17678 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17682 (define_expand "exp10<mode>2"
17683 [(use (match_operand:MODEF 0 "register_operand" ""))
17684 (use (match_operand:MODEF 1 "general_operand" ""))]
17685 "TARGET_USE_FANCY_MATH_387
17686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17687 || TARGET_MIX_SSE_I387)
17688 && flag_unsafe_math_optimizations"
17692 if (optimize_insn_for_size_p ())
17695 op0 = gen_reg_rtx (XFmode);
17696 op1 = gen_reg_rtx (XFmode);
17698 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17699 emit_insn (gen_exp10xf2 (op0, op1));
17700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17704 (define_expand "exp2xf2"
17705 [(use (match_operand:XF 0 "register_operand" ""))
17706 (use (match_operand:XF 1 "register_operand" ""))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && flag_unsafe_math_optimizations"
17712 if (optimize_insn_for_size_p ())
17715 op2 = gen_reg_rtx (XFmode);
17716 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17718 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17722 (define_expand "exp2<mode>2"
17723 [(use (match_operand:MODEF 0 "register_operand" ""))
17724 (use (match_operand:MODEF 1 "general_operand" ""))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17727 || TARGET_MIX_SSE_I387)
17728 && flag_unsafe_math_optimizations"
17732 if (optimize_insn_for_size_p ())
17735 op0 = gen_reg_rtx (XFmode);
17736 op1 = gen_reg_rtx (XFmode);
17738 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17739 emit_insn (gen_exp2xf2 (op0, op1));
17740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17744 (define_expand "expm1xf2"
17745 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17747 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17748 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17749 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17750 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17751 (parallel [(set (match_dup 7)
17752 (unspec:XF [(match_dup 6) (match_dup 4)]
17753 UNSPEC_FSCALE_FRACT))
17755 (unspec:XF [(match_dup 6) (match_dup 4)]
17756 UNSPEC_FSCALE_EXP))])
17757 (parallel [(set (match_dup 10)
17758 (unspec:XF [(match_dup 9) (match_dup 8)]
17759 UNSPEC_FSCALE_FRACT))
17760 (set (match_dup 11)
17761 (unspec:XF [(match_dup 9) (match_dup 8)]
17762 UNSPEC_FSCALE_EXP))])
17763 (set (match_dup 12) (minus:XF (match_dup 10)
17764 (float_extend:XF (match_dup 13))))
17765 (set (match_operand:XF 0 "register_operand" "")
17766 (plus:XF (match_dup 12) (match_dup 7)))]
17767 "TARGET_USE_FANCY_MATH_387
17768 && flag_unsafe_math_optimizations"
17772 if (optimize_insn_for_size_p ())
17775 for (i = 2; i < 13; i++)
17776 operands[i] = gen_reg_rtx (XFmode);
17779 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17781 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17784 (define_expand "expm1<mode>2"
17785 [(use (match_operand:MODEF 0 "register_operand" ""))
17786 (use (match_operand:MODEF 1 "general_operand" ""))]
17787 "TARGET_USE_FANCY_MATH_387
17788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17789 || TARGET_MIX_SSE_I387)
17790 && flag_unsafe_math_optimizations"
17794 if (optimize_insn_for_size_p ())
17797 op0 = gen_reg_rtx (XFmode);
17798 op1 = gen_reg_rtx (XFmode);
17800 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17801 emit_insn (gen_expm1xf2 (op0, op1));
17802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17806 (define_expand "ldexpxf3"
17807 [(set (match_dup 3)
17808 (float:XF (match_operand:SI 2 "register_operand" "")))
17809 (parallel [(set (match_operand:XF 0 " register_operand" "")
17810 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17812 UNSPEC_FSCALE_FRACT))
17814 (unspec:XF [(match_dup 1) (match_dup 3)]
17815 UNSPEC_FSCALE_EXP))])]
17816 "TARGET_USE_FANCY_MATH_387
17817 && flag_unsafe_math_optimizations"
17819 if (optimize_insn_for_size_p ())
17822 operands[3] = gen_reg_rtx (XFmode);
17823 operands[4] = gen_reg_rtx (XFmode);
17826 (define_expand "ldexp<mode>3"
17827 [(use (match_operand:MODEF 0 "register_operand" ""))
17828 (use (match_operand:MODEF 1 "general_operand" ""))
17829 (use (match_operand:SI 2 "register_operand" ""))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832 || TARGET_MIX_SSE_I387)
17833 && flag_unsafe_math_optimizations"
17837 if (optimize_insn_for_size_p ())
17840 op0 = gen_reg_rtx (XFmode);
17841 op1 = gen_reg_rtx (XFmode);
17843 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17844 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17849 (define_expand "scalbxf3"
17850 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17851 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17852 (match_operand:XF 2 "register_operand" "")]
17853 UNSPEC_FSCALE_FRACT))
17855 (unspec:XF [(match_dup 1) (match_dup 2)]
17856 UNSPEC_FSCALE_EXP))])]
17857 "TARGET_USE_FANCY_MATH_387
17858 && flag_unsafe_math_optimizations"
17860 if (optimize_insn_for_size_p ())
17863 operands[3] = gen_reg_rtx (XFmode);
17866 (define_expand "scalb<mode>3"
17867 [(use (match_operand:MODEF 0 "register_operand" ""))
17868 (use (match_operand:MODEF 1 "general_operand" ""))
17869 (use (match_operand:MODEF 2 "register_operand" ""))]
17870 "TARGET_USE_FANCY_MATH_387
17871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17872 || TARGET_MIX_SSE_I387)
17873 && flag_unsafe_math_optimizations"
17877 if (optimize_insn_for_size_p ())
17880 op0 = gen_reg_rtx (XFmode);
17881 op1 = gen_reg_rtx (XFmode);
17882 op2 = gen_reg_rtx (XFmode);
17884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17885 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17886 emit_insn (gen_scalbxf3 (op0, op1, op2));
17887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17892 (define_insn "sse4_1_round<mode>2"
17893 [(set (match_operand:MODEF 0 "register_operand" "=x")
17894 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17895 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17898 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17899 [(set_attr "type" "ssecvt")
17900 (set_attr "prefix_extra" "1")
17901 (set_attr "prefix" "maybe_vex")
17902 (set_attr "mode" "<MODE>")])
17904 (define_insn "rintxf2"
17905 [(set (match_operand:XF 0 "register_operand" "=f")
17906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17908 "TARGET_USE_FANCY_MATH_387
17909 && flag_unsafe_math_optimizations"
17911 [(set_attr "type" "fpspc")
17912 (set_attr "mode" "XF")])
17914 (define_expand "rint<mode>2"
17915 [(use (match_operand:MODEF 0 "register_operand" ""))
17916 (use (match_operand:MODEF 1 "register_operand" ""))]
17917 "(TARGET_USE_FANCY_MATH_387
17918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17919 || TARGET_MIX_SSE_I387)
17920 && flag_unsafe_math_optimizations)
17921 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922 && !flag_trapping_math)"
17924 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17925 && !flag_trapping_math)
17927 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17930 emit_insn (gen_sse4_1_round<mode>2
17931 (operands[0], operands[1], GEN_INT (0x04)));
17933 ix86_expand_rint (operand0, operand1);
17937 rtx op0 = gen_reg_rtx (XFmode);
17938 rtx op1 = gen_reg_rtx (XFmode);
17940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17941 emit_insn (gen_rintxf2 (op0, op1));
17943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17948 (define_expand "round<mode>2"
17949 [(match_operand:MODEF 0 "register_operand" "")
17950 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17951 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952 && !flag_trapping_math && !flag_rounding_math"
17954 if (optimize_insn_for_size_p ())
17956 if (TARGET_64BIT || (<MODE>mode != DFmode))
17957 ix86_expand_round (operand0, operand1);
17959 ix86_expand_rounddf_32 (operand0, operand1);
17963 (define_insn_and_split "*fistdi2_1"
17964 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17965 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17967 "TARGET_USE_FANCY_MATH_387
17968 && !(reload_completed || reload_in_progress)"
17973 if (memory_operand (operands[0], VOIDmode))
17974 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17977 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17978 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17983 [(set_attr "type" "fpspc")
17984 (set_attr "mode" "DI")])
17986 (define_insn "fistdi2"
17987 [(set (match_operand:DI 0 "memory_operand" "=m")
17988 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17990 (clobber (match_scratch:XF 2 "=&1f"))]
17991 "TARGET_USE_FANCY_MATH_387"
17992 "* return output_fix_trunc (insn, operands, 0);"
17993 [(set_attr "type" "fpspc")
17994 (set_attr "mode" "DI")])
17996 (define_insn "fistdi2_with_temp"
17997 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17998 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18000 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18001 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18002 "TARGET_USE_FANCY_MATH_387"
18004 [(set_attr "type" "fpspc")
18005 (set_attr "mode" "DI")])
18008 [(set (match_operand:DI 0 "register_operand" "")
18009 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18011 (clobber (match_operand:DI 2 "memory_operand" ""))
18012 (clobber (match_scratch 3 ""))]
18014 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18015 (clobber (match_dup 3))])
18016 (set (match_dup 0) (match_dup 2))]
18020 [(set (match_operand:DI 0 "memory_operand" "")
18021 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18023 (clobber (match_operand:DI 2 "memory_operand" ""))
18024 (clobber (match_scratch 3 ""))]
18026 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18027 (clobber (match_dup 3))])]
18030 (define_insn_and_split "*fist<mode>2_1"
18031 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18032 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18034 "TARGET_USE_FANCY_MATH_387
18035 && !(reload_completed || reload_in_progress)"
18040 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18041 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18045 [(set_attr "type" "fpspc")
18046 (set_attr "mode" "<MODE>")])
18048 (define_insn "fist<mode>2"
18049 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18050 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18052 "TARGET_USE_FANCY_MATH_387"
18053 "* return output_fix_trunc (insn, operands, 0);"
18054 [(set_attr "type" "fpspc")
18055 (set_attr "mode" "<MODE>")])
18057 (define_insn "fist<mode>2_with_temp"
18058 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18059 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18061 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18062 "TARGET_USE_FANCY_MATH_387"
18064 [(set_attr "type" "fpspc")
18065 (set_attr "mode" "<MODE>")])
18068 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18069 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18071 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18073 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18074 (set (match_dup 0) (match_dup 2))]
18078 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18079 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18081 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18083 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18086 (define_expand "lrintxf<mode>2"
18087 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18088 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18090 "TARGET_USE_FANCY_MATH_387"
18093 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18094 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18095 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18096 UNSPEC_FIX_NOTRUNC))]
18097 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18098 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18101 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18102 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18103 (match_operand:MODEF 1 "register_operand" "")]
18104 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18105 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18106 && !flag_trapping_math && !flag_rounding_math"
18108 if (optimize_insn_for_size_p ())
18110 ix86_expand_lround (operand0, operand1);
18114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18115 (define_insn_and_split "frndintxf2_floor"
18116 [(set (match_operand:XF 0 "register_operand" "")
18117 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18118 UNSPEC_FRNDINT_FLOOR))
18119 (clobber (reg:CC FLAGS_REG))]
18120 "TARGET_USE_FANCY_MATH_387
18121 && flag_unsafe_math_optimizations
18122 && !(reload_completed || reload_in_progress)"
18127 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18129 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18130 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18132 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18133 operands[2], operands[3]));
18136 [(set_attr "type" "frndint")
18137 (set_attr "i387_cw" "floor")
18138 (set_attr "mode" "XF")])
18140 (define_insn "frndintxf2_floor_i387"
18141 [(set (match_operand:XF 0 "register_operand" "=f")
18142 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143 UNSPEC_FRNDINT_FLOOR))
18144 (use (match_operand:HI 2 "memory_operand" "m"))
18145 (use (match_operand:HI 3 "memory_operand" "m"))]
18146 "TARGET_USE_FANCY_MATH_387
18147 && flag_unsafe_math_optimizations"
18148 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18149 [(set_attr "type" "frndint")
18150 (set_attr "i387_cw" "floor")
18151 (set_attr "mode" "XF")])
18153 (define_expand "floorxf2"
18154 [(use (match_operand:XF 0 "register_operand" ""))
18155 (use (match_operand:XF 1 "register_operand" ""))]
18156 "TARGET_USE_FANCY_MATH_387
18157 && flag_unsafe_math_optimizations"
18159 if (optimize_insn_for_size_p ())
18161 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18165 (define_expand "floor<mode>2"
18166 [(use (match_operand:MODEF 0 "register_operand" ""))
18167 (use (match_operand:MODEF 1 "register_operand" ""))]
18168 "(TARGET_USE_FANCY_MATH_387
18169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18170 || TARGET_MIX_SSE_I387)
18171 && flag_unsafe_math_optimizations)
18172 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173 && !flag_trapping_math)"
18175 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18176 && !flag_trapping_math
18177 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18179 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18182 emit_insn (gen_sse4_1_round<mode>2
18183 (operands[0], operands[1], GEN_INT (0x01)));
18184 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18185 ix86_expand_floorceil (operand0, operand1, true);
18187 ix86_expand_floorceildf_32 (operand0, operand1, true);
18193 if (optimize_insn_for_size_p ())
18196 op0 = gen_reg_rtx (XFmode);
18197 op1 = gen_reg_rtx (XFmode);
18198 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18199 emit_insn (gen_frndintxf2_floor (op0, op1));
18201 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18206 (define_insn_and_split "*fist<mode>2_floor_1"
18207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18208 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18209 UNSPEC_FIST_FLOOR))
18210 (clobber (reg:CC FLAGS_REG))]
18211 "TARGET_USE_FANCY_MATH_387
18212 && flag_unsafe_math_optimizations
18213 && !(reload_completed || reload_in_progress)"
18218 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18220 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18221 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18222 if (memory_operand (operands[0], VOIDmode))
18223 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18224 operands[2], operands[3]));
18227 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18228 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18229 operands[2], operands[3],
18234 [(set_attr "type" "fistp")
18235 (set_attr "i387_cw" "floor")
18236 (set_attr "mode" "<MODE>")])
18238 (define_insn "fistdi2_floor"
18239 [(set (match_operand:DI 0 "memory_operand" "=m")
18240 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18241 UNSPEC_FIST_FLOOR))
18242 (use (match_operand:HI 2 "memory_operand" "m"))
18243 (use (match_operand:HI 3 "memory_operand" "m"))
18244 (clobber (match_scratch:XF 4 "=&1f"))]
18245 "TARGET_USE_FANCY_MATH_387
18246 && flag_unsafe_math_optimizations"
18247 "* return output_fix_trunc (insn, operands, 0);"
18248 [(set_attr "type" "fistp")
18249 (set_attr "i387_cw" "floor")
18250 (set_attr "mode" "DI")])
18252 (define_insn "fistdi2_floor_with_temp"
18253 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18254 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18255 UNSPEC_FIST_FLOOR))
18256 (use (match_operand:HI 2 "memory_operand" "m,m"))
18257 (use (match_operand:HI 3 "memory_operand" "m,m"))
18258 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18259 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18260 "TARGET_USE_FANCY_MATH_387
18261 && flag_unsafe_math_optimizations"
18263 [(set_attr "type" "fistp")
18264 (set_attr "i387_cw" "floor")
18265 (set_attr "mode" "DI")])
18268 [(set (match_operand:DI 0 "register_operand" "")
18269 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18270 UNSPEC_FIST_FLOOR))
18271 (use (match_operand:HI 2 "memory_operand" ""))
18272 (use (match_operand:HI 3 "memory_operand" ""))
18273 (clobber (match_operand:DI 4 "memory_operand" ""))
18274 (clobber (match_scratch 5 ""))]
18276 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18277 (use (match_dup 2))
18278 (use (match_dup 3))
18279 (clobber (match_dup 5))])
18280 (set (match_dup 0) (match_dup 4))]
18284 [(set (match_operand:DI 0 "memory_operand" "")
18285 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18286 UNSPEC_FIST_FLOOR))
18287 (use (match_operand:HI 2 "memory_operand" ""))
18288 (use (match_operand:HI 3 "memory_operand" ""))
18289 (clobber (match_operand:DI 4 "memory_operand" ""))
18290 (clobber (match_scratch 5 ""))]
18292 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18293 (use (match_dup 2))
18294 (use (match_dup 3))
18295 (clobber (match_dup 5))])]
18298 (define_insn "fist<mode>2_floor"
18299 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18301 UNSPEC_FIST_FLOOR))
18302 (use (match_operand:HI 2 "memory_operand" "m"))
18303 (use (match_operand:HI 3 "memory_operand" "m"))]
18304 "TARGET_USE_FANCY_MATH_387
18305 && flag_unsafe_math_optimizations"
18306 "* return output_fix_trunc (insn, operands, 0);"
18307 [(set_attr "type" "fistp")
18308 (set_attr "i387_cw" "floor")
18309 (set_attr "mode" "<MODE>")])
18311 (define_insn "fist<mode>2_floor_with_temp"
18312 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18313 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18314 UNSPEC_FIST_FLOOR))
18315 (use (match_operand:HI 2 "memory_operand" "m,m"))
18316 (use (match_operand:HI 3 "memory_operand" "m,m"))
18317 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18318 "TARGET_USE_FANCY_MATH_387
18319 && flag_unsafe_math_optimizations"
18321 [(set_attr "type" "fistp")
18322 (set_attr "i387_cw" "floor")
18323 (set_attr "mode" "<MODE>")])
18326 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328 UNSPEC_FIST_FLOOR))
18329 (use (match_operand:HI 2 "memory_operand" ""))
18330 (use (match_operand:HI 3 "memory_operand" ""))
18331 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18333 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18334 UNSPEC_FIST_FLOOR))
18335 (use (match_dup 2))
18336 (use (match_dup 3))])
18337 (set (match_dup 0) (match_dup 4))]
18341 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18342 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18343 UNSPEC_FIST_FLOOR))
18344 (use (match_operand:HI 2 "memory_operand" ""))
18345 (use (match_operand:HI 3 "memory_operand" ""))
18346 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18348 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18349 UNSPEC_FIST_FLOOR))
18350 (use (match_dup 2))
18351 (use (match_dup 3))])]
18354 (define_expand "lfloorxf<mode>2"
18355 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18356 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18357 UNSPEC_FIST_FLOOR))
18358 (clobber (reg:CC FLAGS_REG))])]
18359 "TARGET_USE_FANCY_MATH_387
18360 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18361 && flag_unsafe_math_optimizations"
18364 (define_expand "lfloor<mode>di2"
18365 [(match_operand:DI 0 "nonimmediate_operand" "")
18366 (match_operand:MODEF 1 "register_operand" "")]
18367 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18368 && !flag_trapping_math"
18370 if (optimize_insn_for_size_p ())
18372 ix86_expand_lfloorceil (operand0, operand1, true);
18376 (define_expand "lfloor<mode>si2"
18377 [(match_operand:SI 0 "nonimmediate_operand" "")
18378 (match_operand:MODEF 1 "register_operand" "")]
18379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18380 && !flag_trapping_math"
18382 if (optimize_insn_for_size_p () && TARGET_64BIT)
18384 ix86_expand_lfloorceil (operand0, operand1, true);
18388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18389 (define_insn_and_split "frndintxf2_ceil"
18390 [(set (match_operand:XF 0 "register_operand" "")
18391 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18392 UNSPEC_FRNDINT_CEIL))
18393 (clobber (reg:CC FLAGS_REG))]
18394 "TARGET_USE_FANCY_MATH_387
18395 && flag_unsafe_math_optimizations
18396 && !(reload_completed || reload_in_progress)"
18401 ix86_optimize_mode_switching[I387_CEIL] = 1;
18403 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18404 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18406 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18407 operands[2], operands[3]));
18410 [(set_attr "type" "frndint")
18411 (set_attr "i387_cw" "ceil")
18412 (set_attr "mode" "XF")])
18414 (define_insn "frndintxf2_ceil_i387"
18415 [(set (match_operand:XF 0 "register_operand" "=f")
18416 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18417 UNSPEC_FRNDINT_CEIL))
18418 (use (match_operand:HI 2 "memory_operand" "m"))
18419 (use (match_operand:HI 3 "memory_operand" "m"))]
18420 "TARGET_USE_FANCY_MATH_387
18421 && flag_unsafe_math_optimizations"
18422 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18423 [(set_attr "type" "frndint")
18424 (set_attr "i387_cw" "ceil")
18425 (set_attr "mode" "XF")])
18427 (define_expand "ceilxf2"
18428 [(use (match_operand:XF 0 "register_operand" ""))
18429 (use (match_operand:XF 1 "register_operand" ""))]
18430 "TARGET_USE_FANCY_MATH_387
18431 && flag_unsafe_math_optimizations"
18433 if (optimize_insn_for_size_p ())
18435 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18439 (define_expand "ceil<mode>2"
18440 [(use (match_operand:MODEF 0 "register_operand" ""))
18441 (use (match_operand:MODEF 1 "register_operand" ""))]
18442 "(TARGET_USE_FANCY_MATH_387
18443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444 || TARGET_MIX_SSE_I387)
18445 && flag_unsafe_math_optimizations)
18446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447 && !flag_trapping_math)"
18449 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18450 && !flag_trapping_math
18451 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18454 emit_insn (gen_sse4_1_round<mode>2
18455 (operands[0], operands[1], GEN_INT (0x02)));
18456 else if (optimize_insn_for_size_p ())
18458 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18459 ix86_expand_floorceil (operand0, operand1, false);
18461 ix86_expand_floorceildf_32 (operand0, operand1, false);
18467 if (optimize_insn_for_size_p ())
18470 op0 = gen_reg_rtx (XFmode);
18471 op1 = gen_reg_rtx (XFmode);
18472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18473 emit_insn (gen_frndintxf2_ceil (op0, op1));
18475 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18480 (define_insn_and_split "*fist<mode>2_ceil_1"
18481 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18482 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18484 (clobber (reg:CC FLAGS_REG))]
18485 "TARGET_USE_FANCY_MATH_387
18486 && flag_unsafe_math_optimizations
18487 && !(reload_completed || reload_in_progress)"
18492 ix86_optimize_mode_switching[I387_CEIL] = 1;
18494 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18495 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18496 if (memory_operand (operands[0], VOIDmode))
18497 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18498 operands[2], operands[3]));
18501 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18502 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18503 operands[2], operands[3],
18508 [(set_attr "type" "fistp")
18509 (set_attr "i387_cw" "ceil")
18510 (set_attr "mode" "<MODE>")])
18512 (define_insn "fistdi2_ceil"
18513 [(set (match_operand:DI 0 "memory_operand" "=m")
18514 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18516 (use (match_operand:HI 2 "memory_operand" "m"))
18517 (use (match_operand:HI 3 "memory_operand" "m"))
18518 (clobber (match_scratch:XF 4 "=&1f"))]
18519 "TARGET_USE_FANCY_MATH_387
18520 && flag_unsafe_math_optimizations"
18521 "* return output_fix_trunc (insn, operands, 0);"
18522 [(set_attr "type" "fistp")
18523 (set_attr "i387_cw" "ceil")
18524 (set_attr "mode" "DI")])
18526 (define_insn "fistdi2_ceil_with_temp"
18527 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18528 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18530 (use (match_operand:HI 2 "memory_operand" "m,m"))
18531 (use (match_operand:HI 3 "memory_operand" "m,m"))
18532 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18533 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18534 "TARGET_USE_FANCY_MATH_387
18535 && flag_unsafe_math_optimizations"
18537 [(set_attr "type" "fistp")
18538 (set_attr "i387_cw" "ceil")
18539 (set_attr "mode" "DI")])
18542 [(set (match_operand:DI 0 "register_operand" "")
18543 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18545 (use (match_operand:HI 2 "memory_operand" ""))
18546 (use (match_operand:HI 3 "memory_operand" ""))
18547 (clobber (match_operand:DI 4 "memory_operand" ""))
18548 (clobber (match_scratch 5 ""))]
18550 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18551 (use (match_dup 2))
18552 (use (match_dup 3))
18553 (clobber (match_dup 5))])
18554 (set (match_dup 0) (match_dup 4))]
18558 [(set (match_operand:DI 0 "memory_operand" "")
18559 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18561 (use (match_operand:HI 2 "memory_operand" ""))
18562 (use (match_operand:HI 3 "memory_operand" ""))
18563 (clobber (match_operand:DI 4 "memory_operand" ""))
18564 (clobber (match_scratch 5 ""))]
18566 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18567 (use (match_dup 2))
18568 (use (match_dup 3))
18569 (clobber (match_dup 5))])]
18572 (define_insn "fist<mode>2_ceil"
18573 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18574 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18576 (use (match_operand:HI 2 "memory_operand" "m"))
18577 (use (match_operand:HI 3 "memory_operand" "m"))]
18578 "TARGET_USE_FANCY_MATH_387
18579 && flag_unsafe_math_optimizations"
18580 "* return output_fix_trunc (insn, operands, 0);"
18581 [(set_attr "type" "fistp")
18582 (set_attr "i387_cw" "ceil")
18583 (set_attr "mode" "<MODE>")])
18585 (define_insn "fist<mode>2_ceil_with_temp"
18586 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18587 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18589 (use (match_operand:HI 2 "memory_operand" "m,m"))
18590 (use (match_operand:HI 3 "memory_operand" "m,m"))
18591 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18592 "TARGET_USE_FANCY_MATH_387
18593 && flag_unsafe_math_optimizations"
18595 [(set_attr "type" "fistp")
18596 (set_attr "i387_cw" "ceil")
18597 (set_attr "mode" "<MODE>")])
18600 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18601 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18603 (use (match_operand:HI 2 "memory_operand" ""))
18604 (use (match_operand:HI 3 "memory_operand" ""))
18605 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18607 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18609 (use (match_dup 2))
18610 (use (match_dup 3))])
18611 (set (match_dup 0) (match_dup 4))]
18615 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18616 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18618 (use (match_operand:HI 2 "memory_operand" ""))
18619 (use (match_operand:HI 3 "memory_operand" ""))
18620 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18622 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18624 (use (match_dup 2))
18625 (use (match_dup 3))])]
18628 (define_expand "lceilxf<mode>2"
18629 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18630 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18632 (clobber (reg:CC FLAGS_REG))])]
18633 "TARGET_USE_FANCY_MATH_387
18634 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18635 && flag_unsafe_math_optimizations"
18638 (define_expand "lceil<mode>di2"
18639 [(match_operand:DI 0 "nonimmediate_operand" "")
18640 (match_operand:MODEF 1 "register_operand" "")]
18641 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18642 && !flag_trapping_math"
18644 ix86_expand_lfloorceil (operand0, operand1, false);
18648 (define_expand "lceil<mode>si2"
18649 [(match_operand:SI 0 "nonimmediate_operand" "")
18650 (match_operand:MODEF 1 "register_operand" "")]
18651 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18652 && !flag_trapping_math"
18654 ix86_expand_lfloorceil (operand0, operand1, false);
18658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18659 (define_insn_and_split "frndintxf2_trunc"
18660 [(set (match_operand:XF 0 "register_operand" "")
18661 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18662 UNSPEC_FRNDINT_TRUNC))
18663 (clobber (reg:CC FLAGS_REG))]
18664 "TARGET_USE_FANCY_MATH_387
18665 && flag_unsafe_math_optimizations
18666 && !(reload_completed || reload_in_progress)"
18671 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18673 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18674 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18676 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18677 operands[2], operands[3]));
18680 [(set_attr "type" "frndint")
18681 (set_attr "i387_cw" "trunc")
18682 (set_attr "mode" "XF")])
18684 (define_insn "frndintxf2_trunc_i387"
18685 [(set (match_operand:XF 0 "register_operand" "=f")
18686 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18687 UNSPEC_FRNDINT_TRUNC))
18688 (use (match_operand:HI 2 "memory_operand" "m"))
18689 (use (match_operand:HI 3 "memory_operand" "m"))]
18690 "TARGET_USE_FANCY_MATH_387
18691 && flag_unsafe_math_optimizations"
18692 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18693 [(set_attr "type" "frndint")
18694 (set_attr "i387_cw" "trunc")
18695 (set_attr "mode" "XF")])
18697 (define_expand "btruncxf2"
18698 [(use (match_operand:XF 0 "register_operand" ""))
18699 (use (match_operand:XF 1 "register_operand" ""))]
18700 "TARGET_USE_FANCY_MATH_387
18701 && flag_unsafe_math_optimizations"
18703 if (optimize_insn_for_size_p ())
18705 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18709 (define_expand "btrunc<mode>2"
18710 [(use (match_operand:MODEF 0 "register_operand" ""))
18711 (use (match_operand:MODEF 1 "register_operand" ""))]
18712 "(TARGET_USE_FANCY_MATH_387
18713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18714 || TARGET_MIX_SSE_I387)
18715 && flag_unsafe_math_optimizations)
18716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717 && !flag_trapping_math)"
18719 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18720 && !flag_trapping_math
18721 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18724 emit_insn (gen_sse4_1_round<mode>2
18725 (operands[0], operands[1], GEN_INT (0x03)));
18726 else if (optimize_insn_for_size_p ())
18728 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18729 ix86_expand_trunc (operand0, operand1);
18731 ix86_expand_truncdf_32 (operand0, operand1);
18737 if (optimize_insn_for_size_p ())
18740 op0 = gen_reg_rtx (XFmode);
18741 op1 = gen_reg_rtx (XFmode);
18742 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18743 emit_insn (gen_frndintxf2_trunc (op0, op1));
18745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18750 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18751 (define_insn_and_split "frndintxf2_mask_pm"
18752 [(set (match_operand:XF 0 "register_operand" "")
18753 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18754 UNSPEC_FRNDINT_MASK_PM))
18755 (clobber (reg:CC FLAGS_REG))]
18756 "TARGET_USE_FANCY_MATH_387
18757 && flag_unsafe_math_optimizations
18758 && !(reload_completed || reload_in_progress)"
18763 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18765 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18766 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18768 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18769 operands[2], operands[3]));
18772 [(set_attr "type" "frndint")
18773 (set_attr "i387_cw" "mask_pm")
18774 (set_attr "mode" "XF")])
18776 (define_insn "frndintxf2_mask_pm_i387"
18777 [(set (match_operand:XF 0 "register_operand" "=f")
18778 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18779 UNSPEC_FRNDINT_MASK_PM))
18780 (use (match_operand:HI 2 "memory_operand" "m"))
18781 (use (match_operand:HI 3 "memory_operand" "m"))]
18782 "TARGET_USE_FANCY_MATH_387
18783 && flag_unsafe_math_optimizations"
18784 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18785 [(set_attr "type" "frndint")
18786 (set_attr "i387_cw" "mask_pm")
18787 (set_attr "mode" "XF")])
18789 (define_expand "nearbyintxf2"
18790 [(use (match_operand:XF 0 "register_operand" ""))
18791 (use (match_operand:XF 1 "register_operand" ""))]
18792 "TARGET_USE_FANCY_MATH_387
18793 && flag_unsafe_math_optimizations"
18795 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18800 (define_expand "nearbyint<mode>2"
18801 [(use (match_operand:MODEF 0 "register_operand" ""))
18802 (use (match_operand:MODEF 1 "register_operand" ""))]
18803 "TARGET_USE_FANCY_MATH_387
18804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18805 || TARGET_MIX_SSE_I387)
18806 && flag_unsafe_math_optimizations"
18808 rtx op0 = gen_reg_rtx (XFmode);
18809 rtx op1 = gen_reg_rtx (XFmode);
18811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18812 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18818 (define_insn "fxam<mode>2_i387"
18819 [(set (match_operand:HI 0 "register_operand" "=a")
18821 [(match_operand:X87MODEF 1 "register_operand" "f")]
18823 "TARGET_USE_FANCY_MATH_387"
18824 "fxam\n\tfnstsw\t%0"
18825 [(set_attr "type" "multi")
18826 (set_attr "unit" "i387")
18827 (set_attr "mode" "<MODE>")])
18829 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18830 [(set (match_operand:HI 0 "register_operand" "")
18832 [(match_operand:MODEF 1 "memory_operand" "")]
18834 "TARGET_USE_FANCY_MATH_387
18835 && !(reload_completed || reload_in_progress)"
18838 [(set (match_dup 2)(match_dup 1))
18840 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18842 operands[2] = gen_reg_rtx (<MODE>mode);
18844 MEM_VOLATILE_P (operands[1]) = 1;
18846 [(set_attr "type" "multi")
18847 (set_attr "unit" "i387")
18848 (set_attr "mode" "<MODE>")])
18850 (define_expand "isinfxf2"
18851 [(use (match_operand:SI 0 "register_operand" ""))
18852 (use (match_operand:XF 1 "register_operand" ""))]
18853 "TARGET_USE_FANCY_MATH_387
18854 && TARGET_C99_FUNCTIONS"
18856 rtx mask = GEN_INT (0x45);
18857 rtx val = GEN_INT (0x05);
18861 rtx scratch = gen_reg_rtx (HImode);
18862 rtx res = gen_reg_rtx (QImode);
18864 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18866 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18867 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18868 cond = gen_rtx_fmt_ee (EQ, QImode,
18869 gen_rtx_REG (CCmode, FLAGS_REG),
18871 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18872 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18876 (define_expand "isinf<mode>2"
18877 [(use (match_operand:SI 0 "register_operand" ""))
18878 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18879 "TARGET_USE_FANCY_MATH_387
18880 && TARGET_C99_FUNCTIONS
18881 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18883 rtx mask = GEN_INT (0x45);
18884 rtx val = GEN_INT (0x05);
18888 rtx scratch = gen_reg_rtx (HImode);
18889 rtx res = gen_reg_rtx (QImode);
18891 /* Remove excess precision by forcing value through memory. */
18892 if (memory_operand (operands[1], VOIDmode))
18893 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18896 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18897 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18899 emit_move_insn (temp, operands[1]);
18900 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18903 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18904 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18905 cond = gen_rtx_fmt_ee (EQ, QImode,
18906 gen_rtx_REG (CCmode, FLAGS_REG),
18908 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18909 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18913 (define_expand "signbit<mode>2"
18914 [(use (match_operand:SI 0 "register_operand" ""))
18915 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18916 "TARGET_USE_FANCY_MATH_387
18917 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18919 rtx mask = GEN_INT (0x0200);
18921 rtx scratch = gen_reg_rtx (HImode);
18923 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18924 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18928 ;; Block operation instructions
18931 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18934 [(set_attr "length" "1")
18935 (set_attr "length_immediate" "0")
18936 (set_attr "modrm" "0")])
18938 (define_expand "movmemsi"
18939 [(use (match_operand:BLK 0 "memory_operand" ""))
18940 (use (match_operand:BLK 1 "memory_operand" ""))
18941 (use (match_operand:SI 2 "nonmemory_operand" ""))
18942 (use (match_operand:SI 3 "const_int_operand" ""))
18943 (use (match_operand:SI 4 "const_int_operand" ""))
18944 (use (match_operand:SI 5 "const_int_operand" ""))]
18947 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18948 operands[4], operands[5]))
18954 (define_expand "movmemdi"
18955 [(use (match_operand:BLK 0 "memory_operand" ""))
18956 (use (match_operand:BLK 1 "memory_operand" ""))
18957 (use (match_operand:DI 2 "nonmemory_operand" ""))
18958 (use (match_operand:DI 3 "const_int_operand" ""))
18959 (use (match_operand:SI 4 "const_int_operand" ""))
18960 (use (match_operand:SI 5 "const_int_operand" ""))]
18963 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18964 operands[4], operands[5]))
18970 ;; Most CPUs don't like single string operations
18971 ;; Handle this case here to simplify previous expander.
18973 (define_expand "strmov"
18974 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18975 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18976 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18977 (clobber (reg:CC FLAGS_REG))])
18978 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18979 (clobber (reg:CC FLAGS_REG))])]
18982 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18984 /* If .md ever supports :P for Pmode, these can be directly
18985 in the pattern above. */
18986 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18987 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18989 /* Can't use this if the user has appropriated esi or edi. */
18990 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18991 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18993 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18994 operands[2], operands[3],
18995 operands[5], operands[6]));
18999 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19002 (define_expand "strmov_singleop"
19003 [(parallel [(set (match_operand 1 "memory_operand" "")
19004 (match_operand 3 "memory_operand" ""))
19005 (set (match_operand 0 "register_operand" "")
19006 (match_operand 4 "" ""))
19007 (set (match_operand 2 "register_operand" "")
19008 (match_operand 5 "" ""))])]
19010 "ix86_current_function_needs_cld = 1;")
19012 (define_insn "*strmovdi_rex_1"
19013 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19014 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19015 (set (match_operand:DI 0 "register_operand" "=D")
19016 (plus:DI (match_dup 2)
19018 (set (match_operand:DI 1 "register_operand" "=S")
19019 (plus:DI (match_dup 3)
19023 [(set_attr "type" "str")
19024 (set_attr "mode" "DI")
19025 (set_attr "memory" "both")])
19027 (define_insn "*strmovsi_1"
19028 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19029 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19030 (set (match_operand:SI 0 "register_operand" "=D")
19031 (plus:SI (match_dup 2)
19033 (set (match_operand:SI 1 "register_operand" "=S")
19034 (plus:SI (match_dup 3)
19038 [(set_attr "type" "str")
19039 (set_attr "mode" "SI")
19040 (set_attr "memory" "both")])
19042 (define_insn "*strmovsi_rex_1"
19043 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19044 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19045 (set (match_operand:DI 0 "register_operand" "=D")
19046 (plus:DI (match_dup 2)
19048 (set (match_operand:DI 1 "register_operand" "=S")
19049 (plus:DI (match_dup 3)
19053 [(set_attr "type" "str")
19054 (set_attr "mode" "SI")
19055 (set_attr "memory" "both")])
19057 (define_insn "*strmovhi_1"
19058 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19059 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19060 (set (match_operand:SI 0 "register_operand" "=D")
19061 (plus:SI (match_dup 2)
19063 (set (match_operand:SI 1 "register_operand" "=S")
19064 (plus:SI (match_dup 3)
19068 [(set_attr "type" "str")
19069 (set_attr "memory" "both")
19070 (set_attr "mode" "HI")])
19072 (define_insn "*strmovhi_rex_1"
19073 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19074 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19075 (set (match_operand:DI 0 "register_operand" "=D")
19076 (plus:DI (match_dup 2)
19078 (set (match_operand:DI 1 "register_operand" "=S")
19079 (plus:DI (match_dup 3)
19083 [(set_attr "type" "str")
19084 (set_attr "memory" "both")
19085 (set_attr "mode" "HI")])
19087 (define_insn "*strmovqi_1"
19088 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19089 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19090 (set (match_operand:SI 0 "register_operand" "=D")
19091 (plus:SI (match_dup 2)
19093 (set (match_operand:SI 1 "register_operand" "=S")
19094 (plus:SI (match_dup 3)
19098 [(set_attr "type" "str")
19099 (set_attr "memory" "both")
19100 (set_attr "mode" "QI")])
19102 (define_insn "*strmovqi_rex_1"
19103 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19104 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19105 (set (match_operand:DI 0 "register_operand" "=D")
19106 (plus:DI (match_dup 2)
19108 (set (match_operand:DI 1 "register_operand" "=S")
19109 (plus:DI (match_dup 3)
19113 [(set_attr "type" "str")
19114 (set_attr "memory" "both")
19115 (set_attr "mode" "QI")])
19117 (define_expand "rep_mov"
19118 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19119 (set (match_operand 0 "register_operand" "")
19120 (match_operand 5 "" ""))
19121 (set (match_operand 2 "register_operand" "")
19122 (match_operand 6 "" ""))
19123 (set (match_operand 1 "memory_operand" "")
19124 (match_operand 3 "memory_operand" ""))
19125 (use (match_dup 4))])]
19127 "ix86_current_function_needs_cld = 1;")
19129 (define_insn "*rep_movdi_rex64"
19130 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19131 (set (match_operand:DI 0 "register_operand" "=D")
19132 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19134 (match_operand:DI 3 "register_operand" "0")))
19135 (set (match_operand:DI 1 "register_operand" "=S")
19136 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19137 (match_operand:DI 4 "register_operand" "1")))
19138 (set (mem:BLK (match_dup 3))
19139 (mem:BLK (match_dup 4)))
19140 (use (match_dup 5))]
19143 [(set_attr "type" "str")
19144 (set_attr "prefix_rep" "1")
19145 (set_attr "memory" "both")
19146 (set_attr "mode" "DI")])
19148 (define_insn "*rep_movsi"
19149 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19150 (set (match_operand:SI 0 "register_operand" "=D")
19151 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19153 (match_operand:SI 3 "register_operand" "0")))
19154 (set (match_operand:SI 1 "register_operand" "=S")
19155 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19156 (match_operand:SI 4 "register_operand" "1")))
19157 (set (mem:BLK (match_dup 3))
19158 (mem:BLK (match_dup 4)))
19159 (use (match_dup 5))]
19162 [(set_attr "type" "str")
19163 (set_attr "prefix_rep" "1")
19164 (set_attr "memory" "both")
19165 (set_attr "mode" "SI")])
19167 (define_insn "*rep_movsi_rex64"
19168 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19169 (set (match_operand:DI 0 "register_operand" "=D")
19170 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19172 (match_operand:DI 3 "register_operand" "0")))
19173 (set (match_operand:DI 1 "register_operand" "=S")
19174 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19175 (match_operand:DI 4 "register_operand" "1")))
19176 (set (mem:BLK (match_dup 3))
19177 (mem:BLK (match_dup 4)))
19178 (use (match_dup 5))]
19181 [(set_attr "type" "str")
19182 (set_attr "prefix_rep" "1")
19183 (set_attr "memory" "both")
19184 (set_attr "mode" "SI")])
19186 (define_insn "*rep_movqi"
19187 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19188 (set (match_operand:SI 0 "register_operand" "=D")
19189 (plus:SI (match_operand:SI 3 "register_operand" "0")
19190 (match_operand:SI 5 "register_operand" "2")))
19191 (set (match_operand:SI 1 "register_operand" "=S")
19192 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19193 (set (mem:BLK (match_dup 3))
19194 (mem:BLK (match_dup 4)))
19195 (use (match_dup 5))]
19198 [(set_attr "type" "str")
19199 (set_attr "prefix_rep" "1")
19200 (set_attr "memory" "both")
19201 (set_attr "mode" "SI")])
19203 (define_insn "*rep_movqi_rex64"
19204 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19205 (set (match_operand:DI 0 "register_operand" "=D")
19206 (plus:DI (match_operand:DI 3 "register_operand" "0")
19207 (match_operand:DI 5 "register_operand" "2")))
19208 (set (match_operand:DI 1 "register_operand" "=S")
19209 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19210 (set (mem:BLK (match_dup 3))
19211 (mem:BLK (match_dup 4)))
19212 (use (match_dup 5))]
19215 [(set_attr "type" "str")
19216 (set_attr "prefix_rep" "1")
19217 (set_attr "memory" "both")
19218 (set_attr "mode" "SI")])
19220 (define_expand "setmemsi"
19221 [(use (match_operand:BLK 0 "memory_operand" ""))
19222 (use (match_operand:SI 1 "nonmemory_operand" ""))
19223 (use (match_operand 2 "const_int_operand" ""))
19224 (use (match_operand 3 "const_int_operand" ""))
19225 (use (match_operand:SI 4 "const_int_operand" ""))
19226 (use (match_operand:SI 5 "const_int_operand" ""))]
19229 if (ix86_expand_setmem (operands[0], operands[1],
19230 operands[2], operands[3],
19231 operands[4], operands[5]))
19237 (define_expand "setmemdi"
19238 [(use (match_operand:BLK 0 "memory_operand" ""))
19239 (use (match_operand:DI 1 "nonmemory_operand" ""))
19240 (use (match_operand 2 "const_int_operand" ""))
19241 (use (match_operand 3 "const_int_operand" ""))
19242 (use (match_operand 4 "const_int_operand" ""))
19243 (use (match_operand 5 "const_int_operand" ""))]
19246 if (ix86_expand_setmem (operands[0], operands[1],
19247 operands[2], operands[3],
19248 operands[4], operands[5]))
19254 ;; Most CPUs don't like single string operations
19255 ;; Handle this case here to simplify previous expander.
19257 (define_expand "strset"
19258 [(set (match_operand 1 "memory_operand" "")
19259 (match_operand 2 "register_operand" ""))
19260 (parallel [(set (match_operand 0 "register_operand" "")
19262 (clobber (reg:CC FLAGS_REG))])]
19265 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19266 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19268 /* If .md ever supports :P for Pmode, this can be directly
19269 in the pattern above. */
19270 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19271 GEN_INT (GET_MODE_SIZE (GET_MODE
19273 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19275 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19281 (define_expand "strset_singleop"
19282 [(parallel [(set (match_operand 1 "memory_operand" "")
19283 (match_operand 2 "register_operand" ""))
19284 (set (match_operand 0 "register_operand" "")
19285 (match_operand 3 "" ""))])]
19287 "ix86_current_function_needs_cld = 1;")
19289 (define_insn "*strsetdi_rex_1"
19290 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19291 (match_operand:DI 2 "register_operand" "a"))
19292 (set (match_operand:DI 0 "register_operand" "=D")
19293 (plus:DI (match_dup 1)
19297 [(set_attr "type" "str")
19298 (set_attr "memory" "store")
19299 (set_attr "mode" "DI")])
19301 (define_insn "*strsetsi_1"
19302 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19303 (match_operand:SI 2 "register_operand" "a"))
19304 (set (match_operand:SI 0 "register_operand" "=D")
19305 (plus:SI (match_dup 1)
19309 [(set_attr "type" "str")
19310 (set_attr "memory" "store")
19311 (set_attr "mode" "SI")])
19313 (define_insn "*strsetsi_rex_1"
19314 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19315 (match_operand:SI 2 "register_operand" "a"))
19316 (set (match_operand:DI 0 "register_operand" "=D")
19317 (plus:DI (match_dup 1)
19321 [(set_attr "type" "str")
19322 (set_attr "memory" "store")
19323 (set_attr "mode" "SI")])
19325 (define_insn "*strsethi_1"
19326 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19327 (match_operand:HI 2 "register_operand" "a"))
19328 (set (match_operand:SI 0 "register_operand" "=D")
19329 (plus:SI (match_dup 1)
19333 [(set_attr "type" "str")
19334 (set_attr "memory" "store")
19335 (set_attr "mode" "HI")])
19337 (define_insn "*strsethi_rex_1"
19338 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19339 (match_operand:HI 2 "register_operand" "a"))
19340 (set (match_operand:DI 0 "register_operand" "=D")
19341 (plus:DI (match_dup 1)
19345 [(set_attr "type" "str")
19346 (set_attr "memory" "store")
19347 (set_attr "mode" "HI")])
19349 (define_insn "*strsetqi_1"
19350 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19351 (match_operand:QI 2 "register_operand" "a"))
19352 (set (match_operand:SI 0 "register_operand" "=D")
19353 (plus:SI (match_dup 1)
19357 [(set_attr "type" "str")
19358 (set_attr "memory" "store")
19359 (set_attr "mode" "QI")])
19361 (define_insn "*strsetqi_rex_1"
19362 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19363 (match_operand:QI 2 "register_operand" "a"))
19364 (set (match_operand:DI 0 "register_operand" "=D")
19365 (plus:DI (match_dup 1)
19369 [(set_attr "type" "str")
19370 (set_attr "memory" "store")
19371 (set_attr "mode" "QI")])
19373 (define_expand "rep_stos"
19374 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19375 (set (match_operand 0 "register_operand" "")
19376 (match_operand 4 "" ""))
19377 (set (match_operand 2 "memory_operand" "") (const_int 0))
19378 (use (match_operand 3 "register_operand" ""))
19379 (use (match_dup 1))])]
19381 "ix86_current_function_needs_cld = 1;")
19383 (define_insn "*rep_stosdi_rex64"
19384 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19385 (set (match_operand:DI 0 "register_operand" "=D")
19386 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19388 (match_operand:DI 3 "register_operand" "0")))
19389 (set (mem:BLK (match_dup 3))
19391 (use (match_operand:DI 2 "register_operand" "a"))
19392 (use (match_dup 4))]
19395 [(set_attr "type" "str")
19396 (set_attr "prefix_rep" "1")
19397 (set_attr "memory" "store")
19398 (set_attr "mode" "DI")])
19400 (define_insn "*rep_stossi"
19401 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19402 (set (match_operand:SI 0 "register_operand" "=D")
19403 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19405 (match_operand:SI 3 "register_operand" "0")))
19406 (set (mem:BLK (match_dup 3))
19408 (use (match_operand:SI 2 "register_operand" "a"))
19409 (use (match_dup 4))]
19412 [(set_attr "type" "str")
19413 (set_attr "prefix_rep" "1")
19414 (set_attr "memory" "store")
19415 (set_attr "mode" "SI")])
19417 (define_insn "*rep_stossi_rex64"
19418 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19419 (set (match_operand:DI 0 "register_operand" "=D")
19420 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19422 (match_operand:DI 3 "register_operand" "0")))
19423 (set (mem:BLK (match_dup 3))
19425 (use (match_operand:SI 2 "register_operand" "a"))
19426 (use (match_dup 4))]
19429 [(set_attr "type" "str")
19430 (set_attr "prefix_rep" "1")
19431 (set_attr "memory" "store")
19432 (set_attr "mode" "SI")])
19434 (define_insn "*rep_stosqi"
19435 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19436 (set (match_operand:SI 0 "register_operand" "=D")
19437 (plus:SI (match_operand:SI 3 "register_operand" "0")
19438 (match_operand:SI 4 "register_operand" "1")))
19439 (set (mem:BLK (match_dup 3))
19441 (use (match_operand:QI 2 "register_operand" "a"))
19442 (use (match_dup 4))]
19445 [(set_attr "type" "str")
19446 (set_attr "prefix_rep" "1")
19447 (set_attr "memory" "store")
19448 (set_attr "mode" "QI")])
19450 (define_insn "*rep_stosqi_rex64"
19451 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19452 (set (match_operand:DI 0 "register_operand" "=D")
19453 (plus:DI (match_operand:DI 3 "register_operand" "0")
19454 (match_operand:DI 4 "register_operand" "1")))
19455 (set (mem:BLK (match_dup 3))
19457 (use (match_operand:QI 2 "register_operand" "a"))
19458 (use (match_dup 4))]
19461 [(set_attr "type" "str")
19462 (set_attr "prefix_rep" "1")
19463 (set_attr "memory" "store")
19464 (set_attr "mode" "QI")])
19466 (define_expand "cmpstrnsi"
19467 [(set (match_operand:SI 0 "register_operand" "")
19468 (compare:SI (match_operand:BLK 1 "general_operand" "")
19469 (match_operand:BLK 2 "general_operand" "")))
19470 (use (match_operand 3 "general_operand" ""))
19471 (use (match_operand 4 "immediate_operand" ""))]
19474 rtx addr1, addr2, out, outlow, count, countreg, align;
19476 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19479 /* Can't use this if the user has appropriated esi or edi. */
19480 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19485 out = gen_reg_rtx (SImode);
19487 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19488 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19489 if (addr1 != XEXP (operands[1], 0))
19490 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19491 if (addr2 != XEXP (operands[2], 0))
19492 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19494 count = operands[3];
19495 countreg = ix86_zero_extend_to_Pmode (count);
19497 /* %%% Iff we are testing strict equality, we can use known alignment
19498 to good advantage. This may be possible with combine, particularly
19499 once cc0 is dead. */
19500 align = operands[4];
19502 if (CONST_INT_P (count))
19504 if (INTVAL (count) == 0)
19506 emit_move_insn (operands[0], const0_rtx);
19509 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19510 operands[1], operands[2]));
19515 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19517 emit_insn (gen_cmpsi_1 (countreg, countreg));
19518 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19519 operands[1], operands[2]));
19522 outlow = gen_lowpart (QImode, out);
19523 emit_insn (gen_cmpintqi (outlow));
19524 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19526 if (operands[0] != out)
19527 emit_move_insn (operands[0], out);
19532 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19534 (define_expand "cmpintqi"
19535 [(set (match_dup 1)
19536 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19538 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19539 (parallel [(set (match_operand:QI 0 "register_operand" "")
19540 (minus:QI (match_dup 1)
19542 (clobber (reg:CC FLAGS_REG))])]
19544 "operands[1] = gen_reg_rtx (QImode);
19545 operands[2] = gen_reg_rtx (QImode);")
19547 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19548 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19550 (define_expand "cmpstrnqi_nz_1"
19551 [(parallel [(set (reg:CC FLAGS_REG)
19552 (compare:CC (match_operand 4 "memory_operand" "")
19553 (match_operand 5 "memory_operand" "")))
19554 (use (match_operand 2 "register_operand" ""))
19555 (use (match_operand:SI 3 "immediate_operand" ""))
19556 (clobber (match_operand 0 "register_operand" ""))
19557 (clobber (match_operand 1 "register_operand" ""))
19558 (clobber (match_dup 2))])]
19560 "ix86_current_function_needs_cld = 1;")
19562 (define_insn "*cmpstrnqi_nz_1"
19563 [(set (reg:CC FLAGS_REG)
19564 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19565 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19566 (use (match_operand:SI 6 "register_operand" "2"))
19567 (use (match_operand:SI 3 "immediate_operand" "i"))
19568 (clobber (match_operand:SI 0 "register_operand" "=S"))
19569 (clobber (match_operand:SI 1 "register_operand" "=D"))
19570 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19573 [(set_attr "type" "str")
19574 (set_attr "mode" "QI")
19575 (set_attr "prefix_rep" "1")])
19577 (define_insn "*cmpstrnqi_nz_rex_1"
19578 [(set (reg:CC FLAGS_REG)
19579 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19580 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19581 (use (match_operand:DI 6 "register_operand" "2"))
19582 (use (match_operand:SI 3 "immediate_operand" "i"))
19583 (clobber (match_operand:DI 0 "register_operand" "=S"))
19584 (clobber (match_operand:DI 1 "register_operand" "=D"))
19585 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19588 [(set_attr "type" "str")
19589 (set_attr "mode" "QI")
19590 (set_attr "prefix_rep" "1")])
19592 ;; The same, but the count is not known to not be zero.
19594 (define_expand "cmpstrnqi_1"
19595 [(parallel [(set (reg:CC FLAGS_REG)
19596 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19598 (compare:CC (match_operand 4 "memory_operand" "")
19599 (match_operand 5 "memory_operand" ""))
19601 (use (match_operand:SI 3 "immediate_operand" ""))
19602 (use (reg:CC FLAGS_REG))
19603 (clobber (match_operand 0 "register_operand" ""))
19604 (clobber (match_operand 1 "register_operand" ""))
19605 (clobber (match_dup 2))])]
19607 "ix86_current_function_needs_cld = 1;")
19609 (define_insn "*cmpstrnqi_1"
19610 [(set (reg:CC FLAGS_REG)
19611 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19613 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19614 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19616 (use (match_operand:SI 3 "immediate_operand" "i"))
19617 (use (reg:CC FLAGS_REG))
19618 (clobber (match_operand:SI 0 "register_operand" "=S"))
19619 (clobber (match_operand:SI 1 "register_operand" "=D"))
19620 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19623 [(set_attr "type" "str")
19624 (set_attr "mode" "QI")
19625 (set_attr "prefix_rep" "1")])
19627 (define_insn "*cmpstrnqi_rex_1"
19628 [(set (reg:CC FLAGS_REG)
19629 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19631 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19632 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19634 (use (match_operand:SI 3 "immediate_operand" "i"))
19635 (use (reg:CC FLAGS_REG))
19636 (clobber (match_operand:DI 0 "register_operand" "=S"))
19637 (clobber (match_operand:DI 1 "register_operand" "=D"))
19638 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19641 [(set_attr "type" "str")
19642 (set_attr "mode" "QI")
19643 (set_attr "prefix_rep" "1")])
19645 (define_expand "strlensi"
19646 [(set (match_operand:SI 0 "register_operand" "")
19647 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19648 (match_operand:QI 2 "immediate_operand" "")
19649 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19652 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19658 (define_expand "strlendi"
19659 [(set (match_operand:DI 0 "register_operand" "")
19660 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19661 (match_operand:QI 2 "immediate_operand" "")
19662 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19665 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19671 (define_expand "strlenqi_1"
19672 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19673 (clobber (match_operand 1 "register_operand" ""))
19674 (clobber (reg:CC FLAGS_REG))])]
19676 "ix86_current_function_needs_cld = 1;")
19678 (define_insn "*strlenqi_1"
19679 [(set (match_operand:SI 0 "register_operand" "=&c")
19680 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19681 (match_operand:QI 2 "register_operand" "a")
19682 (match_operand:SI 3 "immediate_operand" "i")
19683 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19684 (clobber (match_operand:SI 1 "register_operand" "=D"))
19685 (clobber (reg:CC FLAGS_REG))]
19688 [(set_attr "type" "str")
19689 (set_attr "mode" "QI")
19690 (set_attr "prefix_rep" "1")])
19692 (define_insn "*strlenqi_rex_1"
19693 [(set (match_operand:DI 0 "register_operand" "=&c")
19694 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19695 (match_operand:QI 2 "register_operand" "a")
19696 (match_operand:DI 3 "immediate_operand" "i")
19697 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19698 (clobber (match_operand:DI 1 "register_operand" "=D"))
19699 (clobber (reg:CC FLAGS_REG))]
19702 [(set_attr "type" "str")
19703 (set_attr "mode" "QI")
19704 (set_attr "prefix_rep" "1")])
19706 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19707 ;; handled in combine, but it is not currently up to the task.
19708 ;; When used for their truth value, the cmpstrn* expanders generate
19717 ;; The intermediate three instructions are unnecessary.
19719 ;; This one handles cmpstrn*_nz_1...
19722 (set (reg:CC FLAGS_REG)
19723 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19724 (mem:BLK (match_operand 5 "register_operand" ""))))
19725 (use (match_operand 6 "register_operand" ""))
19726 (use (match_operand:SI 3 "immediate_operand" ""))
19727 (clobber (match_operand 0 "register_operand" ""))
19728 (clobber (match_operand 1 "register_operand" ""))
19729 (clobber (match_operand 2 "register_operand" ""))])
19730 (set (match_operand:QI 7 "register_operand" "")
19731 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19732 (set (match_operand:QI 8 "register_operand" "")
19733 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19734 (set (reg FLAGS_REG)
19735 (compare (match_dup 7) (match_dup 8)))
19737 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19739 (set (reg:CC FLAGS_REG)
19740 (compare:CC (mem:BLK (match_dup 4))
19741 (mem:BLK (match_dup 5))))
19742 (use (match_dup 6))
19743 (use (match_dup 3))
19744 (clobber (match_dup 0))
19745 (clobber (match_dup 1))
19746 (clobber (match_dup 2))])]
19749 ;; ...and this one handles cmpstrn*_1.
19752 (set (reg:CC FLAGS_REG)
19753 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19755 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19756 (mem:BLK (match_operand 5 "register_operand" "")))
19758 (use (match_operand:SI 3 "immediate_operand" ""))
19759 (use (reg:CC FLAGS_REG))
19760 (clobber (match_operand 0 "register_operand" ""))
19761 (clobber (match_operand 1 "register_operand" ""))
19762 (clobber (match_operand 2 "register_operand" ""))])
19763 (set (match_operand:QI 7 "register_operand" "")
19764 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19765 (set (match_operand:QI 8 "register_operand" "")
19766 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19767 (set (reg FLAGS_REG)
19768 (compare (match_dup 7) (match_dup 8)))
19770 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19772 (set (reg:CC FLAGS_REG)
19773 (if_then_else:CC (ne (match_dup 6)
19775 (compare:CC (mem:BLK (match_dup 4))
19776 (mem:BLK (match_dup 5)))
19778 (use (match_dup 3))
19779 (use (reg:CC FLAGS_REG))
19780 (clobber (match_dup 0))
19781 (clobber (match_dup 1))
19782 (clobber (match_dup 2))])]
19787 ;; Conditional move instructions.
19789 (define_expand "movdicc"
19790 [(set (match_operand:DI 0 "register_operand" "")
19791 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19792 (match_operand:DI 2 "general_operand" "")
19793 (match_operand:DI 3 "general_operand" "")))]
19795 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19797 (define_insn "x86_movdicc_0_m1_rex64"
19798 [(set (match_operand:DI 0 "register_operand" "=r")
19799 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19802 (clobber (reg:CC FLAGS_REG))]
19805 ; Since we don't have the proper number of operands for an alu insn,
19806 ; fill in all the blanks.
19807 [(set_attr "type" "alu")
19808 (set_attr "pent_pair" "pu")
19809 (set_attr "memory" "none")
19810 (set_attr "imm_disp" "false")
19811 (set_attr "mode" "DI")
19812 (set_attr "length_immediate" "0")])
19814 (define_insn "*x86_movdicc_0_m1_se"
19815 [(set (match_operand:DI 0 "register_operand" "=r")
19816 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19819 (clobber (reg:CC FLAGS_REG))]
19822 [(set_attr "type" "alu")
19823 (set_attr "pent_pair" "pu")
19824 (set_attr "memory" "none")
19825 (set_attr "imm_disp" "false")
19826 (set_attr "mode" "DI")
19827 (set_attr "length_immediate" "0")])
19829 (define_insn "*movdicc_c_rex64"
19830 [(set (match_operand:DI 0 "register_operand" "=r,r")
19831 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19832 [(reg FLAGS_REG) (const_int 0)])
19833 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19834 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19835 "TARGET_64BIT && TARGET_CMOVE
19836 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19838 cmov%O2%C1\t{%2, %0|%0, %2}
19839 cmov%O2%c1\t{%3, %0|%0, %3}"
19840 [(set_attr "type" "icmov")
19841 (set_attr "mode" "DI")])
19843 (define_expand "movsicc"
19844 [(set (match_operand:SI 0 "register_operand" "")
19845 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19846 (match_operand:SI 2 "general_operand" "")
19847 (match_operand:SI 3 "general_operand" "")))]
19849 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19851 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19852 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19853 ;; So just document what we're doing explicitly.
19855 (define_insn "x86_movsicc_0_m1"
19856 [(set (match_operand:SI 0 "register_operand" "=r")
19857 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19860 (clobber (reg:CC FLAGS_REG))]
19863 ; Since we don't have the proper number of operands for an alu insn,
19864 ; fill in all the blanks.
19865 [(set_attr "type" "alu")
19866 (set_attr "pent_pair" "pu")
19867 (set_attr "memory" "none")
19868 (set_attr "imm_disp" "false")
19869 (set_attr "mode" "SI")
19870 (set_attr "length_immediate" "0")])
19872 (define_insn "*x86_movsicc_0_m1_se"
19873 [(set (match_operand:SI 0 "register_operand" "=r")
19874 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19877 (clobber (reg:CC FLAGS_REG))]
19880 [(set_attr "type" "alu")
19881 (set_attr "pent_pair" "pu")
19882 (set_attr "memory" "none")
19883 (set_attr "imm_disp" "false")
19884 (set_attr "mode" "SI")
19885 (set_attr "length_immediate" "0")])
19887 (define_insn "*movsicc_noc"
19888 [(set (match_operand:SI 0 "register_operand" "=r,r")
19889 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19890 [(reg FLAGS_REG) (const_int 0)])
19891 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19892 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19894 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19896 cmov%O2%C1\t{%2, %0|%0, %2}
19897 cmov%O2%c1\t{%3, %0|%0, %3}"
19898 [(set_attr "type" "icmov")
19899 (set_attr "mode" "SI")])
19901 (define_expand "movhicc"
19902 [(set (match_operand:HI 0 "register_operand" "")
19903 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19904 (match_operand:HI 2 "general_operand" "")
19905 (match_operand:HI 3 "general_operand" "")))]
19906 "TARGET_HIMODE_MATH"
19907 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19909 (define_insn "*movhicc_noc"
19910 [(set (match_operand:HI 0 "register_operand" "=r,r")
19911 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19912 [(reg FLAGS_REG) (const_int 0)])
19913 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19914 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19916 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19918 cmov%O2%C1\t{%2, %0|%0, %2}
19919 cmov%O2%c1\t{%3, %0|%0, %3}"
19920 [(set_attr "type" "icmov")
19921 (set_attr "mode" "HI")])
19923 (define_expand "movqicc"
19924 [(set (match_operand:QI 0 "register_operand" "")
19925 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19926 (match_operand:QI 2 "general_operand" "")
19927 (match_operand:QI 3 "general_operand" "")))]
19928 "TARGET_QIMODE_MATH"
19929 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19931 (define_insn_and_split "*movqicc_noc"
19932 [(set (match_operand:QI 0 "register_operand" "=r,r")
19933 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19934 [(match_operand 4 "flags_reg_operand" "")
19936 (match_operand:QI 2 "register_operand" "r,0")
19937 (match_operand:QI 3 "register_operand" "0,r")))]
19938 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19940 "&& reload_completed"
19941 [(set (match_dup 0)
19942 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19945 "operands[0] = gen_lowpart (SImode, operands[0]);
19946 operands[2] = gen_lowpart (SImode, operands[2]);
19947 operands[3] = gen_lowpart (SImode, operands[3]);"
19948 [(set_attr "type" "icmov")
19949 (set_attr "mode" "SI")])
19951 (define_expand "mov<mode>cc"
19952 [(set (match_operand:X87MODEF 0 "register_operand" "")
19953 (if_then_else:X87MODEF
19954 (match_operand 1 "comparison_operator" "")
19955 (match_operand:X87MODEF 2 "register_operand" "")
19956 (match_operand:X87MODEF 3 "register_operand" "")))]
19957 "(TARGET_80387 && TARGET_CMOVE)
19958 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19959 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19961 (define_insn "*movsfcc_1_387"
19962 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19963 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19964 [(reg FLAGS_REG) (const_int 0)])
19965 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19966 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19967 "TARGET_80387 && TARGET_CMOVE
19968 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19970 fcmov%F1\t{%2, %0|%0, %2}
19971 fcmov%f1\t{%3, %0|%0, %3}
19972 cmov%O2%C1\t{%2, %0|%0, %2}
19973 cmov%O2%c1\t{%3, %0|%0, %3}"
19974 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19975 (set_attr "mode" "SF,SF,SI,SI")])
19977 (define_insn "*movdfcc_1"
19978 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19979 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19980 [(reg FLAGS_REG) (const_int 0)])
19981 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19982 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19983 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19984 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19986 fcmov%F1\t{%2, %0|%0, %2}
19987 fcmov%f1\t{%3, %0|%0, %3}
19990 [(set_attr "type" "fcmov,fcmov,multi,multi")
19991 (set_attr "mode" "DF")])
19993 (define_insn "*movdfcc_1_rex64"
19994 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19995 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19996 [(reg FLAGS_REG) (const_int 0)])
19997 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19998 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19999 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20000 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20002 fcmov%F1\t{%2, %0|%0, %2}
20003 fcmov%f1\t{%3, %0|%0, %3}
20004 cmov%O2%C1\t{%2, %0|%0, %2}
20005 cmov%O2%c1\t{%3, %0|%0, %3}"
20006 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20007 (set_attr "mode" "DF")])
20010 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20011 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20012 [(match_operand 4 "flags_reg_operand" "")
20014 (match_operand:DF 2 "nonimmediate_operand" "")
20015 (match_operand:DF 3 "nonimmediate_operand" "")))]
20016 "!TARGET_64BIT && reload_completed"
20017 [(set (match_dup 2)
20018 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20022 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20025 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20026 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20028 (define_insn "*movxfcc_1"
20029 [(set (match_operand:XF 0 "register_operand" "=f,f")
20030 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20031 [(reg FLAGS_REG) (const_int 0)])
20032 (match_operand:XF 2 "register_operand" "f,0")
20033 (match_operand:XF 3 "register_operand" "0,f")))]
20034 "TARGET_80387 && TARGET_CMOVE"
20036 fcmov%F1\t{%2, %0|%0, %2}
20037 fcmov%f1\t{%3, %0|%0, %3}"
20038 [(set_attr "type" "fcmov")
20039 (set_attr "mode" "XF")])
20041 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20042 ;; the scalar versions to have only XMM registers as operands.
20044 ;; SSE5 conditional move
20045 (define_insn "*sse5_pcmov_<mode>"
20046 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20047 (if_then_else:MODEF
20048 (match_operand:MODEF 1 "register_operand" "x,0")
20049 (match_operand:MODEF 2 "register_operand" "0,x")
20050 (match_operand:MODEF 3 "register_operand" "x,x")))]
20051 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20052 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20053 [(set_attr "type" "sse4arg")])
20055 ;; These versions of the min/max patterns are intentionally ignorant of
20056 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20057 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20058 ;; are undefined in this condition, we're certain this is correct.
20060 (define_insn "*avx_<code><mode>3"
20061 [(set (match_operand:MODEF 0 "register_operand" "=x")
20063 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20064 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20065 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20066 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20067 [(set_attr "type" "sseadd")
20068 (set_attr "prefix" "vex")
20069 (set_attr "mode" "<MODE>")])
20071 (define_insn "<code><mode>3"
20072 [(set (match_operand:MODEF 0 "register_operand" "=x")
20074 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20075 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20076 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20077 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20078 [(set_attr "type" "sseadd")
20079 (set_attr "mode" "<MODE>")])
20081 ;; These versions of the min/max patterns implement exactly the operations
20082 ;; min = (op1 < op2 ? op1 : op2)
20083 ;; max = (!(op1 < op2) ? op1 : op2)
20084 ;; Their operands are not commutative, and thus they may be used in the
20085 ;; presence of -0.0 and NaN.
20087 (define_insn "*avx_ieee_smin<mode>3"
20088 [(set (match_operand:MODEF 0 "register_operand" "=x")
20090 [(match_operand:MODEF 1 "register_operand" "x")
20091 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20093 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20094 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20095 [(set_attr "type" "sseadd")
20096 (set_attr "prefix" "vex")
20097 (set_attr "mode" "<MODE>")])
20099 (define_insn "*ieee_smin<mode>3"
20100 [(set (match_operand:MODEF 0 "register_operand" "=x")
20102 [(match_operand:MODEF 1 "register_operand" "0")
20103 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20105 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20106 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20107 [(set_attr "type" "sseadd")
20108 (set_attr "mode" "<MODE>")])
20110 (define_insn "*avx_ieee_smax<mode>3"
20111 [(set (match_operand:MODEF 0 "register_operand" "=x")
20113 [(match_operand:MODEF 1 "register_operand" "0")
20114 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20116 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20117 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20118 [(set_attr "type" "sseadd")
20119 (set_attr "prefix" "vex")
20120 (set_attr "mode" "<MODE>")])
20122 (define_insn "*ieee_smax<mode>3"
20123 [(set (match_operand:MODEF 0 "register_operand" "=x")
20125 [(match_operand:MODEF 1 "register_operand" "0")
20126 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20128 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20129 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20130 [(set_attr "type" "sseadd")
20131 (set_attr "mode" "<MODE>")])
20133 ;; Make two stack loads independent:
20135 ;; fld %st(0) -> fld bb
20136 ;; fmul bb fmul %st(1), %st
20138 ;; Actually we only match the last two instructions for simplicity.
20140 [(set (match_operand 0 "fp_register_operand" "")
20141 (match_operand 1 "fp_register_operand" ""))
20143 (match_operator 2 "binary_fp_operator"
20145 (match_operand 3 "memory_operand" "")]))]
20146 "REGNO (operands[0]) != REGNO (operands[1])"
20147 [(set (match_dup 0) (match_dup 3))
20148 (set (match_dup 0) (match_dup 4))]
20150 ;; The % modifier is not operational anymore in peephole2's, so we have to
20151 ;; swap the operands manually in the case of addition and multiplication.
20152 "if (COMMUTATIVE_ARITH_P (operands[2]))
20153 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20154 operands[0], operands[1]);
20156 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20157 operands[1], operands[0]);")
20159 ;; Conditional addition patterns
20160 (define_expand "add<mode>cc"
20161 [(match_operand:SWI 0 "register_operand" "")
20162 (match_operand 1 "comparison_operator" "")
20163 (match_operand:SWI 2 "register_operand" "")
20164 (match_operand:SWI 3 "const_int_operand" "")]
20166 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20169 ;; Misc patterns (?)
20171 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20172 ;; Otherwise there will be nothing to keep
20174 ;; [(set (reg ebp) (reg esp))]
20175 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20176 ;; (clobber (eflags)]
20177 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20179 ;; in proper program order.
20180 (define_insn "pro_epilogue_adjust_stack_1"
20181 [(set (match_operand:SI 0 "register_operand" "=r,r")
20182 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20183 (match_operand:SI 2 "immediate_operand" "i,i")))
20184 (clobber (reg:CC FLAGS_REG))
20185 (clobber (mem:BLK (scratch)))]
20188 switch (get_attr_type (insn))
20191 return "mov{l}\t{%1, %0|%0, %1}";
20194 if (CONST_INT_P (operands[2])
20195 && (INTVAL (operands[2]) == 128
20196 || (INTVAL (operands[2]) < 0
20197 && INTVAL (operands[2]) != -128)))
20199 operands[2] = GEN_INT (-INTVAL (operands[2]));
20200 return "sub{l}\t{%2, %0|%0, %2}";
20202 return "add{l}\t{%2, %0|%0, %2}";
20205 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20206 return "lea{l}\t{%a2, %0|%0, %a2}";
20209 gcc_unreachable ();
20212 [(set (attr "type")
20213 (cond [(eq_attr "alternative" "0")
20214 (const_string "alu")
20215 (match_operand:SI 2 "const0_operand" "")
20216 (const_string "imov")
20218 (const_string "lea")))
20219 (set_attr "mode" "SI")])
20221 (define_insn "pro_epilogue_adjust_stack_rex64"
20222 [(set (match_operand:DI 0 "register_operand" "=r,r")
20223 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20224 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20225 (clobber (reg:CC FLAGS_REG))
20226 (clobber (mem:BLK (scratch)))]
20229 switch (get_attr_type (insn))
20232 return "mov{q}\t{%1, %0|%0, %1}";
20235 if (CONST_INT_P (operands[2])
20236 /* Avoid overflows. */
20237 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20238 && (INTVAL (operands[2]) == 128
20239 || (INTVAL (operands[2]) < 0
20240 && INTVAL (operands[2]) != -128)))
20242 operands[2] = GEN_INT (-INTVAL (operands[2]));
20243 return "sub{q}\t{%2, %0|%0, %2}";
20245 return "add{q}\t{%2, %0|%0, %2}";
20248 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20249 return "lea{q}\t{%a2, %0|%0, %a2}";
20252 gcc_unreachable ();
20255 [(set (attr "type")
20256 (cond [(eq_attr "alternative" "0")
20257 (const_string "alu")
20258 (match_operand:DI 2 "const0_operand" "")
20259 (const_string "imov")
20261 (const_string "lea")))
20262 (set_attr "mode" "DI")])
20264 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20265 [(set (match_operand:DI 0 "register_operand" "=r,r")
20266 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20267 (match_operand:DI 3 "immediate_operand" "i,i")))
20268 (use (match_operand:DI 2 "register_operand" "r,r"))
20269 (clobber (reg:CC FLAGS_REG))
20270 (clobber (mem:BLK (scratch)))]
20273 switch (get_attr_type (insn))
20276 return "add{q}\t{%2, %0|%0, %2}";
20279 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20280 return "lea{q}\t{%a2, %0|%0, %a2}";
20283 gcc_unreachable ();
20286 [(set_attr "type" "alu,lea")
20287 (set_attr "mode" "DI")])
20289 (define_insn "allocate_stack_worker_32"
20290 [(set (match_operand:SI 0 "register_operand" "=a")
20291 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20292 UNSPECV_STACK_PROBE))
20293 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20294 (clobber (reg:CC FLAGS_REG))]
20295 "!TARGET_64BIT && TARGET_STACK_PROBE"
20297 [(set_attr "type" "multi")
20298 (set_attr "length" "5")])
20300 (define_insn "allocate_stack_worker_64"
20301 [(set (match_operand:DI 0 "register_operand" "=a")
20302 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20303 UNSPECV_STACK_PROBE))
20304 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20305 (clobber (reg:DI R10_REG))
20306 (clobber (reg:DI R11_REG))
20307 (clobber (reg:CC FLAGS_REG))]
20308 "TARGET_64BIT && TARGET_STACK_PROBE"
20310 [(set_attr "type" "multi")
20311 (set_attr "length" "5")])
20313 (define_expand "allocate_stack"
20314 [(match_operand 0 "register_operand" "")
20315 (match_operand 1 "general_operand" "")]
20316 "TARGET_STACK_PROBE"
20320 #ifndef CHECK_STACK_LIMIT
20321 #define CHECK_STACK_LIMIT 0
20324 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20325 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20327 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20328 stack_pointer_rtx, 0, OPTAB_DIRECT);
20329 if (x != stack_pointer_rtx)
20330 emit_move_insn (stack_pointer_rtx, x);
20334 x = copy_to_mode_reg (Pmode, operands[1]);
20336 x = gen_allocate_stack_worker_64 (x, x);
20338 x = gen_allocate_stack_worker_32 (x, x);
20342 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20346 (define_expand "builtin_setjmp_receiver"
20347 [(label_ref (match_operand 0 "" ""))]
20348 "!TARGET_64BIT && flag_pic"
20354 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20355 rtx label_rtx = gen_label_rtx ();
20356 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20357 xops[0] = xops[1] = picreg;
20358 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20359 ix86_expand_binary_operator (MINUS, SImode, xops);
20363 emit_insn (gen_set_got (pic_offset_table_rtx));
20367 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20370 [(set (match_operand 0 "register_operand" "")
20371 (match_operator 3 "promotable_binary_operator"
20372 [(match_operand 1 "register_operand" "")
20373 (match_operand 2 "aligned_operand" "")]))
20374 (clobber (reg:CC FLAGS_REG))]
20375 "! TARGET_PARTIAL_REG_STALL && reload_completed
20376 && ((GET_MODE (operands[0]) == HImode
20377 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20378 /* ??? next two lines just !satisfies_constraint_K (...) */
20379 || !CONST_INT_P (operands[2])
20380 || satisfies_constraint_K (operands[2])))
20381 || (GET_MODE (operands[0]) == QImode
20382 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20383 [(parallel [(set (match_dup 0)
20384 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20385 (clobber (reg:CC FLAGS_REG))])]
20386 "operands[0] = gen_lowpart (SImode, operands[0]);
20387 operands[1] = gen_lowpart (SImode, operands[1]);
20388 if (GET_CODE (operands[3]) != ASHIFT)
20389 operands[2] = gen_lowpart (SImode, operands[2]);
20390 PUT_MODE (operands[3], SImode);")
20392 ; Promote the QImode tests, as i386 has encoding of the AND
20393 ; instruction with 32-bit sign-extended immediate and thus the
20394 ; instruction size is unchanged, except in the %eax case for
20395 ; which it is increased by one byte, hence the ! optimize_size.
20397 [(set (match_operand 0 "flags_reg_operand" "")
20398 (match_operator 2 "compare_operator"
20399 [(and (match_operand 3 "aligned_operand" "")
20400 (match_operand 4 "const_int_operand" ""))
20402 (set (match_operand 1 "register_operand" "")
20403 (and (match_dup 3) (match_dup 4)))]
20404 "! TARGET_PARTIAL_REG_STALL && reload_completed
20405 && optimize_insn_for_speed_p ()
20406 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20407 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20408 /* Ensure that the operand will remain sign-extended immediate. */
20409 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20410 [(parallel [(set (match_dup 0)
20411 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20414 (and:SI (match_dup 3) (match_dup 4)))])]
20417 = gen_int_mode (INTVAL (operands[4])
20418 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20419 operands[1] = gen_lowpart (SImode, operands[1]);
20420 operands[3] = gen_lowpart (SImode, operands[3]);
20423 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20424 ; the TEST instruction with 32-bit sign-extended immediate and thus
20425 ; the instruction size would at least double, which is not what we
20426 ; want even with ! optimize_size.
20428 [(set (match_operand 0 "flags_reg_operand" "")
20429 (match_operator 1 "compare_operator"
20430 [(and (match_operand:HI 2 "aligned_operand" "")
20431 (match_operand:HI 3 "const_int_operand" ""))
20433 "! TARGET_PARTIAL_REG_STALL && reload_completed
20434 && ! TARGET_FAST_PREFIX
20435 && optimize_insn_for_speed_p ()
20436 /* Ensure that the operand will remain sign-extended immediate. */
20437 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20438 [(set (match_dup 0)
20439 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20443 = gen_int_mode (INTVAL (operands[3])
20444 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20445 operands[2] = gen_lowpart (SImode, operands[2]);
20449 [(set (match_operand 0 "register_operand" "")
20450 (neg (match_operand 1 "register_operand" "")))
20451 (clobber (reg:CC FLAGS_REG))]
20452 "! TARGET_PARTIAL_REG_STALL && reload_completed
20453 && (GET_MODE (operands[0]) == HImode
20454 || (GET_MODE (operands[0]) == QImode
20455 && (TARGET_PROMOTE_QImode
20456 || optimize_insn_for_size_p ())))"
20457 [(parallel [(set (match_dup 0)
20458 (neg:SI (match_dup 1)))
20459 (clobber (reg:CC FLAGS_REG))])]
20460 "operands[0] = gen_lowpart (SImode, operands[0]);
20461 operands[1] = gen_lowpart (SImode, operands[1]);")
20464 [(set (match_operand 0 "register_operand" "")
20465 (not (match_operand 1 "register_operand" "")))]
20466 "! TARGET_PARTIAL_REG_STALL && reload_completed
20467 && (GET_MODE (operands[0]) == HImode
20468 || (GET_MODE (operands[0]) == QImode
20469 && (TARGET_PROMOTE_QImode
20470 || optimize_insn_for_size_p ())))"
20471 [(set (match_dup 0)
20472 (not:SI (match_dup 1)))]
20473 "operands[0] = gen_lowpart (SImode, operands[0]);
20474 operands[1] = gen_lowpart (SImode, operands[1]);")
20477 [(set (match_operand 0 "register_operand" "")
20478 (if_then_else (match_operator 1 "comparison_operator"
20479 [(reg FLAGS_REG) (const_int 0)])
20480 (match_operand 2 "register_operand" "")
20481 (match_operand 3 "register_operand" "")))]
20482 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20483 && (GET_MODE (operands[0]) == HImode
20484 || (GET_MODE (operands[0]) == QImode
20485 && (TARGET_PROMOTE_QImode
20486 || optimize_insn_for_size_p ())))"
20487 [(set (match_dup 0)
20488 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20489 "operands[0] = gen_lowpart (SImode, operands[0]);
20490 operands[2] = gen_lowpart (SImode, operands[2]);
20491 operands[3] = gen_lowpart (SImode, operands[3]);")
20494 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20495 ;; transform a complex memory operation into two memory to register operations.
20497 ;; Don't push memory operands
20499 [(set (match_operand:SI 0 "push_operand" "")
20500 (match_operand:SI 1 "memory_operand" ""))
20501 (match_scratch:SI 2 "r")]
20502 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20503 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20504 [(set (match_dup 2) (match_dup 1))
20505 (set (match_dup 0) (match_dup 2))]
20509 [(set (match_operand:DI 0 "push_operand" "")
20510 (match_operand:DI 1 "memory_operand" ""))
20511 (match_scratch:DI 2 "r")]
20512 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20513 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20514 [(set (match_dup 2) (match_dup 1))
20515 (set (match_dup 0) (match_dup 2))]
20518 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20521 [(set (match_operand:SF 0 "push_operand" "")
20522 (match_operand:SF 1 "memory_operand" ""))
20523 (match_scratch:SF 2 "r")]
20524 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20525 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20526 [(set (match_dup 2) (match_dup 1))
20527 (set (match_dup 0) (match_dup 2))]
20531 [(set (match_operand:HI 0 "push_operand" "")
20532 (match_operand:HI 1 "memory_operand" ""))
20533 (match_scratch:HI 2 "r")]
20534 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20535 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20536 [(set (match_dup 2) (match_dup 1))
20537 (set (match_dup 0) (match_dup 2))]
20541 [(set (match_operand:QI 0 "push_operand" "")
20542 (match_operand:QI 1 "memory_operand" ""))
20543 (match_scratch:QI 2 "q")]
20544 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20545 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20546 [(set (match_dup 2) (match_dup 1))
20547 (set (match_dup 0) (match_dup 2))]
20550 ;; Don't move an immediate directly to memory when the instruction
20553 [(match_scratch:SI 1 "r")
20554 (set (match_operand:SI 0 "memory_operand" "")
20556 "optimize_insn_for_speed_p ()
20557 && ! TARGET_USE_MOV0
20558 && TARGET_SPLIT_LONG_MOVES
20559 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20560 && peep2_regno_dead_p (0, FLAGS_REG)"
20561 [(parallel [(set (match_dup 1) (const_int 0))
20562 (clobber (reg:CC FLAGS_REG))])
20563 (set (match_dup 0) (match_dup 1))]
20567 [(match_scratch:HI 1 "r")
20568 (set (match_operand:HI 0 "memory_operand" "")
20570 "optimize_insn_for_speed_p ()
20571 && ! TARGET_USE_MOV0
20572 && TARGET_SPLIT_LONG_MOVES
20573 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20574 && peep2_regno_dead_p (0, FLAGS_REG)"
20575 [(parallel [(set (match_dup 2) (const_int 0))
20576 (clobber (reg:CC FLAGS_REG))])
20577 (set (match_dup 0) (match_dup 1))]
20578 "operands[2] = gen_lowpart (SImode, operands[1]);")
20581 [(match_scratch:QI 1 "q")
20582 (set (match_operand:QI 0 "memory_operand" "")
20584 "optimize_insn_for_speed_p ()
20585 && ! TARGET_USE_MOV0
20586 && TARGET_SPLIT_LONG_MOVES
20587 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20588 && peep2_regno_dead_p (0, FLAGS_REG)"
20589 [(parallel [(set (match_dup 2) (const_int 0))
20590 (clobber (reg:CC FLAGS_REG))])
20591 (set (match_dup 0) (match_dup 1))]
20592 "operands[2] = gen_lowpart (SImode, operands[1]);")
20595 [(match_scratch:SI 2 "r")
20596 (set (match_operand:SI 0 "memory_operand" "")
20597 (match_operand:SI 1 "immediate_operand" ""))]
20598 "optimize_insn_for_speed_p ()
20599 && TARGET_SPLIT_LONG_MOVES
20600 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20601 [(set (match_dup 2) (match_dup 1))
20602 (set (match_dup 0) (match_dup 2))]
20606 [(match_scratch:HI 2 "r")
20607 (set (match_operand:HI 0 "memory_operand" "")
20608 (match_operand:HI 1 "immediate_operand" ""))]
20609 "optimize_insn_for_speed_p ()
20610 && TARGET_SPLIT_LONG_MOVES
20611 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20612 [(set (match_dup 2) (match_dup 1))
20613 (set (match_dup 0) (match_dup 2))]
20617 [(match_scratch:QI 2 "q")
20618 (set (match_operand:QI 0 "memory_operand" "")
20619 (match_operand:QI 1 "immediate_operand" ""))]
20620 "optimize_insn_for_speed_p ()
20621 && TARGET_SPLIT_LONG_MOVES
20622 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20623 [(set (match_dup 2) (match_dup 1))
20624 (set (match_dup 0) (match_dup 2))]
20627 ;; Don't compare memory with zero, load and use a test instead.
20629 [(set (match_operand 0 "flags_reg_operand" "")
20630 (match_operator 1 "compare_operator"
20631 [(match_operand:SI 2 "memory_operand" "")
20633 (match_scratch:SI 3 "r")]
20634 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20635 [(set (match_dup 3) (match_dup 2))
20636 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20639 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20640 ;; Don't split NOTs with a displacement operand, because resulting XOR
20641 ;; will not be pairable anyway.
20643 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20644 ;; represented using a modRM byte. The XOR replacement is long decoded,
20645 ;; so this split helps here as well.
20647 ;; Note: Can't do this as a regular split because we can't get proper
20648 ;; lifetime information then.
20651 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20652 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20653 "optimize_insn_for_speed_p ()
20654 && ((TARGET_NOT_UNPAIRABLE
20655 && (!MEM_P (operands[0])
20656 || !memory_displacement_operand (operands[0], SImode)))
20657 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20658 && peep2_regno_dead_p (0, FLAGS_REG)"
20659 [(parallel [(set (match_dup 0)
20660 (xor:SI (match_dup 1) (const_int -1)))
20661 (clobber (reg:CC FLAGS_REG))])]
20665 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20666 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20667 "optimize_insn_for_speed_p ()
20668 && ((TARGET_NOT_UNPAIRABLE
20669 && (!MEM_P (operands[0])
20670 || !memory_displacement_operand (operands[0], HImode)))
20671 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20672 && peep2_regno_dead_p (0, FLAGS_REG)"
20673 [(parallel [(set (match_dup 0)
20674 (xor:HI (match_dup 1) (const_int -1)))
20675 (clobber (reg:CC FLAGS_REG))])]
20679 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20680 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20681 "optimize_insn_for_speed_p ()
20682 && ((TARGET_NOT_UNPAIRABLE
20683 && (!MEM_P (operands[0])
20684 || !memory_displacement_operand (operands[0], QImode)))
20685 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20686 && peep2_regno_dead_p (0, FLAGS_REG)"
20687 [(parallel [(set (match_dup 0)
20688 (xor:QI (match_dup 1) (const_int -1)))
20689 (clobber (reg:CC FLAGS_REG))])]
20692 ;; Non pairable "test imm, reg" instructions can be translated to
20693 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20694 ;; byte opcode instead of two, have a short form for byte operands),
20695 ;; so do it for other CPUs as well. Given that the value was dead,
20696 ;; this should not create any new dependencies. Pass on the sub-word
20697 ;; versions if we're concerned about partial register stalls.
20700 [(set (match_operand 0 "flags_reg_operand" "")
20701 (match_operator 1 "compare_operator"
20702 [(and:SI (match_operand:SI 2 "register_operand" "")
20703 (match_operand:SI 3 "immediate_operand" ""))
20705 "ix86_match_ccmode (insn, CCNOmode)
20706 && (true_regnum (operands[2]) != AX_REG
20707 || satisfies_constraint_K (operands[3]))
20708 && peep2_reg_dead_p (1, operands[2])"
20710 [(set (match_dup 0)
20711 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20714 (and:SI (match_dup 2) (match_dup 3)))])]
20717 ;; We don't need to handle HImode case, because it will be promoted to SImode
20718 ;; on ! TARGET_PARTIAL_REG_STALL
20721 [(set (match_operand 0 "flags_reg_operand" "")
20722 (match_operator 1 "compare_operator"
20723 [(and:QI (match_operand:QI 2 "register_operand" "")
20724 (match_operand:QI 3 "immediate_operand" ""))
20726 "! TARGET_PARTIAL_REG_STALL
20727 && ix86_match_ccmode (insn, CCNOmode)
20728 && true_regnum (operands[2]) != AX_REG
20729 && peep2_reg_dead_p (1, operands[2])"
20731 [(set (match_dup 0)
20732 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20735 (and:QI (match_dup 2) (match_dup 3)))])]
20739 [(set (match_operand 0 "flags_reg_operand" "")
20740 (match_operator 1 "compare_operator"
20743 (match_operand 2 "ext_register_operand" "")
20746 (match_operand 3 "const_int_operand" ""))
20748 "! TARGET_PARTIAL_REG_STALL
20749 && ix86_match_ccmode (insn, CCNOmode)
20750 && true_regnum (operands[2]) != AX_REG
20751 && peep2_reg_dead_p (1, operands[2])"
20752 [(parallel [(set (match_dup 0)
20761 (set (zero_extract:SI (match_dup 2)
20772 ;; Don't do logical operations with memory inputs.
20774 [(match_scratch:SI 2 "r")
20775 (parallel [(set (match_operand:SI 0 "register_operand" "")
20776 (match_operator:SI 3 "arith_or_logical_operator"
20778 (match_operand:SI 1 "memory_operand" "")]))
20779 (clobber (reg:CC FLAGS_REG))])]
20780 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20781 [(set (match_dup 2) (match_dup 1))
20782 (parallel [(set (match_dup 0)
20783 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20784 (clobber (reg:CC FLAGS_REG))])]
20788 [(match_scratch:SI 2 "r")
20789 (parallel [(set (match_operand:SI 0 "register_operand" "")
20790 (match_operator:SI 3 "arith_or_logical_operator"
20791 [(match_operand:SI 1 "memory_operand" "")
20793 (clobber (reg:CC FLAGS_REG))])]
20794 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20795 [(set (match_dup 2) (match_dup 1))
20796 (parallel [(set (match_dup 0)
20797 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20798 (clobber (reg:CC FLAGS_REG))])]
20801 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20802 ;; refers to the destination of the load!
20805 [(set (match_operand:SI 0 "register_operand" "")
20806 (match_operand:SI 1 "register_operand" ""))
20807 (parallel [(set (match_dup 0)
20808 (match_operator:SI 3 "commutative_operator"
20810 (match_operand:SI 2 "memory_operand" "")]))
20811 (clobber (reg:CC FLAGS_REG))])]
20812 "REGNO (operands[0]) != REGNO (operands[1])
20813 && GENERAL_REGNO_P (REGNO (operands[0]))
20814 && GENERAL_REGNO_P (REGNO (operands[1]))"
20815 [(set (match_dup 0) (match_dup 4))
20816 (parallel [(set (match_dup 0)
20817 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20818 (clobber (reg:CC FLAGS_REG))])]
20819 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20822 [(set (match_operand 0 "register_operand" "")
20823 (match_operand 1 "register_operand" ""))
20825 (match_operator 3 "commutative_operator"
20827 (match_operand 2 "memory_operand" "")]))]
20828 "REGNO (operands[0]) != REGNO (operands[1])
20829 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20830 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20831 [(set (match_dup 0) (match_dup 2))
20833 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20836 ; Don't do logical operations with memory outputs
20838 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20839 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20840 ; the same decoder scheduling characteristics as the original.
20843 [(match_scratch:SI 2 "r")
20844 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20845 (match_operator:SI 3 "arith_or_logical_operator"
20847 (match_operand:SI 1 "nonmemory_operand" "")]))
20848 (clobber (reg:CC FLAGS_REG))])]
20849 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20850 [(set (match_dup 2) (match_dup 0))
20851 (parallel [(set (match_dup 2)
20852 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20853 (clobber (reg:CC FLAGS_REG))])
20854 (set (match_dup 0) (match_dup 2))]
20858 [(match_scratch:SI 2 "r")
20859 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20860 (match_operator:SI 3 "arith_or_logical_operator"
20861 [(match_operand:SI 1 "nonmemory_operand" "")
20863 (clobber (reg:CC FLAGS_REG))])]
20864 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20865 [(set (match_dup 2) (match_dup 0))
20866 (parallel [(set (match_dup 2)
20867 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20868 (clobber (reg:CC FLAGS_REG))])
20869 (set (match_dup 0) (match_dup 2))]
20872 ;; Attempt to always use XOR for zeroing registers.
20874 [(set (match_operand 0 "register_operand" "")
20875 (match_operand 1 "const0_operand" ""))]
20876 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20877 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20878 && GENERAL_REG_P (operands[0])
20879 && peep2_regno_dead_p (0, FLAGS_REG)"
20880 [(parallel [(set (match_dup 0) (const_int 0))
20881 (clobber (reg:CC FLAGS_REG))])]
20883 operands[0] = gen_lowpart (word_mode, operands[0]);
20887 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20889 "(GET_MODE (operands[0]) == QImode
20890 || GET_MODE (operands[0]) == HImode)
20891 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20892 && peep2_regno_dead_p (0, FLAGS_REG)"
20893 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20894 (clobber (reg:CC FLAGS_REG))])])
20896 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20898 [(set (match_operand 0 "register_operand" "")
20900 "(GET_MODE (operands[0]) == HImode
20901 || GET_MODE (operands[0]) == SImode
20902 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20903 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20904 && peep2_regno_dead_p (0, FLAGS_REG)"
20905 [(parallel [(set (match_dup 0) (const_int -1))
20906 (clobber (reg:CC FLAGS_REG))])]
20907 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20910 ;; Attempt to convert simple leas to adds. These can be created by
20913 [(set (match_operand:SI 0 "register_operand" "")
20914 (plus:SI (match_dup 0)
20915 (match_operand:SI 1 "nonmemory_operand" "")))]
20916 "peep2_regno_dead_p (0, FLAGS_REG)"
20917 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20918 (clobber (reg:CC FLAGS_REG))])]
20922 [(set (match_operand:SI 0 "register_operand" "")
20923 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20924 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20925 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20926 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20927 (clobber (reg:CC FLAGS_REG))])]
20928 "operands[2] = gen_lowpart (SImode, operands[2]);")
20931 [(set (match_operand:DI 0 "register_operand" "")
20932 (plus:DI (match_dup 0)
20933 (match_operand:DI 1 "x86_64_general_operand" "")))]
20934 "peep2_regno_dead_p (0, FLAGS_REG)"
20935 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20936 (clobber (reg:CC FLAGS_REG))])]
20940 [(set (match_operand:SI 0 "register_operand" "")
20941 (mult:SI (match_dup 0)
20942 (match_operand:SI 1 "const_int_operand" "")))]
20943 "exact_log2 (INTVAL (operands[1])) >= 0
20944 && peep2_regno_dead_p (0, FLAGS_REG)"
20945 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20946 (clobber (reg:CC FLAGS_REG))])]
20947 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20950 [(set (match_operand:DI 0 "register_operand" "")
20951 (mult:DI (match_dup 0)
20952 (match_operand:DI 1 "const_int_operand" "")))]
20953 "exact_log2 (INTVAL (operands[1])) >= 0
20954 && peep2_regno_dead_p (0, FLAGS_REG)"
20955 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20956 (clobber (reg:CC FLAGS_REG))])]
20957 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20960 [(set (match_operand:SI 0 "register_operand" "")
20961 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20962 (match_operand:DI 2 "const_int_operand" "")) 0))]
20963 "exact_log2 (INTVAL (operands[2])) >= 0
20964 && REGNO (operands[0]) == REGNO (operands[1])
20965 && peep2_regno_dead_p (0, FLAGS_REG)"
20966 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20967 (clobber (reg:CC FLAGS_REG))])]
20968 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20970 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20971 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20972 ;; many CPUs it is also faster, since special hardware to avoid esp
20973 ;; dependencies is present.
20975 ;; While some of these conversions may be done using splitters, we use peepholes
20976 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20978 ;; Convert prologue esp subtractions to push.
20979 ;; We need register to push. In order to keep verify_flow_info happy we have
20981 ;; - use scratch and clobber it in order to avoid dependencies
20982 ;; - use already live register
20983 ;; We can't use the second way right now, since there is no reliable way how to
20984 ;; verify that given register is live. First choice will also most likely in
20985 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20986 ;; call clobbered registers are dead. We may want to use base pointer as an
20987 ;; alternative when no register is available later.
20990 [(match_scratch:SI 0 "r")
20991 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20992 (clobber (reg:CC FLAGS_REG))
20993 (clobber (mem:BLK (scratch)))])]
20994 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20995 [(clobber (match_dup 0))
20996 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20997 (clobber (mem:BLK (scratch)))])])
21000 [(match_scratch:SI 0 "r")
21001 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21002 (clobber (reg:CC FLAGS_REG))
21003 (clobber (mem:BLK (scratch)))])]
21004 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21005 [(clobber (match_dup 0))
21006 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21007 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21008 (clobber (mem:BLK (scratch)))])])
21010 ;; Convert esp subtractions to push.
21012 [(match_scratch:SI 0 "r")
21013 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21014 (clobber (reg:CC FLAGS_REG))])]
21015 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21016 [(clobber (match_dup 0))
21017 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21020 [(match_scratch:SI 0 "r")
21021 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21022 (clobber (reg:CC FLAGS_REG))])]
21023 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21024 [(clobber (match_dup 0))
21025 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21026 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21028 ;; Convert epilogue deallocator to pop.
21030 [(match_scratch:SI 0 "r")
21031 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21032 (clobber (reg:CC FLAGS_REG))
21033 (clobber (mem:BLK (scratch)))])]
21034 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21035 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21036 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21037 (clobber (mem:BLK (scratch)))])]
21040 ;; Two pops case is tricky, since pop causes dependency on destination register.
21041 ;; We use two registers if available.
21043 [(match_scratch:SI 0 "r")
21044 (match_scratch:SI 1 "r")
21045 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21046 (clobber (reg:CC FLAGS_REG))
21047 (clobber (mem:BLK (scratch)))])]
21048 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21049 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21050 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21051 (clobber (mem:BLK (scratch)))])
21052 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21053 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21057 [(match_scratch:SI 0 "r")
21058 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21059 (clobber (reg:CC FLAGS_REG))
21060 (clobber (mem:BLK (scratch)))])]
21061 "optimize_insn_for_size_p ()"
21062 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21063 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21064 (clobber (mem:BLK (scratch)))])
21065 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21066 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21069 ;; Convert esp additions to pop.
21071 [(match_scratch:SI 0 "r")
21072 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21073 (clobber (reg:CC FLAGS_REG))])]
21075 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21076 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21079 ;; Two pops case is tricky, since pop causes dependency on destination register.
21080 ;; We use two registers if available.
21082 [(match_scratch:SI 0 "r")
21083 (match_scratch:SI 1 "r")
21084 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21085 (clobber (reg:CC FLAGS_REG))])]
21087 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21088 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21089 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21090 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21094 [(match_scratch:SI 0 "r")
21095 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21096 (clobber (reg:CC FLAGS_REG))])]
21097 "optimize_insn_for_size_p ()"
21098 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21099 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21100 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21101 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21104 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21105 ;; required and register dies. Similarly for 128 to -128.
21107 [(set (match_operand 0 "flags_reg_operand" "")
21108 (match_operator 1 "compare_operator"
21109 [(match_operand 2 "register_operand" "")
21110 (match_operand 3 "const_int_operand" "")]))]
21111 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21112 && incdec_operand (operands[3], GET_MODE (operands[3])))
21113 || (!TARGET_FUSE_CMP_AND_BRANCH
21114 && INTVAL (operands[3]) == 128))
21115 && ix86_match_ccmode (insn, CCGCmode)
21116 && peep2_reg_dead_p (1, operands[2])"
21117 [(parallel [(set (match_dup 0)
21118 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21119 (clobber (match_dup 2))])]
21123 [(match_scratch:DI 0 "r")
21124 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21125 (clobber (reg:CC FLAGS_REG))
21126 (clobber (mem:BLK (scratch)))])]
21127 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21128 [(clobber (match_dup 0))
21129 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21130 (clobber (mem:BLK (scratch)))])])
21133 [(match_scratch:DI 0 "r")
21134 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21135 (clobber (reg:CC FLAGS_REG))
21136 (clobber (mem:BLK (scratch)))])]
21137 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21138 [(clobber (match_dup 0))
21139 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21140 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21141 (clobber (mem:BLK (scratch)))])])
21143 ;; Convert esp subtractions to push.
21145 [(match_scratch:DI 0 "r")
21146 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21147 (clobber (reg:CC FLAGS_REG))])]
21148 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21149 [(clobber (match_dup 0))
21150 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21153 [(match_scratch:DI 0 "r")
21154 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21155 (clobber (reg:CC FLAGS_REG))])]
21156 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21157 [(clobber (match_dup 0))
21158 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21159 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21161 ;; Convert epilogue deallocator to pop.
21163 [(match_scratch:DI 0 "r")
21164 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21165 (clobber (reg:CC FLAGS_REG))
21166 (clobber (mem:BLK (scratch)))])]
21167 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21168 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21169 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21170 (clobber (mem:BLK (scratch)))])]
21173 ;; Two pops case is tricky, since pop causes dependency on destination register.
21174 ;; We use two registers if available.
21176 [(match_scratch:DI 0 "r")
21177 (match_scratch:DI 1 "r")
21178 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21179 (clobber (reg:CC FLAGS_REG))
21180 (clobber (mem:BLK (scratch)))])]
21181 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21182 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21183 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21184 (clobber (mem:BLK (scratch)))])
21185 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21186 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21190 [(match_scratch:DI 0 "r")
21191 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21192 (clobber (reg:CC FLAGS_REG))
21193 (clobber (mem:BLK (scratch)))])]
21194 "optimize_insn_for_size_p ()"
21195 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21196 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21197 (clobber (mem:BLK (scratch)))])
21198 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21199 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21202 ;; Convert esp additions to pop.
21204 [(match_scratch:DI 0 "r")
21205 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21206 (clobber (reg:CC FLAGS_REG))])]
21208 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21209 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21212 ;; Two pops case is tricky, since pop causes dependency on destination register.
21213 ;; We use two registers if available.
21215 [(match_scratch:DI 0 "r")
21216 (match_scratch:DI 1 "r")
21217 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21218 (clobber (reg:CC FLAGS_REG))])]
21220 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21221 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21222 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21223 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21227 [(match_scratch:DI 0 "r")
21228 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21229 (clobber (reg:CC FLAGS_REG))])]
21230 "optimize_insn_for_size_p ()"
21231 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21232 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21233 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21234 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21237 ;; Convert imul by three, five and nine into lea
21240 [(set (match_operand:SI 0 "register_operand" "")
21241 (mult:SI (match_operand:SI 1 "register_operand" "")
21242 (match_operand:SI 2 "const_int_operand" "")))
21243 (clobber (reg:CC FLAGS_REG))])]
21244 "INTVAL (operands[2]) == 3
21245 || INTVAL (operands[2]) == 5
21246 || INTVAL (operands[2]) == 9"
21247 [(set (match_dup 0)
21248 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21250 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21254 [(set (match_operand:SI 0 "register_operand" "")
21255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21256 (match_operand:SI 2 "const_int_operand" "")))
21257 (clobber (reg:CC FLAGS_REG))])]
21258 "optimize_insn_for_speed_p ()
21259 && (INTVAL (operands[2]) == 3
21260 || INTVAL (operands[2]) == 5
21261 || INTVAL (operands[2]) == 9)"
21262 [(set (match_dup 0) (match_dup 1))
21264 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21266 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21270 [(set (match_operand:DI 0 "register_operand" "")
21271 (mult:DI (match_operand:DI 1 "register_operand" "")
21272 (match_operand:DI 2 "const_int_operand" "")))
21273 (clobber (reg:CC FLAGS_REG))])]
21275 && (INTVAL (operands[2]) == 3
21276 || INTVAL (operands[2]) == 5
21277 || INTVAL (operands[2]) == 9)"
21278 [(set (match_dup 0)
21279 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21281 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21285 [(set (match_operand:DI 0 "register_operand" "")
21286 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21287 (match_operand:DI 2 "const_int_operand" "")))
21288 (clobber (reg:CC FLAGS_REG))])]
21290 && optimize_insn_for_speed_p ()
21291 && (INTVAL (operands[2]) == 3
21292 || INTVAL (operands[2]) == 5
21293 || INTVAL (operands[2]) == 9)"
21294 [(set (match_dup 0) (match_dup 1))
21296 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21298 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21300 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21301 ;; imul $32bit_imm, reg, reg is direct decoded.
21303 [(match_scratch:DI 3 "r")
21304 (parallel [(set (match_operand:DI 0 "register_operand" "")
21305 (mult:DI (match_operand:DI 1 "memory_operand" "")
21306 (match_operand:DI 2 "immediate_operand" "")))
21307 (clobber (reg:CC FLAGS_REG))])]
21308 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21309 && !satisfies_constraint_K (operands[2])"
21310 [(set (match_dup 3) (match_dup 1))
21311 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21312 (clobber (reg:CC FLAGS_REG))])]
21316 [(match_scratch:SI 3 "r")
21317 (parallel [(set (match_operand:SI 0 "register_operand" "")
21318 (mult:SI (match_operand:SI 1 "memory_operand" "")
21319 (match_operand:SI 2 "immediate_operand" "")))
21320 (clobber (reg:CC FLAGS_REG))])]
21321 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21322 && !satisfies_constraint_K (operands[2])"
21323 [(set (match_dup 3) (match_dup 1))
21324 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21325 (clobber (reg:CC FLAGS_REG))])]
21329 [(match_scratch:SI 3 "r")
21330 (parallel [(set (match_operand:DI 0 "register_operand" "")
21332 (mult:SI (match_operand:SI 1 "memory_operand" "")
21333 (match_operand:SI 2 "immediate_operand" ""))))
21334 (clobber (reg:CC FLAGS_REG))])]
21335 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21336 && !satisfies_constraint_K (operands[2])"
21337 [(set (match_dup 3) (match_dup 1))
21338 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21339 (clobber (reg:CC FLAGS_REG))])]
21342 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21343 ;; Convert it into imul reg, reg
21344 ;; It would be better to force assembler to encode instruction using long
21345 ;; immediate, but there is apparently no way to do so.
21347 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21348 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21349 (match_operand:DI 2 "const_int_operand" "")))
21350 (clobber (reg:CC FLAGS_REG))])
21351 (match_scratch:DI 3 "r")]
21352 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21353 && satisfies_constraint_K (operands[2])"
21354 [(set (match_dup 3) (match_dup 2))
21355 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21356 (clobber (reg:CC FLAGS_REG))])]
21358 if (!rtx_equal_p (operands[0], operands[1]))
21359 emit_move_insn (operands[0], operands[1]);
21363 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21364 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21365 (match_operand:SI 2 "const_int_operand" "")))
21366 (clobber (reg:CC FLAGS_REG))])
21367 (match_scratch:SI 3 "r")]
21368 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21369 && satisfies_constraint_K (operands[2])"
21370 [(set (match_dup 3) (match_dup 2))
21371 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21372 (clobber (reg:CC FLAGS_REG))])]
21374 if (!rtx_equal_p (operands[0], operands[1]))
21375 emit_move_insn (operands[0], operands[1]);
21379 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21380 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21381 (match_operand:HI 2 "immediate_operand" "")))
21382 (clobber (reg:CC FLAGS_REG))])
21383 (match_scratch:HI 3 "r")]
21384 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21385 [(set (match_dup 3) (match_dup 2))
21386 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21387 (clobber (reg:CC FLAGS_REG))])]
21389 if (!rtx_equal_p (operands[0], operands[1]))
21390 emit_move_insn (operands[0], operands[1]);
21393 ;; After splitting up read-modify operations, array accesses with memory
21394 ;; operands might end up in form:
21396 ;; movl 4(%esp), %edx
21398 ;; instead of pre-splitting:
21400 ;; addl 4(%esp), %eax
21402 ;; movl 4(%esp), %edx
21403 ;; leal (%edx,%eax,4), %eax
21406 [(parallel [(set (match_operand 0 "register_operand" "")
21407 (ashift (match_operand 1 "register_operand" "")
21408 (match_operand 2 "const_int_operand" "")))
21409 (clobber (reg:CC FLAGS_REG))])
21410 (set (match_operand 3 "register_operand")
21411 (match_operand 4 "x86_64_general_operand" ""))
21412 (parallel [(set (match_operand 5 "register_operand" "")
21413 (plus (match_operand 6 "register_operand" "")
21414 (match_operand 7 "register_operand" "")))
21415 (clobber (reg:CC FLAGS_REG))])]
21416 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21417 /* Validate MODE for lea. */
21418 && ((!TARGET_PARTIAL_REG_STALL
21419 && (GET_MODE (operands[0]) == QImode
21420 || GET_MODE (operands[0]) == HImode))
21421 || GET_MODE (operands[0]) == SImode
21422 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21423 /* We reorder load and the shift. */
21424 && !rtx_equal_p (operands[1], operands[3])
21425 && !reg_overlap_mentioned_p (operands[0], operands[4])
21426 /* Last PLUS must consist of operand 0 and 3. */
21427 && !rtx_equal_p (operands[0], operands[3])
21428 && (rtx_equal_p (operands[3], operands[6])
21429 || rtx_equal_p (operands[3], operands[7]))
21430 && (rtx_equal_p (operands[0], operands[6])
21431 || rtx_equal_p (operands[0], operands[7]))
21432 /* The intermediate operand 0 must die or be same as output. */
21433 && (rtx_equal_p (operands[0], operands[5])
21434 || peep2_reg_dead_p (3, operands[0]))"
21435 [(set (match_dup 3) (match_dup 4))
21436 (set (match_dup 0) (match_dup 1))]
21438 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21439 int scale = 1 << INTVAL (operands[2]);
21440 rtx index = gen_lowpart (Pmode, operands[1]);
21441 rtx base = gen_lowpart (Pmode, operands[3]);
21442 rtx dest = gen_lowpart (mode, operands[5]);
21444 operands[1] = gen_rtx_PLUS (Pmode, base,
21445 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21447 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21448 operands[0] = dest;
21451 ;; Call-value patterns last so that the wildcard operand does not
21452 ;; disrupt insn-recog's switch tables.
21454 (define_insn "*call_value_pop_0"
21455 [(set (match_operand 0 "" "")
21456 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21457 (match_operand:SI 2 "" "")))
21458 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21459 (match_operand:SI 3 "immediate_operand" "")))]
21462 if (SIBLING_CALL_P (insn))
21465 return "call\t%P1";
21467 [(set_attr "type" "callv")])
21469 (define_insn "*call_value_pop_1"
21470 [(set (match_operand 0 "" "")
21471 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21472 (match_operand:SI 2 "" "")))
21473 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21474 (match_operand:SI 3 "immediate_operand" "i")))]
21475 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21477 if (constant_call_address_operand (operands[1], Pmode))
21478 return "call\t%P1";
21479 return "call\t%A1";
21481 [(set_attr "type" "callv")])
21483 (define_insn "*sibcall_value_pop_1"
21484 [(set (match_operand 0 "" "")
21485 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21486 (match_operand:SI 2 "" "")))
21487 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21488 (match_operand:SI 3 "immediate_operand" "i,i")))]
21489 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21493 [(set_attr "type" "callv")])
21495 (define_insn "*call_value_0"
21496 [(set (match_operand 0 "" "")
21497 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21498 (match_operand:SI 2 "" "")))]
21501 if (SIBLING_CALL_P (insn))
21504 return "call\t%P1";
21506 [(set_attr "type" "callv")])
21508 (define_insn "*call_value_0_rex64"
21509 [(set (match_operand 0 "" "")
21510 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21511 (match_operand:DI 2 "const_int_operand" "")))]
21514 if (SIBLING_CALL_P (insn))
21517 return "call\t%P1";
21519 [(set_attr "type" "callv")])
21521 (define_insn "*call_value_0_rex64_ms_sysv"
21522 [(set (match_operand 0 "" "")
21523 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21524 (match_operand:DI 2 "const_int_operand" "")))
21525 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21526 (clobber (reg:TI XMM6_REG))
21527 (clobber (reg:TI XMM7_REG))
21528 (clobber (reg:TI XMM8_REG))
21529 (clobber (reg:TI XMM9_REG))
21530 (clobber (reg:TI XMM10_REG))
21531 (clobber (reg:TI XMM11_REG))
21532 (clobber (reg:TI XMM12_REG))
21533 (clobber (reg:TI XMM13_REG))
21534 (clobber (reg:TI XMM14_REG))
21535 (clobber (reg:TI XMM15_REG))
21536 (clobber (reg:DI SI_REG))
21537 (clobber (reg:DI DI_REG))]
21538 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21540 if (SIBLING_CALL_P (insn))
21543 return "call\t%P1";
21545 [(set_attr "type" "callv")])
21547 (define_insn "*call_value_1"
21548 [(set (match_operand 0 "" "")
21549 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21550 (match_operand:SI 2 "" "")))]
21551 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21553 if (constant_call_address_operand (operands[1], Pmode))
21554 return "call\t%P1";
21555 return "call\t%A1";
21557 [(set_attr "type" "callv")])
21559 (define_insn "*sibcall_value_1"
21560 [(set (match_operand 0 "" "")
21561 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21562 (match_operand:SI 2 "" "")))]
21563 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21567 [(set_attr "type" "callv")])
21569 (define_insn "*call_value_1_rex64"
21570 [(set (match_operand 0 "" "")
21571 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21572 (match_operand:DI 2 "" "")))]
21573 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21574 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21576 if (constant_call_address_operand (operands[1], Pmode))
21577 return "call\t%P1";
21578 return "call\t%A1";
21580 [(set_attr "type" "callv")])
21582 (define_insn "*call_value_1_rex64_ms_sysv"
21583 [(set (match_operand 0 "" "")
21584 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21585 (match_operand:DI 2 "" "")))
21586 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21587 (clobber (reg:TI 27))
21588 (clobber (reg:TI 28))
21589 (clobber (reg:TI 45))
21590 (clobber (reg:TI 46))
21591 (clobber (reg:TI 47))
21592 (clobber (reg:TI 48))
21593 (clobber (reg:TI 49))
21594 (clobber (reg:TI 50))
21595 (clobber (reg:TI 51))
21596 (clobber (reg:TI 52))
21597 (clobber (reg:DI SI_REG))
21598 (clobber (reg:DI DI_REG))]
21599 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21601 if (constant_call_address_operand (operands[1], Pmode))
21602 return "call\t%P1";
21603 return "call\t%A1";
21605 [(set_attr "type" "callv")])
21607 (define_insn "*call_value_1_rex64_large"
21608 [(set (match_operand 0 "" "")
21609 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21610 (match_operand:DI 2 "" "")))]
21611 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21613 [(set_attr "type" "callv")])
21615 (define_insn "*sibcall_value_1_rex64"
21616 [(set (match_operand 0 "" "")
21617 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21618 (match_operand:DI 2 "" "")))]
21619 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21623 [(set_attr "type" "callv")])
21625 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21626 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21627 ;; caught for use by garbage collectors and the like. Using an insn that
21628 ;; maps to SIGILL makes it more likely the program will rightfully die.
21629 ;; Keeping with tradition, "6" is in honor of #UD.
21630 (define_insn "trap"
21631 [(trap_if (const_int 1) (const_int 6))]
21633 { return ASM_SHORT "0x0b0f"; }
21634 [(set_attr "length" "2")])
21636 (define_expand "sse_prologue_save"
21637 [(parallel [(set (match_operand:BLK 0 "" "")
21638 (unspec:BLK [(reg:DI 21)
21645 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21646 (use (match_operand:DI 1 "register_operand" ""))
21647 (use (match_operand:DI 2 "immediate_operand" ""))
21648 (use (label_ref:DI (match_operand 3 "" "")))])]
21652 (define_insn "*sse_prologue_save_insn"
21653 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21654 (match_operand:DI 4 "const_int_operand" "n")))
21655 (unspec:BLK [(reg:DI 21)
21662 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21663 (use (match_operand:DI 1 "register_operand" "r"))
21664 (use (match_operand:DI 2 "const_int_operand" "i"))
21665 (use (label_ref:DI (match_operand 3 "" "X")))]
21667 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21668 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21671 operands[0] = gen_rtx_MEM (Pmode,
21672 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21673 /* VEX instruction with a REX prefix will #UD. */
21674 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21675 gcc_unreachable ();
21677 output_asm_insn ("jmp\t%A1", operands);
21678 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21680 operands[4] = adjust_address (operands[0], DImode, i*16);
21681 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21682 PUT_MODE (operands[4], TImode);
21683 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21684 output_asm_insn ("rex", operands);
21685 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21687 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21688 CODE_LABEL_NUMBER (operands[3]));
21691 [(set_attr "type" "other")
21692 (set_attr "length_immediate" "0")
21693 (set_attr "length_address" "0")
21694 (set (attr "length")
21696 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21697 (const_string "34")
21698 (const_string "42")))
21699 (set_attr "memory" "store")
21700 (set_attr "modrm" "0")
21701 (set_attr "prefix" "maybe_vex")
21702 (set_attr "mode" "DI")])
21704 (define_expand "prefetch"
21705 [(prefetch (match_operand 0 "address_operand" "")
21706 (match_operand:SI 1 "const_int_operand" "")
21707 (match_operand:SI 2 "const_int_operand" ""))]
21708 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21710 int rw = INTVAL (operands[1]);
21711 int locality = INTVAL (operands[2]);
21713 gcc_assert (rw == 0 || rw == 1);
21714 gcc_assert (locality >= 0 && locality <= 3);
21715 gcc_assert (GET_MODE (operands[0]) == Pmode
21716 || GET_MODE (operands[0]) == VOIDmode);
21718 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21719 supported by SSE counterpart or the SSE prefetch is not available
21720 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21722 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21723 operands[2] = GEN_INT (3);
21725 operands[1] = const0_rtx;
21728 (define_insn "*prefetch_sse"
21729 [(prefetch (match_operand:SI 0 "address_operand" "p")
21731 (match_operand:SI 1 "const_int_operand" ""))]
21732 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21734 static const char * const patterns[4] = {
21735 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21738 int locality = INTVAL (operands[1]);
21739 gcc_assert (locality >= 0 && locality <= 3);
21741 return patterns[locality];
21743 [(set_attr "type" "sse")
21744 (set_attr "memory" "none")])
21746 (define_insn "*prefetch_sse_rex"
21747 [(prefetch (match_operand:DI 0 "address_operand" "p")
21749 (match_operand:SI 1 "const_int_operand" ""))]
21750 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21752 static const char * const patterns[4] = {
21753 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21756 int locality = INTVAL (operands[1]);
21757 gcc_assert (locality >= 0 && locality <= 3);
21759 return patterns[locality];
21761 [(set_attr "type" "sse")
21762 (set_attr "memory" "none")])
21764 (define_insn "*prefetch_3dnow"
21765 [(prefetch (match_operand:SI 0 "address_operand" "p")
21766 (match_operand:SI 1 "const_int_operand" "n")
21768 "TARGET_3DNOW && !TARGET_64BIT"
21770 if (INTVAL (operands[1]) == 0)
21771 return "prefetch\t%a0";
21773 return "prefetchw\t%a0";
21775 [(set_attr "type" "mmx")
21776 (set_attr "memory" "none")])
21778 (define_insn "*prefetch_3dnow_rex"
21779 [(prefetch (match_operand:DI 0 "address_operand" "p")
21780 (match_operand:SI 1 "const_int_operand" "n")
21782 "TARGET_3DNOW && TARGET_64BIT"
21784 if (INTVAL (operands[1]) == 0)
21785 return "prefetch\t%a0";
21787 return "prefetchw\t%a0";
21789 [(set_attr "type" "mmx")
21790 (set_attr "memory" "none")])
21792 (define_expand "stack_protect_set"
21793 [(match_operand 0 "memory_operand" "")
21794 (match_operand 1 "memory_operand" "")]
21797 #ifdef TARGET_THREAD_SSP_OFFSET
21799 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21800 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21802 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21803 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21806 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21808 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21813 (define_insn "stack_protect_set_si"
21814 [(set (match_operand:SI 0 "memory_operand" "=m")
21815 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21816 (set (match_scratch:SI 2 "=&r") (const_int 0))
21817 (clobber (reg:CC FLAGS_REG))]
21819 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21820 [(set_attr "type" "multi")])
21822 (define_insn "stack_protect_set_di"
21823 [(set (match_operand:DI 0 "memory_operand" "=m")
21824 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21825 (set (match_scratch:DI 2 "=&r") (const_int 0))
21826 (clobber (reg:CC FLAGS_REG))]
21828 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21829 [(set_attr "type" "multi")])
21831 (define_insn "stack_tls_protect_set_si"
21832 [(set (match_operand:SI 0 "memory_operand" "=m")
21833 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21834 (set (match_scratch:SI 2 "=&r") (const_int 0))
21835 (clobber (reg:CC FLAGS_REG))]
21837 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21838 [(set_attr "type" "multi")])
21840 (define_insn "stack_tls_protect_set_di"
21841 [(set (match_operand:DI 0 "memory_operand" "=m")
21842 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21843 (set (match_scratch:DI 2 "=&r") (const_int 0))
21844 (clobber (reg:CC FLAGS_REG))]
21847 /* The kernel uses a different segment register for performance reasons; a
21848 system call would not have to trash the userspace segment register,
21849 which would be expensive */
21850 if (ix86_cmodel != CM_KERNEL)
21851 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21853 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21855 [(set_attr "type" "multi")])
21857 (define_expand "stack_protect_test"
21858 [(match_operand 0 "memory_operand" "")
21859 (match_operand 1 "memory_operand" "")
21860 (match_operand 2 "" "")]
21863 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21864 ix86_compare_op0 = operands[0];
21865 ix86_compare_op1 = operands[1];
21866 ix86_compare_emitted = flags;
21868 #ifdef TARGET_THREAD_SSP_OFFSET
21870 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21871 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21873 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21874 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21877 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21879 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21881 emit_jump_insn (gen_beq (operands[2]));
21885 (define_insn "stack_protect_test_si"
21886 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21887 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21888 (match_operand:SI 2 "memory_operand" "m")]
21890 (clobber (match_scratch:SI 3 "=&r"))]
21892 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21893 [(set_attr "type" "multi")])
21895 (define_insn "stack_protect_test_di"
21896 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21897 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21898 (match_operand:DI 2 "memory_operand" "m")]
21900 (clobber (match_scratch:DI 3 "=&r"))]
21902 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21903 [(set_attr "type" "multi")])
21905 (define_insn "stack_tls_protect_test_si"
21906 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21907 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21908 (match_operand:SI 2 "const_int_operand" "i")]
21909 UNSPEC_SP_TLS_TEST))
21910 (clobber (match_scratch:SI 3 "=r"))]
21912 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21913 [(set_attr "type" "multi")])
21915 (define_insn "stack_tls_protect_test_di"
21916 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21917 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21918 (match_operand:DI 2 "const_int_operand" "i")]
21919 UNSPEC_SP_TLS_TEST))
21920 (clobber (match_scratch:DI 3 "=r"))]
21923 /* The kernel uses a different segment register for performance reasons; a
21924 system call would not have to trash the userspace segment register,
21925 which would be expensive */
21926 if (ix86_cmodel != CM_KERNEL)
21927 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21929 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21931 [(set_attr "type" "multi")])
21933 (define_mode_iterator CRC32MODE [QI HI SI])
21934 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21935 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21937 (define_insn "sse4_2_crc32<mode>"
21938 [(set (match_operand:SI 0 "register_operand" "=r")
21940 [(match_operand:SI 1 "register_operand" "0")
21941 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21944 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "sselog1")
21946 (set_attr "prefix_rep" "1")
21947 (set_attr "prefix_extra" "1")
21948 (set_attr "mode" "SI")])
21950 (define_insn "sse4_2_crc32di"
21951 [(set (match_operand:DI 0 "register_operand" "=r")
21953 [(match_operand:DI 1 "register_operand" "0")
21954 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21956 "TARGET_SSE4_2 && TARGET_64BIT"
21957 "crc32q\t{%2, %0|%0, %2}"
21958 [(set_attr "type" "sselog1")
21959 (set_attr "prefix_rep" "1")
21960 (set_attr "prefix_extra" "1")
21961 (set_attr "mode" "DI")])
21965 (include "sync.md")