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")))]
14978 if (constant_call_address_operand (operands[0], Pmode))
14980 if (SIBLING_CALL_P (insn))
14983 return "call\t%P0";
14985 if (SIBLING_CALL_P (insn))
14988 return "call\t%A0";
14990 [(set_attr "type" "call")])
14992 (define_expand "call"
14993 [(call (match_operand:QI 0 "" "")
14994 (match_operand 1 "" ""))
14995 (use (match_operand 2 "" ""))]
14998 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15002 (define_expand "sibcall"
15003 [(call (match_operand:QI 0 "" "")
15004 (match_operand 1 "" ""))
15005 (use (match_operand 2 "" ""))]
15008 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15012 (define_insn "*call_0"
15013 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15014 (match_operand 1 "" ""))]
15017 if (SIBLING_CALL_P (insn))
15020 return "call\t%P0";
15022 [(set_attr "type" "call")])
15024 (define_insn "*call_1"
15025 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15026 (match_operand 1 "" ""))]
15027 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15029 if (constant_call_address_operand (operands[0], Pmode))
15030 return "call\t%P0";
15031 return "call\t%A0";
15033 [(set_attr "type" "call")])
15035 (define_insn "*sibcall_1"
15036 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15037 (match_operand 1 "" ""))]
15038 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15042 [(set_attr "type" "call")])
15044 (define_insn "*call_1_rex64"
15045 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15046 (match_operand 1 "" ""))]
15047 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15048 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15050 if (constant_call_address_operand (operands[0], Pmode))
15051 return "call\t%P0";
15052 return "call\t%A0";
15054 [(set_attr "type" "call")])
15056 (define_insn "*call_1_rex64_ms_sysv"
15057 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15058 (match_operand 1 "" ""))
15059 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15060 (clobber (reg:TI XMM6_REG))
15061 (clobber (reg:TI XMM7_REG))
15062 (clobber (reg:TI XMM8_REG))
15063 (clobber (reg:TI XMM9_REG))
15064 (clobber (reg:TI XMM10_REG))
15065 (clobber (reg:TI XMM11_REG))
15066 (clobber (reg:TI XMM12_REG))
15067 (clobber (reg:TI XMM13_REG))
15068 (clobber (reg:TI XMM14_REG))
15069 (clobber (reg:TI XMM15_REG))
15070 (clobber (reg:DI SI_REG))
15071 (clobber (reg:DI DI_REG))]
15072 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15074 if (constant_call_address_operand (operands[0], Pmode))
15075 return "call\t%P0";
15076 return "call\t%A0";
15078 [(set_attr "type" "call")])
15080 (define_insn "*call_1_rex64_large"
15081 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15082 (match_operand 1 "" ""))]
15083 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15085 [(set_attr "type" "call")])
15087 (define_insn "*sibcall_1_rex64"
15088 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15089 (match_operand 1 "" ""))]
15090 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15094 [(set_attr "type" "call")])
15096 ;; Call subroutine, returning value in operand 0
15097 (define_expand "call_value_pop"
15098 [(parallel [(set (match_operand 0 "" "")
15099 (call (match_operand:QI 1 "" "")
15100 (match_operand:SI 2 "" "")))
15101 (set (reg:SI SP_REG)
15102 (plus:SI (reg:SI SP_REG)
15103 (match_operand:SI 4 "" "")))])]
15106 ix86_expand_call (operands[0], operands[1], operands[2],
15107 operands[3], operands[4], 0);
15111 (define_expand "call_value"
15112 [(set (match_operand 0 "" "")
15113 (call (match_operand:QI 1 "" "")
15114 (match_operand:SI 2 "" "")))
15115 (use (match_operand:SI 3 "" ""))]
15116 ;; Operand 2 not used on the i386.
15119 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15123 (define_expand "sibcall_value"
15124 [(set (match_operand 0 "" "")
15125 (call (match_operand:QI 1 "" "")
15126 (match_operand:SI 2 "" "")))
15127 (use (match_operand:SI 3 "" ""))]
15128 ;; Operand 2 not used on the i386.
15131 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15135 ;; Call subroutine returning any type.
15137 (define_expand "untyped_call"
15138 [(parallel [(call (match_operand 0 "" "")
15140 (match_operand 1 "" "")
15141 (match_operand 2 "" "")])]
15146 /* In order to give reg-stack an easier job in validating two
15147 coprocessor registers as containing a possible return value,
15148 simply pretend the untyped call returns a complex long double
15151 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15152 and should have the default ABI. */
15154 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15155 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15156 operands[0], const0_rtx,
15157 GEN_INT ((TARGET_64BIT
15158 ? (DEFAULT_ABI == SYSV_ABI
15159 ? X86_64_SSE_REGPARM_MAX
15160 : X64_SSE_REGPARM_MAX)
15161 : X86_32_SSE_REGPARM_MAX)
15165 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15167 rtx set = XVECEXP (operands[2], 0, i);
15168 emit_move_insn (SET_DEST (set), SET_SRC (set));
15171 /* The optimizer does not know that the call sets the function value
15172 registers we stored in the result block. We avoid problems by
15173 claiming that all hard registers are used and clobbered at this
15175 emit_insn (gen_blockage ());
15180 ;; Prologue and epilogue instructions
15182 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15183 ;; all of memory. This blocks insns from being moved across this point.
15185 (define_insn "blockage"
15186 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15189 [(set_attr "length" "0")])
15191 ;; Do not schedule instructions accessing memory across this point.
15193 (define_expand "memory_blockage"
15194 [(set (match_dup 0)
15195 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15198 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15199 MEM_VOLATILE_P (operands[0]) = 1;
15202 (define_insn "*memory_blockage"
15203 [(set (match_operand:BLK 0 "" "")
15204 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15207 [(set_attr "length" "0")])
15209 ;; As USE insns aren't meaningful after reload, this is used instead
15210 ;; to prevent deleting instructions setting registers for PIC code
15211 (define_insn "prologue_use"
15212 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15215 [(set_attr "length" "0")])
15217 ;; Insn emitted into the body of a function to return from a function.
15218 ;; This is only done if the function's epilogue is known to be simple.
15219 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15221 (define_expand "return"
15223 "ix86_can_use_return_insn_p ()"
15225 if (crtl->args.pops_args)
15227 rtx popc = GEN_INT (crtl->args.pops_args);
15228 emit_jump_insn (gen_return_pop_internal (popc));
15233 (define_insn "return_internal"
15237 [(set_attr "length" "1")
15238 (set_attr "length_immediate" "0")
15239 (set_attr "modrm" "0")])
15241 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15242 ;; instruction Athlon and K8 have.
15244 (define_insn "return_internal_long"
15246 (unspec [(const_int 0)] UNSPEC_REP)]
15249 [(set_attr "length" "1")
15250 (set_attr "length_immediate" "0")
15251 (set_attr "prefix_rep" "1")
15252 (set_attr "modrm" "0")])
15254 (define_insn "return_pop_internal"
15256 (use (match_operand:SI 0 "const_int_operand" ""))]
15259 [(set_attr "length" "3")
15260 (set_attr "length_immediate" "2")
15261 (set_attr "modrm" "0")])
15263 (define_insn "return_indirect_internal"
15265 (use (match_operand:SI 0 "register_operand" "r"))]
15268 [(set_attr "type" "ibr")
15269 (set_attr "length_immediate" "0")])
15275 [(set_attr "length" "1")
15276 (set_attr "length_immediate" "0")
15277 (set_attr "modrm" "0")])
15279 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15280 ;; branch prediction penalty for the third jump in a 16-byte
15283 (define_insn "align"
15284 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15287 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15288 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15290 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15291 The align insn is used to avoid 3 jump instructions in the row to improve
15292 branch prediction and the benefits hardly outweigh the cost of extra 8
15293 nops on the average inserted by full alignment pseudo operation. */
15297 [(set_attr "length" "16")])
15299 (define_expand "prologue"
15302 "ix86_expand_prologue (); DONE;")
15304 (define_insn "set_got"
15305 [(set (match_operand:SI 0 "register_operand" "=r")
15306 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15307 (clobber (reg:CC FLAGS_REG))]
15309 { return output_set_got (operands[0], NULL_RTX); }
15310 [(set_attr "type" "multi")
15311 (set_attr "length" "12")])
15313 (define_insn "set_got_labelled"
15314 [(set (match_operand:SI 0 "register_operand" "=r")
15315 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15317 (clobber (reg:CC FLAGS_REG))]
15319 { return output_set_got (operands[0], operands[1]); }
15320 [(set_attr "type" "multi")
15321 (set_attr "length" "12")])
15323 (define_insn "set_got_rex64"
15324 [(set (match_operand:DI 0 "register_operand" "=r")
15325 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15327 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15328 [(set_attr "type" "lea")
15329 (set_attr "length" "6")])
15331 (define_insn "set_rip_rex64"
15332 [(set (match_operand:DI 0 "register_operand" "=r")
15333 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15335 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15336 [(set_attr "type" "lea")
15337 (set_attr "length" "6")])
15339 (define_insn "set_got_offset_rex64"
15340 [(set (match_operand:DI 0 "register_operand" "=r")
15342 [(label_ref (match_operand 1 "" ""))]
15343 UNSPEC_SET_GOT_OFFSET))]
15345 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15346 [(set_attr "type" "imov")
15347 (set_attr "length" "11")])
15349 (define_expand "epilogue"
15352 "ix86_expand_epilogue (1); DONE;")
15354 (define_expand "sibcall_epilogue"
15357 "ix86_expand_epilogue (0); DONE;")
15359 (define_expand "eh_return"
15360 [(use (match_operand 0 "register_operand" ""))]
15363 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15365 /* Tricky bit: we write the address of the handler to which we will
15366 be returning into someone else's stack frame, one word below the
15367 stack address we wish to restore. */
15368 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15369 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15370 tmp = gen_rtx_MEM (Pmode, tmp);
15371 emit_move_insn (tmp, ra);
15373 if (Pmode == SImode)
15374 emit_jump_insn (gen_eh_return_si (sa));
15376 emit_jump_insn (gen_eh_return_di (sa));
15381 (define_insn_and_split "eh_return_<mode>"
15383 (unspec [(match_operand:P 0 "register_operand" "c")]
15384 UNSPEC_EH_RETURN))]
15389 "ix86_expand_epilogue (2); DONE;")
15391 (define_insn "leave"
15392 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15393 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15394 (clobber (mem:BLK (scratch)))]
15397 [(set_attr "type" "leave")])
15399 (define_insn "leave_rex64"
15400 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15401 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15402 (clobber (mem:BLK (scratch)))]
15405 [(set_attr "type" "leave")])
15407 (define_expand "ffssi2"
15409 [(set (match_operand:SI 0 "register_operand" "")
15410 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15411 (clobber (match_scratch:SI 2 ""))
15412 (clobber (reg:CC FLAGS_REG))])]
15417 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15422 (define_expand "ffs_cmove"
15423 [(set (match_dup 2) (const_int -1))
15424 (parallel [(set (reg:CCZ FLAGS_REG)
15425 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15427 (set (match_operand:SI 0 "register_operand" "")
15428 (ctz:SI (match_dup 1)))])
15429 (set (match_dup 0) (if_then_else:SI
15430 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15433 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15434 (clobber (reg:CC FLAGS_REG))])]
15436 "operands[2] = gen_reg_rtx (SImode);")
15438 (define_insn_and_split "*ffs_no_cmove"
15439 [(set (match_operand:SI 0 "register_operand" "=r")
15440 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15441 (clobber (match_scratch:SI 2 "=&q"))
15442 (clobber (reg:CC FLAGS_REG))]
15445 "&& reload_completed"
15446 [(parallel [(set (reg:CCZ FLAGS_REG)
15447 (compare:CCZ (match_dup 1) (const_int 0)))
15448 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15449 (set (strict_low_part (match_dup 3))
15450 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15451 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15452 (clobber (reg:CC FLAGS_REG))])
15453 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15454 (clobber (reg:CC FLAGS_REG))])
15455 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15456 (clobber (reg:CC FLAGS_REG))])]
15458 operands[3] = gen_lowpart (QImode, operands[2]);
15459 ix86_expand_clear (operands[2]);
15462 (define_insn "*ffssi_1"
15463 [(set (reg:CCZ FLAGS_REG)
15464 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15466 (set (match_operand:SI 0 "register_operand" "=r")
15467 (ctz:SI (match_dup 1)))]
15469 "bsf{l}\t{%1, %0|%0, %1}"
15470 [(set_attr "prefix_0f" "1")])
15472 (define_expand "ffsdi2"
15473 [(set (match_dup 2) (const_int -1))
15474 (parallel [(set (reg:CCZ FLAGS_REG)
15475 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15477 (set (match_operand:DI 0 "register_operand" "")
15478 (ctz:DI (match_dup 1)))])
15479 (set (match_dup 0) (if_then_else:DI
15480 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15483 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15484 (clobber (reg:CC FLAGS_REG))])]
15486 "operands[2] = gen_reg_rtx (DImode);")
15488 (define_insn "*ffsdi_1"
15489 [(set (reg:CCZ FLAGS_REG)
15490 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15492 (set (match_operand:DI 0 "register_operand" "=r")
15493 (ctz:DI (match_dup 1)))]
15495 "bsf{q}\t{%1, %0|%0, %1}"
15496 [(set_attr "prefix_0f" "1")])
15498 (define_insn "ctzsi2"
15499 [(set (match_operand:SI 0 "register_operand" "=r")
15500 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15501 (clobber (reg:CC FLAGS_REG))]
15503 "bsf{l}\t{%1, %0|%0, %1}"
15504 [(set_attr "prefix_0f" "1")])
15506 (define_insn "ctzdi2"
15507 [(set (match_operand:DI 0 "register_operand" "=r")
15508 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15509 (clobber (reg:CC FLAGS_REG))]
15511 "bsf{q}\t{%1, %0|%0, %1}"
15512 [(set_attr "prefix_0f" "1")])
15514 (define_expand "clzsi2"
15516 [(set (match_operand:SI 0 "register_operand" "")
15517 (minus:SI (const_int 31)
15518 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15519 (clobber (reg:CC FLAGS_REG))])
15521 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15522 (clobber (reg:CC FLAGS_REG))])]
15527 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15532 (define_insn "clzsi2_abm"
15533 [(set (match_operand:SI 0 "register_operand" "=r")
15534 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15535 (clobber (reg:CC FLAGS_REG))]
15537 "lzcnt{l}\t{%1, %0|%0, %1}"
15538 [(set_attr "prefix_rep" "1")
15539 (set_attr "type" "bitmanip")
15540 (set_attr "mode" "SI")])
15542 (define_insn "*bsr"
15543 [(set (match_operand:SI 0 "register_operand" "=r")
15544 (minus:SI (const_int 31)
15545 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15546 (clobber (reg:CC FLAGS_REG))]
15548 "bsr{l}\t{%1, %0|%0, %1}"
15549 [(set_attr "prefix_0f" "1")
15550 (set_attr "mode" "SI")])
15552 (define_insn "popcount<mode>2"
15553 [(set (match_operand:SWI248 0 "register_operand" "=r")
15555 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15556 (clobber (reg:CC FLAGS_REG))]
15560 return "popcnt\t{%1, %0|%0, %1}";
15562 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15565 [(set_attr "prefix_rep" "1")
15566 (set_attr "type" "bitmanip")
15567 (set_attr "mode" "<MODE>")])
15569 (define_insn "*popcount<mode>2_cmp"
15570 [(set (reg FLAGS_REG)
15573 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15575 (set (match_operand:SWI248 0 "register_operand" "=r")
15576 (popcount:SWI248 (match_dup 1)))]
15577 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15580 return "popcnt\t{%1, %0|%0, %1}";
15582 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15585 [(set_attr "prefix_rep" "1")
15586 (set_attr "type" "bitmanip")
15587 (set_attr "mode" "<MODE>")])
15589 (define_insn "*popcountsi2_cmp_zext"
15590 [(set (reg FLAGS_REG)
15592 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15594 (set (match_operand:DI 0 "register_operand" "=r")
15595 (zero_extend:DI(popcount:SI (match_dup 1))))]
15596 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15599 return "popcnt\t{%1, %0|%0, %1}";
15601 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15604 [(set_attr "prefix_rep" "1")
15605 (set_attr "type" "bitmanip")
15606 (set_attr "mode" "SI")])
15608 (define_expand "bswapsi2"
15609 [(set (match_operand:SI 0 "register_operand" "")
15610 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15615 rtx x = operands[0];
15617 emit_move_insn (x, operands[1]);
15618 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15619 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15620 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15625 (define_insn "*bswapsi_1"
15626 [(set (match_operand:SI 0 "register_operand" "=r")
15627 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15630 [(set_attr "prefix_0f" "1")
15631 (set_attr "length" "2")])
15633 (define_insn "*bswaphi_lowpart_1"
15634 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15635 (bswap:HI (match_dup 0)))
15636 (clobber (reg:CC FLAGS_REG))]
15637 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15639 xchg{b}\t{%h0, %b0|%b0, %h0}
15640 rol{w}\t{$8, %0|%0, 8}"
15641 [(set_attr "length" "2,4")
15642 (set_attr "mode" "QI,HI")])
15644 (define_insn "bswaphi_lowpart"
15645 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15646 (bswap:HI (match_dup 0)))
15647 (clobber (reg:CC FLAGS_REG))]
15649 "rol{w}\t{$8, %0|%0, 8}"
15650 [(set_attr "length" "4")
15651 (set_attr "mode" "HI")])
15653 (define_insn "bswapdi2"
15654 [(set (match_operand:DI 0 "register_operand" "=r")
15655 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15658 [(set_attr "prefix_0f" "1")
15659 (set_attr "length" "3")])
15661 (define_expand "clzdi2"
15663 [(set (match_operand:DI 0 "register_operand" "")
15664 (minus:DI (const_int 63)
15665 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15666 (clobber (reg:CC FLAGS_REG))])
15668 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15669 (clobber (reg:CC FLAGS_REG))])]
15674 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15679 (define_insn "clzdi2_abm"
15680 [(set (match_operand:DI 0 "register_operand" "=r")
15681 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15682 (clobber (reg:CC FLAGS_REG))]
15683 "TARGET_64BIT && TARGET_ABM"
15684 "lzcnt{q}\t{%1, %0|%0, %1}"
15685 [(set_attr "prefix_rep" "1")
15686 (set_attr "type" "bitmanip")
15687 (set_attr "mode" "DI")])
15689 (define_insn "*bsr_rex64"
15690 [(set (match_operand:DI 0 "register_operand" "=r")
15691 (minus:DI (const_int 63)
15692 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15693 (clobber (reg:CC FLAGS_REG))]
15695 "bsr{q}\t{%1, %0|%0, %1}"
15696 [(set_attr "prefix_0f" "1")
15697 (set_attr "mode" "DI")])
15699 (define_expand "clzhi2"
15701 [(set (match_operand:HI 0 "register_operand" "")
15702 (minus:HI (const_int 15)
15703 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15704 (clobber (reg:CC FLAGS_REG))])
15706 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15707 (clobber (reg:CC FLAGS_REG))])]
15712 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15717 (define_insn "clzhi2_abm"
15718 [(set (match_operand:HI 0 "register_operand" "=r")
15719 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15720 (clobber (reg:CC FLAGS_REG))]
15722 "lzcnt{w}\t{%1, %0|%0, %1}"
15723 [(set_attr "prefix_rep" "1")
15724 (set_attr "type" "bitmanip")
15725 (set_attr "mode" "HI")])
15727 (define_insn "*bsrhi"
15728 [(set (match_operand:HI 0 "register_operand" "=r")
15729 (minus:HI (const_int 15)
15730 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15731 (clobber (reg:CC FLAGS_REG))]
15733 "bsr{w}\t{%1, %0|%0, %1}"
15734 [(set_attr "prefix_0f" "1")
15735 (set_attr "mode" "HI")])
15737 (define_expand "paritydi2"
15738 [(set (match_operand:DI 0 "register_operand" "")
15739 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15742 rtx scratch = gen_reg_rtx (QImode);
15745 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15746 NULL_RTX, operands[1]));
15748 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15749 gen_rtx_REG (CCmode, FLAGS_REG),
15751 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15754 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15757 rtx tmp = gen_reg_rtx (SImode);
15759 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15760 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15765 (define_insn_and_split "paritydi2_cmp"
15766 [(set (reg:CC FLAGS_REG)
15767 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15768 (clobber (match_scratch:DI 0 "=r"))
15769 (clobber (match_scratch:SI 1 "=&r"))
15770 (clobber (match_scratch:HI 2 "=Q"))]
15773 "&& reload_completed"
15775 [(set (match_dup 1)
15776 (xor:SI (match_dup 1) (match_dup 4)))
15777 (clobber (reg:CC FLAGS_REG))])
15779 [(set (reg:CC FLAGS_REG)
15780 (parity:CC (match_dup 1)))
15781 (clobber (match_dup 1))
15782 (clobber (match_dup 2))])]
15784 operands[4] = gen_lowpart (SImode, operands[3]);
15788 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15789 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15792 operands[1] = gen_highpart (SImode, operands[3]);
15795 (define_expand "paritysi2"
15796 [(set (match_operand:SI 0 "register_operand" "")
15797 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15800 rtx scratch = gen_reg_rtx (QImode);
15803 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15805 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15806 gen_rtx_REG (CCmode, FLAGS_REG),
15808 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15810 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15814 (define_insn_and_split "paritysi2_cmp"
15815 [(set (reg:CC FLAGS_REG)
15816 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15817 (clobber (match_scratch:SI 0 "=r"))
15818 (clobber (match_scratch:HI 1 "=&Q"))]
15821 "&& reload_completed"
15823 [(set (match_dup 1)
15824 (xor:HI (match_dup 1) (match_dup 3)))
15825 (clobber (reg:CC FLAGS_REG))])
15827 [(set (reg:CC FLAGS_REG)
15828 (parity:CC (match_dup 1)))
15829 (clobber (match_dup 1))])]
15831 operands[3] = gen_lowpart (HImode, operands[2]);
15833 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15834 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15837 (define_insn "*parityhi2_cmp"
15838 [(set (reg:CC FLAGS_REG)
15839 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15840 (clobber (match_scratch:HI 0 "=Q"))]
15842 "xor{b}\t{%h0, %b0|%b0, %h0}"
15843 [(set_attr "length" "2")
15844 (set_attr "mode" "HI")])
15846 (define_insn "*parityqi2_cmp"
15847 [(set (reg:CC FLAGS_REG)
15848 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15851 [(set_attr "length" "2")
15852 (set_attr "mode" "QI")])
15854 ;; Thread-local storage patterns for ELF.
15856 ;; Note that these code sequences must appear exactly as shown
15857 ;; in order to allow linker relaxation.
15859 (define_insn "*tls_global_dynamic_32_gnu"
15860 [(set (match_operand:SI 0 "register_operand" "=a")
15861 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15862 (match_operand:SI 2 "tls_symbolic_operand" "")
15863 (match_operand:SI 3 "call_insn_operand" "")]
15865 (clobber (match_scratch:SI 4 "=d"))
15866 (clobber (match_scratch:SI 5 "=c"))
15867 (clobber (reg:CC FLAGS_REG))]
15868 "!TARGET_64BIT && TARGET_GNU_TLS"
15869 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15870 [(set_attr "type" "multi")
15871 (set_attr "length" "12")])
15873 (define_insn "*tls_global_dynamic_32_sun"
15874 [(set (match_operand:SI 0 "register_operand" "=a")
15875 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15876 (match_operand:SI 2 "tls_symbolic_operand" "")
15877 (match_operand:SI 3 "call_insn_operand" "")]
15879 (clobber (match_scratch:SI 4 "=d"))
15880 (clobber (match_scratch:SI 5 "=c"))
15881 (clobber (reg:CC FLAGS_REG))]
15882 "!TARGET_64BIT && TARGET_SUN_TLS"
15883 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15884 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15885 [(set_attr "type" "multi")
15886 (set_attr "length" "14")])
15888 (define_expand "tls_global_dynamic_32"
15889 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15892 (match_operand:SI 1 "tls_symbolic_operand" "")
15895 (clobber (match_scratch:SI 4 ""))
15896 (clobber (match_scratch:SI 5 ""))
15897 (clobber (reg:CC FLAGS_REG))])]
15901 operands[2] = pic_offset_table_rtx;
15904 operands[2] = gen_reg_rtx (Pmode);
15905 emit_insn (gen_set_got (operands[2]));
15907 if (TARGET_GNU2_TLS)
15909 emit_insn (gen_tls_dynamic_gnu2_32
15910 (operands[0], operands[1], operands[2]));
15913 operands[3] = ix86_tls_get_addr ();
15916 (define_insn "*tls_global_dynamic_64"
15917 [(set (match_operand:DI 0 "register_operand" "=a")
15918 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15919 (match_operand:DI 3 "" "")))
15920 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15923 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15924 [(set_attr "type" "multi")
15925 (set_attr "length" "16")])
15927 (define_expand "tls_global_dynamic_64"
15928 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15929 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15930 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15934 if (TARGET_GNU2_TLS)
15936 emit_insn (gen_tls_dynamic_gnu2_64
15937 (operands[0], operands[1]));
15940 operands[2] = ix86_tls_get_addr ();
15943 (define_insn "*tls_local_dynamic_base_32_gnu"
15944 [(set (match_operand:SI 0 "register_operand" "=a")
15945 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15946 (match_operand:SI 2 "call_insn_operand" "")]
15947 UNSPEC_TLS_LD_BASE))
15948 (clobber (match_scratch:SI 3 "=d"))
15949 (clobber (match_scratch:SI 4 "=c"))
15950 (clobber (reg:CC FLAGS_REG))]
15951 "!TARGET_64BIT && TARGET_GNU_TLS"
15952 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15953 [(set_attr "type" "multi")
15954 (set_attr "length" "11")])
15956 (define_insn "*tls_local_dynamic_base_32_sun"
15957 [(set (match_operand:SI 0 "register_operand" "=a")
15958 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15959 (match_operand:SI 2 "call_insn_operand" "")]
15960 UNSPEC_TLS_LD_BASE))
15961 (clobber (match_scratch:SI 3 "=d"))
15962 (clobber (match_scratch:SI 4 "=c"))
15963 (clobber (reg:CC FLAGS_REG))]
15964 "!TARGET_64BIT && TARGET_SUN_TLS"
15965 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15966 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15967 [(set_attr "type" "multi")
15968 (set_attr "length" "13")])
15970 (define_expand "tls_local_dynamic_base_32"
15971 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15972 (unspec:SI [(match_dup 1) (match_dup 2)]
15973 UNSPEC_TLS_LD_BASE))
15974 (clobber (match_scratch:SI 3 ""))
15975 (clobber (match_scratch:SI 4 ""))
15976 (clobber (reg:CC FLAGS_REG))])]
15980 operands[1] = pic_offset_table_rtx;
15983 operands[1] = gen_reg_rtx (Pmode);
15984 emit_insn (gen_set_got (operands[1]));
15986 if (TARGET_GNU2_TLS)
15988 emit_insn (gen_tls_dynamic_gnu2_32
15989 (operands[0], ix86_tls_module_base (), operands[1]));
15992 operands[2] = ix86_tls_get_addr ();
15995 (define_insn "*tls_local_dynamic_base_64"
15996 [(set (match_operand:DI 0 "register_operand" "=a")
15997 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15998 (match_operand:DI 2 "" "")))
15999 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16001 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16002 [(set_attr "type" "multi")
16003 (set_attr "length" "12")])
16005 (define_expand "tls_local_dynamic_base_64"
16006 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16007 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16008 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16011 if (TARGET_GNU2_TLS)
16013 emit_insn (gen_tls_dynamic_gnu2_64
16014 (operands[0], ix86_tls_module_base ()));
16017 operands[1] = ix86_tls_get_addr ();
16020 ;; Local dynamic of a single variable is a lose. Show combine how
16021 ;; to convert that back to global dynamic.
16023 (define_insn_and_split "*tls_local_dynamic_32_once"
16024 [(set (match_operand:SI 0 "register_operand" "=a")
16025 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16026 (match_operand:SI 2 "call_insn_operand" "")]
16027 UNSPEC_TLS_LD_BASE)
16028 (const:SI (unspec:SI
16029 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16031 (clobber (match_scratch:SI 4 "=d"))
16032 (clobber (match_scratch:SI 5 "=c"))
16033 (clobber (reg:CC FLAGS_REG))]
16037 [(parallel [(set (match_dup 0)
16038 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16040 (clobber (match_dup 4))
16041 (clobber (match_dup 5))
16042 (clobber (reg:CC FLAGS_REG))])]
16045 ;; Load and add the thread base pointer from %gs:0.
16047 (define_insn "*load_tp_si"
16048 [(set (match_operand:SI 0 "register_operand" "=r")
16049 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16051 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16052 [(set_attr "type" "imov")
16053 (set_attr "modrm" "0")
16054 (set_attr "length" "7")
16055 (set_attr "memory" "load")
16056 (set_attr "imm_disp" "false")])
16058 (define_insn "*add_tp_si"
16059 [(set (match_operand:SI 0 "register_operand" "=r")
16060 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16061 (match_operand:SI 1 "register_operand" "0")))
16062 (clobber (reg:CC FLAGS_REG))]
16064 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16065 [(set_attr "type" "alu")
16066 (set_attr "modrm" "0")
16067 (set_attr "length" "7")
16068 (set_attr "memory" "load")
16069 (set_attr "imm_disp" "false")])
16071 (define_insn "*load_tp_di"
16072 [(set (match_operand:DI 0 "register_operand" "=r")
16073 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16075 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16076 [(set_attr "type" "imov")
16077 (set_attr "modrm" "0")
16078 (set_attr "length" "7")
16079 (set_attr "memory" "load")
16080 (set_attr "imm_disp" "false")])
16082 (define_insn "*add_tp_di"
16083 [(set (match_operand:DI 0 "register_operand" "=r")
16084 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16085 (match_operand:DI 1 "register_operand" "0")))
16086 (clobber (reg:CC FLAGS_REG))]
16088 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16089 [(set_attr "type" "alu")
16090 (set_attr "modrm" "0")
16091 (set_attr "length" "7")
16092 (set_attr "memory" "load")
16093 (set_attr "imm_disp" "false")])
16095 ;; GNU2 TLS patterns can be split.
16097 (define_expand "tls_dynamic_gnu2_32"
16098 [(set (match_dup 3)
16099 (plus:SI (match_operand:SI 2 "register_operand" "")
16101 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16104 [(set (match_operand:SI 0 "register_operand" "")
16105 (unspec:SI [(match_dup 1) (match_dup 3)
16106 (match_dup 2) (reg:SI SP_REG)]
16108 (clobber (reg:CC FLAGS_REG))])]
16109 "!TARGET_64BIT && TARGET_GNU2_TLS"
16111 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16112 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16115 (define_insn "*tls_dynamic_lea_32"
16116 [(set (match_operand:SI 0 "register_operand" "=r")
16117 (plus:SI (match_operand:SI 1 "register_operand" "b")
16119 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16120 UNSPEC_TLSDESC))))]
16121 "!TARGET_64BIT && TARGET_GNU2_TLS"
16122 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16123 [(set_attr "type" "lea")
16124 (set_attr "mode" "SI")
16125 (set_attr "length" "6")
16126 (set_attr "length_address" "4")])
16128 (define_insn "*tls_dynamic_call_32"
16129 [(set (match_operand:SI 0 "register_operand" "=a")
16130 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16131 (match_operand:SI 2 "register_operand" "0")
16132 ;; we have to make sure %ebx still points to the GOT
16133 (match_operand:SI 3 "register_operand" "b")
16136 (clobber (reg:CC FLAGS_REG))]
16137 "!TARGET_64BIT && TARGET_GNU2_TLS"
16138 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16139 [(set_attr "type" "call")
16140 (set_attr "length" "2")
16141 (set_attr "length_address" "0")])
16143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16144 [(set (match_operand:SI 0 "register_operand" "=&a")
16146 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16147 (match_operand:SI 4 "" "")
16148 (match_operand:SI 2 "register_operand" "b")
16151 (const:SI (unspec:SI
16152 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16154 (clobber (reg:CC FLAGS_REG))]
16155 "!TARGET_64BIT && TARGET_GNU2_TLS"
16158 [(set (match_dup 0) (match_dup 5))]
16160 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16161 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16164 (define_expand "tls_dynamic_gnu2_64"
16165 [(set (match_dup 2)
16166 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16169 [(set (match_operand:DI 0 "register_operand" "")
16170 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16172 (clobber (reg:CC FLAGS_REG))])]
16173 "TARGET_64BIT && TARGET_GNU2_TLS"
16175 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16176 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16179 (define_insn "*tls_dynamic_lea_64"
16180 [(set (match_operand:DI 0 "register_operand" "=r")
16181 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16183 "TARGET_64BIT && TARGET_GNU2_TLS"
16184 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16185 [(set_attr "type" "lea")
16186 (set_attr "mode" "DI")
16187 (set_attr "length" "7")
16188 (set_attr "length_address" "4")])
16190 (define_insn "*tls_dynamic_call_64"
16191 [(set (match_operand:DI 0 "register_operand" "=a")
16192 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16193 (match_operand:DI 2 "register_operand" "0")
16196 (clobber (reg:CC FLAGS_REG))]
16197 "TARGET_64BIT && TARGET_GNU2_TLS"
16198 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16199 [(set_attr "type" "call")
16200 (set_attr "length" "2")
16201 (set_attr "length_address" "0")])
16203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16204 [(set (match_operand:DI 0 "register_operand" "=&a")
16206 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16207 (match_operand:DI 3 "" "")
16210 (const:DI (unspec:DI
16211 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16213 (clobber (reg:CC FLAGS_REG))]
16214 "TARGET_64BIT && TARGET_GNU2_TLS"
16217 [(set (match_dup 0) (match_dup 4))]
16219 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16220 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16225 ;; These patterns match the binary 387 instructions for addM3, subM3,
16226 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16227 ;; SFmode. The first is the normal insn, the second the same insn but
16228 ;; with one operand a conversion, and the third the same insn but with
16229 ;; the other operand a conversion. The conversion may be SFmode or
16230 ;; SImode if the target mode DFmode, but only SImode if the target mode
16233 ;; Gcc is slightly more smart about handling normal two address instructions
16234 ;; so use special patterns for add and mull.
16236 (define_insn "*fop_<mode>_comm_mixed_avx"
16237 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16238 (match_operator:MODEF 3 "binary_fp_operator"
16239 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16241 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16242 && COMMUTATIVE_ARITH_P (operands[3])
16243 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16244 "* return output_387_binary_op (insn, operands);"
16245 [(set (attr "type")
16246 (if_then_else (eq_attr "alternative" "1")
16247 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16248 (const_string "ssemul")
16249 (const_string "sseadd"))
16250 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251 (const_string "fmul")
16252 (const_string "fop"))))
16253 (set_attr "prefix" "orig,maybe_vex")
16254 (set_attr "mode" "<MODE>")])
16256 (define_insn "*fop_<mode>_comm_mixed"
16257 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16258 (match_operator:MODEF 3 "binary_fp_operator"
16259 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16262 && COMMUTATIVE_ARITH_P (operands[3])
16263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16264 "* return output_387_binary_op (insn, operands);"
16265 [(set (attr "type")
16266 (if_then_else (eq_attr "alternative" "1")
16267 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16268 (const_string "ssemul")
16269 (const_string "sseadd"))
16270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271 (const_string "fmul")
16272 (const_string "fop"))))
16273 (set_attr "mode" "<MODE>")])
16275 (define_insn "*fop_<mode>_comm_avx"
16276 [(set (match_operand:MODEF 0 "register_operand" "=x")
16277 (match_operator:MODEF 3 "binary_fp_operator"
16278 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16279 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16280 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16281 && COMMUTATIVE_ARITH_P (operands[3])
16282 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16283 "* return output_387_binary_op (insn, operands);"
16284 [(set (attr "type")
16285 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16286 (const_string "ssemul")
16287 (const_string "sseadd")))
16288 (set_attr "prefix" "vex")
16289 (set_attr "mode" "<MODE>")])
16291 (define_insn "*fop_<mode>_comm_sse"
16292 [(set (match_operand:MODEF 0 "register_operand" "=x")
16293 (match_operator:MODEF 3 "binary_fp_operator"
16294 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16295 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16297 && COMMUTATIVE_ARITH_P (operands[3])
16298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299 "* return output_387_binary_op (insn, operands);"
16300 [(set (attr "type")
16301 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16302 (const_string "ssemul")
16303 (const_string "sseadd")))
16304 (set_attr "mode" "<MODE>")])
16306 (define_insn "*fop_<mode>_comm_i387"
16307 [(set (match_operand:MODEF 0 "register_operand" "=f")
16308 (match_operator:MODEF 3 "binary_fp_operator"
16309 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16310 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16312 && COMMUTATIVE_ARITH_P (operands[3])
16313 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16314 "* return output_387_binary_op (insn, operands);"
16315 [(set (attr "type")
16316 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16317 (const_string "fmul")
16318 (const_string "fop")))
16319 (set_attr "mode" "<MODE>")])
16321 (define_insn "*fop_<mode>_1_mixed_avx"
16322 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16323 (match_operator:MODEF 3 "binary_fp_operator"
16324 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16325 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16326 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16327 && !COMMUTATIVE_ARITH_P (operands[3])
16328 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16329 "* return output_387_binary_op (insn, operands);"
16330 [(set (attr "type")
16331 (cond [(and (eq_attr "alternative" "2")
16332 (match_operand:MODEF 3 "mult_operator" ""))
16333 (const_string "ssemul")
16334 (and (eq_attr "alternative" "2")
16335 (match_operand:MODEF 3 "div_operator" ""))
16336 (const_string "ssediv")
16337 (eq_attr "alternative" "2")
16338 (const_string "sseadd")
16339 (match_operand:MODEF 3 "mult_operator" "")
16340 (const_string "fmul")
16341 (match_operand:MODEF 3 "div_operator" "")
16342 (const_string "fdiv")
16344 (const_string "fop")))
16345 (set_attr "prefix" "orig,orig,maybe_vex")
16346 (set_attr "mode" "<MODE>")])
16348 (define_insn "*fop_<mode>_1_mixed"
16349 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16350 (match_operator:MODEF 3 "binary_fp_operator"
16351 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16352 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16353 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16354 && !COMMUTATIVE_ARITH_P (operands[3])
16355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16356 "* return output_387_binary_op (insn, operands);"
16357 [(set (attr "type")
16358 (cond [(and (eq_attr "alternative" "2")
16359 (match_operand:MODEF 3 "mult_operator" ""))
16360 (const_string "ssemul")
16361 (and (eq_attr "alternative" "2")
16362 (match_operand:MODEF 3 "div_operator" ""))
16363 (const_string "ssediv")
16364 (eq_attr "alternative" "2")
16365 (const_string "sseadd")
16366 (match_operand:MODEF 3 "mult_operator" "")
16367 (const_string "fmul")
16368 (match_operand:MODEF 3 "div_operator" "")
16369 (const_string "fdiv")
16371 (const_string "fop")))
16372 (set_attr "mode" "<MODE>")])
16374 (define_insn "*rcpsf2_sse"
16375 [(set (match_operand:SF 0 "register_operand" "=x")
16376 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16379 "%vrcpss\t{%1, %d0|%d0, %1}"
16380 [(set_attr "type" "sse")
16381 (set_attr "prefix" "maybe_vex")
16382 (set_attr "mode" "SF")])
16384 (define_insn "*fop_<mode>_1_avx"
16385 [(set (match_operand:MODEF 0 "register_operand" "=x")
16386 (match_operator:MODEF 3 "binary_fp_operator"
16387 [(match_operand:MODEF 1 "register_operand" "x")
16388 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16389 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16390 && !COMMUTATIVE_ARITH_P (operands[3])"
16391 "* return output_387_binary_op (insn, operands);"
16392 [(set (attr "type")
16393 (cond [(match_operand:MODEF 3 "mult_operator" "")
16394 (const_string "ssemul")
16395 (match_operand:MODEF 3 "div_operator" "")
16396 (const_string "ssediv")
16398 (const_string "sseadd")))
16399 (set_attr "prefix" "vex")
16400 (set_attr "mode" "<MODE>")])
16402 (define_insn "*fop_<mode>_1_sse"
16403 [(set (match_operand:MODEF 0 "register_operand" "=x")
16404 (match_operator:MODEF 3 "binary_fp_operator"
16405 [(match_operand:MODEF 1 "register_operand" "0")
16406 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16407 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16408 && !COMMUTATIVE_ARITH_P (operands[3])"
16409 "* return output_387_binary_op (insn, operands);"
16410 [(set (attr "type")
16411 (cond [(match_operand:MODEF 3 "mult_operator" "")
16412 (const_string "ssemul")
16413 (match_operand:MODEF 3 "div_operator" "")
16414 (const_string "ssediv")
16416 (const_string "sseadd")))
16417 (set_attr "mode" "<MODE>")])
16419 ;; This pattern is not fully shadowed by the pattern above.
16420 (define_insn "*fop_<mode>_1_i387"
16421 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16422 (match_operator:MODEF 3 "binary_fp_operator"
16423 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16424 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16425 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16426 && !COMMUTATIVE_ARITH_P (operands[3])
16427 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16428 "* return output_387_binary_op (insn, operands);"
16429 [(set (attr "type")
16430 (cond [(match_operand:MODEF 3 "mult_operator" "")
16431 (const_string "fmul")
16432 (match_operand:MODEF 3 "div_operator" "")
16433 (const_string "fdiv")
16435 (const_string "fop")))
16436 (set_attr "mode" "<MODE>")])
16438 ;; ??? Add SSE splitters for these!
16439 (define_insn "*fop_<MODEF:mode>_2_i387"
16440 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16441 (match_operator:MODEF 3 "binary_fp_operator"
16443 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16444 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16445 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16446 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16447 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16448 [(set (attr "type")
16449 (cond [(match_operand:MODEF 3 "mult_operator" "")
16450 (const_string "fmul")
16451 (match_operand:MODEF 3 "div_operator" "")
16452 (const_string "fdiv")
16454 (const_string "fop")))
16455 (set_attr "fp_int_src" "true")
16456 (set_attr "mode" "<X87MODEI12:MODE>")])
16458 (define_insn "*fop_<MODEF:mode>_3_i387"
16459 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16460 (match_operator:MODEF 3 "binary_fp_operator"
16461 [(match_operand:MODEF 1 "register_operand" "0,0")
16463 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16464 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16465 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16466 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16467 [(set (attr "type")
16468 (cond [(match_operand:MODEF 3 "mult_operator" "")
16469 (const_string "fmul")
16470 (match_operand:MODEF 3 "div_operator" "")
16471 (const_string "fdiv")
16473 (const_string "fop")))
16474 (set_attr "fp_int_src" "true")
16475 (set_attr "mode" "<MODE>")])
16477 (define_insn "*fop_df_4_i387"
16478 [(set (match_operand:DF 0 "register_operand" "=f,f")
16479 (match_operator:DF 3 "binary_fp_operator"
16481 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16482 (match_operand:DF 2 "register_operand" "0,f")]))]
16483 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16484 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16485 "* return output_387_binary_op (insn, operands);"
16486 [(set (attr "type")
16487 (cond [(match_operand:DF 3 "mult_operator" "")
16488 (const_string "fmul")
16489 (match_operand:DF 3 "div_operator" "")
16490 (const_string "fdiv")
16492 (const_string "fop")))
16493 (set_attr "mode" "SF")])
16495 (define_insn "*fop_df_5_i387"
16496 [(set (match_operand:DF 0 "register_operand" "=f,f")
16497 (match_operator:DF 3 "binary_fp_operator"
16498 [(match_operand:DF 1 "register_operand" "0,f")
16500 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16501 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16502 "* return output_387_binary_op (insn, operands);"
16503 [(set (attr "type")
16504 (cond [(match_operand:DF 3 "mult_operator" "")
16505 (const_string "fmul")
16506 (match_operand:DF 3 "div_operator" "")
16507 (const_string "fdiv")
16509 (const_string "fop")))
16510 (set_attr "mode" "SF")])
16512 (define_insn "*fop_df_6_i387"
16513 [(set (match_operand:DF 0 "register_operand" "=f,f")
16514 (match_operator:DF 3 "binary_fp_operator"
16516 (match_operand:SF 1 "register_operand" "0,f"))
16518 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16519 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16520 "* return output_387_binary_op (insn, operands);"
16521 [(set (attr "type")
16522 (cond [(match_operand:DF 3 "mult_operator" "")
16523 (const_string "fmul")
16524 (match_operand:DF 3 "div_operator" "")
16525 (const_string "fdiv")
16527 (const_string "fop")))
16528 (set_attr "mode" "SF")])
16530 (define_insn "*fop_xf_comm_i387"
16531 [(set (match_operand:XF 0 "register_operand" "=f")
16532 (match_operator:XF 3 "binary_fp_operator"
16533 [(match_operand:XF 1 "register_operand" "%0")
16534 (match_operand:XF 2 "register_operand" "f")]))]
16536 && COMMUTATIVE_ARITH_P (operands[3])"
16537 "* return output_387_binary_op (insn, operands);"
16538 [(set (attr "type")
16539 (if_then_else (match_operand:XF 3 "mult_operator" "")
16540 (const_string "fmul")
16541 (const_string "fop")))
16542 (set_attr "mode" "XF")])
16544 (define_insn "*fop_xf_1_i387"
16545 [(set (match_operand:XF 0 "register_operand" "=f,f")
16546 (match_operator:XF 3 "binary_fp_operator"
16547 [(match_operand:XF 1 "register_operand" "0,f")
16548 (match_operand:XF 2 "register_operand" "f,0")]))]
16550 && !COMMUTATIVE_ARITH_P (operands[3])"
16551 "* return output_387_binary_op (insn, operands);"
16552 [(set (attr "type")
16553 (cond [(match_operand:XF 3 "mult_operator" "")
16554 (const_string "fmul")
16555 (match_operand:XF 3 "div_operator" "")
16556 (const_string "fdiv")
16558 (const_string "fop")))
16559 (set_attr "mode" "XF")])
16561 (define_insn "*fop_xf_2_i387"
16562 [(set (match_operand:XF 0 "register_operand" "=f,f")
16563 (match_operator:XF 3 "binary_fp_operator"
16565 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16566 (match_operand:XF 2 "register_operand" "0,0")]))]
16567 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16568 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16569 [(set (attr "type")
16570 (cond [(match_operand:XF 3 "mult_operator" "")
16571 (const_string "fmul")
16572 (match_operand:XF 3 "div_operator" "")
16573 (const_string "fdiv")
16575 (const_string "fop")))
16576 (set_attr "fp_int_src" "true")
16577 (set_attr "mode" "<MODE>")])
16579 (define_insn "*fop_xf_3_i387"
16580 [(set (match_operand:XF 0 "register_operand" "=f,f")
16581 (match_operator:XF 3 "binary_fp_operator"
16582 [(match_operand:XF 1 "register_operand" "0,0")
16584 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16585 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16586 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16587 [(set (attr "type")
16588 (cond [(match_operand:XF 3 "mult_operator" "")
16589 (const_string "fmul")
16590 (match_operand:XF 3 "div_operator" "")
16591 (const_string "fdiv")
16593 (const_string "fop")))
16594 (set_attr "fp_int_src" "true")
16595 (set_attr "mode" "<MODE>")])
16597 (define_insn "*fop_xf_4_i387"
16598 [(set (match_operand:XF 0 "register_operand" "=f,f")
16599 (match_operator:XF 3 "binary_fp_operator"
16601 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16602 (match_operand:XF 2 "register_operand" "0,f")]))]
16604 "* return output_387_binary_op (insn, operands);"
16605 [(set (attr "type")
16606 (cond [(match_operand:XF 3 "mult_operator" "")
16607 (const_string "fmul")
16608 (match_operand:XF 3 "div_operator" "")
16609 (const_string "fdiv")
16611 (const_string "fop")))
16612 (set_attr "mode" "<MODE>")])
16614 (define_insn "*fop_xf_5_i387"
16615 [(set (match_operand:XF 0 "register_operand" "=f,f")
16616 (match_operator:XF 3 "binary_fp_operator"
16617 [(match_operand:XF 1 "register_operand" "0,f")
16619 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16621 "* return output_387_binary_op (insn, operands);"
16622 [(set (attr "type")
16623 (cond [(match_operand:XF 3 "mult_operator" "")
16624 (const_string "fmul")
16625 (match_operand:XF 3 "div_operator" "")
16626 (const_string "fdiv")
16628 (const_string "fop")))
16629 (set_attr "mode" "<MODE>")])
16631 (define_insn "*fop_xf_6_i387"
16632 [(set (match_operand:XF 0 "register_operand" "=f,f")
16633 (match_operator:XF 3 "binary_fp_operator"
16635 (match_operand:MODEF 1 "register_operand" "0,f"))
16637 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16639 "* return output_387_binary_op (insn, operands);"
16640 [(set (attr "type")
16641 (cond [(match_operand:XF 3 "mult_operator" "")
16642 (const_string "fmul")
16643 (match_operand:XF 3 "div_operator" "")
16644 (const_string "fdiv")
16646 (const_string "fop")))
16647 (set_attr "mode" "<MODE>")])
16650 [(set (match_operand 0 "register_operand" "")
16651 (match_operator 3 "binary_fp_operator"
16652 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16653 (match_operand 2 "register_operand" "")]))]
16655 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16658 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16659 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16660 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16661 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16662 GET_MODE (operands[3]),
16665 ix86_free_from_memory (GET_MODE (operands[1]));
16670 [(set (match_operand 0 "register_operand" "")
16671 (match_operator 3 "binary_fp_operator"
16672 [(match_operand 1 "register_operand" "")
16673 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16675 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16678 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16679 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16680 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16681 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16682 GET_MODE (operands[3]),
16685 ix86_free_from_memory (GET_MODE (operands[2]));
16689 ;; FPU special functions.
16691 ;; This pattern implements a no-op XFmode truncation for
16692 ;; all fancy i386 XFmode math functions.
16694 (define_insn "truncxf<mode>2_i387_noop_unspec"
16695 [(set (match_operand:MODEF 0 "register_operand" "=f")
16696 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16697 UNSPEC_TRUNC_NOOP))]
16698 "TARGET_USE_FANCY_MATH_387"
16699 "* return output_387_reg_move (insn, operands);"
16700 [(set_attr "type" "fmov")
16701 (set_attr "mode" "<MODE>")])
16703 (define_insn "sqrtxf2"
16704 [(set (match_operand:XF 0 "register_operand" "=f")
16705 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16706 "TARGET_USE_FANCY_MATH_387"
16708 [(set_attr "type" "fpspc")
16709 (set_attr "mode" "XF")
16710 (set_attr "athlon_decode" "direct")
16711 (set_attr "amdfam10_decode" "direct")])
16713 (define_insn "sqrt_extend<mode>xf2_i387"
16714 [(set (match_operand:XF 0 "register_operand" "=f")
16717 (match_operand:MODEF 1 "register_operand" "0"))))]
16718 "TARGET_USE_FANCY_MATH_387"
16720 [(set_attr "type" "fpspc")
16721 (set_attr "mode" "XF")
16722 (set_attr "athlon_decode" "direct")
16723 (set_attr "amdfam10_decode" "direct")])
16725 (define_insn "*rsqrtsf2_sse"
16726 [(set (match_operand:SF 0 "register_operand" "=x")
16727 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16730 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16731 [(set_attr "type" "sse")
16732 (set_attr "prefix" "maybe_vex")
16733 (set_attr "mode" "SF")])
16735 (define_expand "rsqrtsf2"
16736 [(set (match_operand:SF 0 "register_operand" "")
16737 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16741 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16745 (define_insn "*sqrt<mode>2_sse"
16746 [(set (match_operand:MODEF 0 "register_operand" "=x")
16748 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16749 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16750 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16751 [(set_attr "type" "sse")
16752 (set_attr "prefix" "maybe_vex")
16753 (set_attr "mode" "<MODE>")
16754 (set_attr "athlon_decode" "*")
16755 (set_attr "amdfam10_decode" "*")])
16757 (define_expand "sqrt<mode>2"
16758 [(set (match_operand:MODEF 0 "register_operand" "")
16760 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16761 "TARGET_USE_FANCY_MATH_387
16762 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16764 if (<MODE>mode == SFmode
16765 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16766 && flag_finite_math_only && !flag_trapping_math
16767 && flag_unsafe_math_optimizations)
16769 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16773 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16775 rtx op0 = gen_reg_rtx (XFmode);
16776 rtx op1 = force_reg (<MODE>mode, operands[1]);
16778 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16779 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16784 (define_insn "fpremxf4_i387"
16785 [(set (match_operand:XF 0 "register_operand" "=f")
16786 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16787 (match_operand:XF 3 "register_operand" "1")]
16789 (set (match_operand:XF 1 "register_operand" "=u")
16790 (unspec:XF [(match_dup 2) (match_dup 3)]
16792 (set (reg:CCFP FPSR_REG)
16793 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16795 "TARGET_USE_FANCY_MATH_387"
16797 [(set_attr "type" "fpspc")
16798 (set_attr "mode" "XF")])
16800 (define_expand "fmodxf3"
16801 [(use (match_operand:XF 0 "register_operand" ""))
16802 (use (match_operand:XF 1 "general_operand" ""))
16803 (use (match_operand:XF 2 "general_operand" ""))]
16804 "TARGET_USE_FANCY_MATH_387"
16806 rtx label = gen_label_rtx ();
16808 rtx op1 = gen_reg_rtx (XFmode);
16809 rtx op2 = gen_reg_rtx (XFmode);
16811 emit_move_insn (op2, operands[2]);
16812 emit_move_insn (op1, operands[1]);
16814 emit_label (label);
16815 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16816 ix86_emit_fp_unordered_jump (label);
16817 LABEL_NUSES (label) = 1;
16819 emit_move_insn (operands[0], op1);
16823 (define_expand "fmod<mode>3"
16824 [(use (match_operand:MODEF 0 "register_operand" ""))
16825 (use (match_operand:MODEF 1 "general_operand" ""))
16826 (use (match_operand:MODEF 2 "general_operand" ""))]
16827 "TARGET_USE_FANCY_MATH_387"
16829 rtx label = gen_label_rtx ();
16831 rtx op1 = gen_reg_rtx (XFmode);
16832 rtx op2 = gen_reg_rtx (XFmode);
16834 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16835 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16837 emit_label (label);
16838 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16839 ix86_emit_fp_unordered_jump (label);
16840 LABEL_NUSES (label) = 1;
16842 /* Truncate the result properly for strict SSE math. */
16843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16844 && !TARGET_MIX_SSE_I387)
16845 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16847 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16852 (define_insn "fprem1xf4_i387"
16853 [(set (match_operand:XF 0 "register_operand" "=f")
16854 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16855 (match_operand:XF 3 "register_operand" "1")]
16857 (set (match_operand:XF 1 "register_operand" "=u")
16858 (unspec:XF [(match_dup 2) (match_dup 3)]
16860 (set (reg:CCFP FPSR_REG)
16861 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16863 "TARGET_USE_FANCY_MATH_387"
16865 [(set_attr "type" "fpspc")
16866 (set_attr "mode" "XF")])
16868 (define_expand "remainderxf3"
16869 [(use (match_operand:XF 0 "register_operand" ""))
16870 (use (match_operand:XF 1 "general_operand" ""))
16871 (use (match_operand:XF 2 "general_operand" ""))]
16872 "TARGET_USE_FANCY_MATH_387"
16874 rtx label = gen_label_rtx ();
16876 rtx op1 = gen_reg_rtx (XFmode);
16877 rtx op2 = gen_reg_rtx (XFmode);
16879 emit_move_insn (op2, operands[2]);
16880 emit_move_insn (op1, operands[1]);
16882 emit_label (label);
16883 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16884 ix86_emit_fp_unordered_jump (label);
16885 LABEL_NUSES (label) = 1;
16887 emit_move_insn (operands[0], op1);
16891 (define_expand "remainder<mode>3"
16892 [(use (match_operand:MODEF 0 "register_operand" ""))
16893 (use (match_operand:MODEF 1 "general_operand" ""))
16894 (use (match_operand:MODEF 2 "general_operand" ""))]
16895 "TARGET_USE_FANCY_MATH_387"
16897 rtx label = gen_label_rtx ();
16899 rtx op1 = gen_reg_rtx (XFmode);
16900 rtx op2 = gen_reg_rtx (XFmode);
16902 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16903 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16905 emit_label (label);
16907 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16908 ix86_emit_fp_unordered_jump (label);
16909 LABEL_NUSES (label) = 1;
16911 /* Truncate the result properly for strict SSE math. */
16912 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16913 && !TARGET_MIX_SSE_I387)
16914 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16916 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16921 (define_insn "*sinxf2_i387"
16922 [(set (match_operand:XF 0 "register_operand" "=f")
16923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16924 "TARGET_USE_FANCY_MATH_387
16925 && flag_unsafe_math_optimizations"
16927 [(set_attr "type" "fpspc")
16928 (set_attr "mode" "XF")])
16930 (define_insn "*sin_extend<mode>xf2_i387"
16931 [(set (match_operand:XF 0 "register_operand" "=f")
16932 (unspec:XF [(float_extend:XF
16933 (match_operand:MODEF 1 "register_operand" "0"))]
16935 "TARGET_USE_FANCY_MATH_387
16936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16937 || TARGET_MIX_SSE_I387)
16938 && flag_unsafe_math_optimizations"
16940 [(set_attr "type" "fpspc")
16941 (set_attr "mode" "XF")])
16943 (define_insn "*cosxf2_i387"
16944 [(set (match_operand:XF 0 "register_operand" "=f")
16945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && flag_unsafe_math_optimizations"
16949 [(set_attr "type" "fpspc")
16950 (set_attr "mode" "XF")])
16952 (define_insn "*cos_extend<mode>xf2_i387"
16953 [(set (match_operand:XF 0 "register_operand" "=f")
16954 (unspec:XF [(float_extend:XF
16955 (match_operand:MODEF 1 "register_operand" "0"))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959 || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16962 [(set_attr "type" "fpspc")
16963 (set_attr "mode" "XF")])
16965 ;; When sincos pattern is defined, sin and cos builtin functions will be
16966 ;; expanded to sincos pattern with one of its outputs left unused.
16967 ;; CSE pass will figure out if two sincos patterns can be combined,
16968 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16969 ;; depending on the unused output.
16971 (define_insn "sincosxf3"
16972 [(set (match_operand:XF 0 "register_operand" "=f")
16973 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16974 UNSPEC_SINCOS_COS))
16975 (set (match_operand:XF 1 "register_operand" "=u")
16976 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16977 "TARGET_USE_FANCY_MATH_387
16978 && flag_unsafe_math_optimizations"
16980 [(set_attr "type" "fpspc")
16981 (set_attr "mode" "XF")])
16984 [(set (match_operand:XF 0 "register_operand" "")
16985 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16986 UNSPEC_SINCOS_COS))
16987 (set (match_operand:XF 1 "register_operand" "")
16988 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16989 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16990 && !(reload_completed || reload_in_progress)"
16991 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16995 [(set (match_operand:XF 0 "register_operand" "")
16996 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16997 UNSPEC_SINCOS_COS))
16998 (set (match_operand:XF 1 "register_operand" "")
16999 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17000 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17001 && !(reload_completed || reload_in_progress)"
17002 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17005 (define_insn "sincos_extend<mode>xf3_i387"
17006 [(set (match_operand:XF 0 "register_operand" "=f")
17007 (unspec:XF [(float_extend:XF
17008 (match_operand:MODEF 2 "register_operand" "0"))]
17009 UNSPEC_SINCOS_COS))
17010 (set (match_operand:XF 1 "register_operand" "=u")
17011 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17012 "TARGET_USE_FANCY_MATH_387
17013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17014 || TARGET_MIX_SSE_I387)
17015 && flag_unsafe_math_optimizations"
17017 [(set_attr "type" "fpspc")
17018 (set_attr "mode" "XF")])
17021 [(set (match_operand:XF 0 "register_operand" "")
17022 (unspec:XF [(float_extend:XF
17023 (match_operand:MODEF 2 "register_operand" ""))]
17024 UNSPEC_SINCOS_COS))
17025 (set (match_operand:XF 1 "register_operand" "")
17026 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17027 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17028 && !(reload_completed || reload_in_progress)"
17029 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17033 [(set (match_operand:XF 0 "register_operand" "")
17034 (unspec:XF [(float_extend:XF
17035 (match_operand:MODEF 2 "register_operand" ""))]
17036 UNSPEC_SINCOS_COS))
17037 (set (match_operand:XF 1 "register_operand" "")
17038 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17039 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17040 && !(reload_completed || reload_in_progress)"
17041 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17044 (define_expand "sincos<mode>3"
17045 [(use (match_operand:MODEF 0 "register_operand" ""))
17046 (use (match_operand:MODEF 1 "register_operand" ""))
17047 (use (match_operand:MODEF 2 "register_operand" ""))]
17048 "TARGET_USE_FANCY_MATH_387
17049 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17050 || TARGET_MIX_SSE_I387)
17051 && flag_unsafe_math_optimizations"
17053 rtx op0 = gen_reg_rtx (XFmode);
17054 rtx op1 = gen_reg_rtx (XFmode);
17056 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17057 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17058 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17062 (define_insn "fptanxf4_i387"
17063 [(set (match_operand:XF 0 "register_operand" "=f")
17064 (match_operand:XF 3 "const_double_operand" "F"))
17065 (set (match_operand:XF 1 "register_operand" "=u")
17066 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17068 "TARGET_USE_FANCY_MATH_387
17069 && flag_unsafe_math_optimizations
17070 && standard_80387_constant_p (operands[3]) == 2"
17072 [(set_attr "type" "fpspc")
17073 (set_attr "mode" "XF")])
17075 (define_insn "fptan_extend<mode>xf4_i387"
17076 [(set (match_operand:MODEF 0 "register_operand" "=f")
17077 (match_operand:MODEF 3 "const_double_operand" "F"))
17078 (set (match_operand:XF 1 "register_operand" "=u")
17079 (unspec:XF [(float_extend:XF
17080 (match_operand:MODEF 2 "register_operand" "0"))]
17082 "TARGET_USE_FANCY_MATH_387
17083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17084 || TARGET_MIX_SSE_I387)
17085 && flag_unsafe_math_optimizations
17086 && standard_80387_constant_p (operands[3]) == 2"
17088 [(set_attr "type" "fpspc")
17089 (set_attr "mode" "XF")])
17091 (define_expand "tanxf2"
17092 [(use (match_operand:XF 0 "register_operand" ""))
17093 (use (match_operand:XF 1 "register_operand" ""))]
17094 "TARGET_USE_FANCY_MATH_387
17095 && flag_unsafe_math_optimizations"
17097 rtx one = gen_reg_rtx (XFmode);
17098 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17100 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17104 (define_expand "tan<mode>2"
17105 [(use (match_operand:MODEF 0 "register_operand" ""))
17106 (use (match_operand:MODEF 1 "register_operand" ""))]
17107 "TARGET_USE_FANCY_MATH_387
17108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17109 || TARGET_MIX_SSE_I387)
17110 && flag_unsafe_math_optimizations"
17112 rtx op0 = gen_reg_rtx (XFmode);
17114 rtx one = gen_reg_rtx (<MODE>mode);
17115 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17117 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17118 operands[1], op2));
17119 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17123 (define_insn "*fpatanxf3_i387"
17124 [(set (match_operand:XF 0 "register_operand" "=f")
17125 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17126 (match_operand:XF 2 "register_operand" "u")]
17128 (clobber (match_scratch:XF 3 "=2"))]
17129 "TARGET_USE_FANCY_MATH_387
17130 && flag_unsafe_math_optimizations"
17132 [(set_attr "type" "fpspc")
17133 (set_attr "mode" "XF")])
17135 (define_insn "fpatan_extend<mode>xf3_i387"
17136 [(set (match_operand:XF 0 "register_operand" "=f")
17137 (unspec:XF [(float_extend:XF
17138 (match_operand:MODEF 1 "register_operand" "0"))
17140 (match_operand:MODEF 2 "register_operand" "u"))]
17142 (clobber (match_scratch:XF 3 "=2"))]
17143 "TARGET_USE_FANCY_MATH_387
17144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17145 || TARGET_MIX_SSE_I387)
17146 && flag_unsafe_math_optimizations"
17148 [(set_attr "type" "fpspc")
17149 (set_attr "mode" "XF")])
17151 (define_expand "atan2xf3"
17152 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17153 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17154 (match_operand:XF 1 "register_operand" "")]
17156 (clobber (match_scratch:XF 3 ""))])]
17157 "TARGET_USE_FANCY_MATH_387
17158 && flag_unsafe_math_optimizations"
17161 (define_expand "atan2<mode>3"
17162 [(use (match_operand:MODEF 0 "register_operand" ""))
17163 (use (match_operand:MODEF 1 "register_operand" ""))
17164 (use (match_operand:MODEF 2 "register_operand" ""))]
17165 "TARGET_USE_FANCY_MATH_387
17166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17167 || TARGET_MIX_SSE_I387)
17168 && flag_unsafe_math_optimizations"
17170 rtx op0 = gen_reg_rtx (XFmode);
17172 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17173 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17177 (define_expand "atanxf2"
17178 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17179 (unspec:XF [(match_dup 2)
17180 (match_operand:XF 1 "register_operand" "")]
17182 (clobber (match_scratch:XF 3 ""))])]
17183 "TARGET_USE_FANCY_MATH_387
17184 && flag_unsafe_math_optimizations"
17186 operands[2] = gen_reg_rtx (XFmode);
17187 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17190 (define_expand "atan<mode>2"
17191 [(use (match_operand:MODEF 0 "register_operand" ""))
17192 (use (match_operand:MODEF 1 "register_operand" ""))]
17193 "TARGET_USE_FANCY_MATH_387
17194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17195 || TARGET_MIX_SSE_I387)
17196 && flag_unsafe_math_optimizations"
17198 rtx op0 = gen_reg_rtx (XFmode);
17200 rtx op2 = gen_reg_rtx (<MODE>mode);
17201 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17203 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17204 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17208 (define_expand "asinxf2"
17209 [(set (match_dup 2)
17210 (mult:XF (match_operand:XF 1 "register_operand" "")
17212 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17213 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17214 (parallel [(set (match_operand:XF 0 "register_operand" "")
17215 (unspec:XF [(match_dup 5) (match_dup 1)]
17217 (clobber (match_scratch:XF 6 ""))])]
17218 "TARGET_USE_FANCY_MATH_387
17219 && flag_unsafe_math_optimizations"
17223 if (optimize_insn_for_size_p ())
17226 for (i = 2; i < 6; i++)
17227 operands[i] = gen_reg_rtx (XFmode);
17229 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17232 (define_expand "asin<mode>2"
17233 [(use (match_operand:MODEF 0 "register_operand" ""))
17234 (use (match_operand:MODEF 1 "general_operand" ""))]
17235 "TARGET_USE_FANCY_MATH_387
17236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17237 || TARGET_MIX_SSE_I387)
17238 && flag_unsafe_math_optimizations"
17240 rtx op0 = gen_reg_rtx (XFmode);
17241 rtx op1 = gen_reg_rtx (XFmode);
17243 if (optimize_insn_for_size_p ())
17246 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17247 emit_insn (gen_asinxf2 (op0, op1));
17248 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17252 (define_expand "acosxf2"
17253 [(set (match_dup 2)
17254 (mult:XF (match_operand:XF 1 "register_operand" "")
17256 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17257 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17258 (parallel [(set (match_operand:XF 0 "register_operand" "")
17259 (unspec:XF [(match_dup 1) (match_dup 5)]
17261 (clobber (match_scratch:XF 6 ""))])]
17262 "TARGET_USE_FANCY_MATH_387
17263 && flag_unsafe_math_optimizations"
17267 if (optimize_insn_for_size_p ())
17270 for (i = 2; i < 6; i++)
17271 operands[i] = gen_reg_rtx (XFmode);
17273 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17276 (define_expand "acos<mode>2"
17277 [(use (match_operand:MODEF 0 "register_operand" ""))
17278 (use (match_operand:MODEF 1 "general_operand" ""))]
17279 "TARGET_USE_FANCY_MATH_387
17280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17281 || TARGET_MIX_SSE_I387)
17282 && flag_unsafe_math_optimizations"
17284 rtx op0 = gen_reg_rtx (XFmode);
17285 rtx op1 = gen_reg_rtx (XFmode);
17287 if (optimize_insn_for_size_p ())
17290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17291 emit_insn (gen_acosxf2 (op0, op1));
17292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296 (define_insn "fyl2xxf3_i387"
17297 [(set (match_operand:XF 0 "register_operand" "=f")
17298 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17299 (match_operand:XF 2 "register_operand" "u")]
17301 (clobber (match_scratch:XF 3 "=2"))]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "XF")])
17308 (define_insn "fyl2x_extend<mode>xf3_i387"
17309 [(set (match_operand:XF 0 "register_operand" "=f")
17310 (unspec:XF [(float_extend:XF
17311 (match_operand:MODEF 1 "register_operand" "0"))
17312 (match_operand:XF 2 "register_operand" "u")]
17314 (clobber (match_scratch:XF 3 "=2"))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317 || TARGET_MIX_SSE_I387)
17318 && flag_unsafe_math_optimizations"
17320 [(set_attr "type" "fpspc")
17321 (set_attr "mode" "XF")])
17323 (define_expand "logxf2"
17324 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17325 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17326 (match_dup 2)] UNSPEC_FYL2X))
17327 (clobber (match_scratch:XF 3 ""))])]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17331 operands[2] = gen_reg_rtx (XFmode);
17332 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17335 (define_expand "log<mode>2"
17336 [(use (match_operand:MODEF 0 "register_operand" ""))
17337 (use (match_operand:MODEF 1 "register_operand" ""))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340 || TARGET_MIX_SSE_I387)
17341 && flag_unsafe_math_optimizations"
17343 rtx op0 = gen_reg_rtx (XFmode);
17345 rtx op2 = gen_reg_rtx (XFmode);
17346 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17348 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353 (define_expand "log10xf2"
17354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17355 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356 (match_dup 2)] UNSPEC_FYL2X))
17357 (clobber (match_scratch:XF 3 ""))])]
17358 "TARGET_USE_FANCY_MATH_387
17359 && flag_unsafe_math_optimizations"
17361 operands[2] = gen_reg_rtx (XFmode);
17362 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17365 (define_expand "log10<mode>2"
17366 [(use (match_operand:MODEF 0 "register_operand" ""))
17367 (use (match_operand:MODEF 1 "register_operand" ""))]
17368 "TARGET_USE_FANCY_MATH_387
17369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370 || TARGET_MIX_SSE_I387)
17371 && flag_unsafe_math_optimizations"
17373 rtx op0 = gen_reg_rtx (XFmode);
17375 rtx op2 = gen_reg_rtx (XFmode);
17376 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17378 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17383 (define_expand "log2xf2"
17384 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17385 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17386 (match_dup 2)] UNSPEC_FYL2X))
17387 (clobber (match_scratch:XF 3 ""))])]
17388 "TARGET_USE_FANCY_MATH_387
17389 && flag_unsafe_math_optimizations"
17391 operands[2] = gen_reg_rtx (XFmode);
17392 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17395 (define_expand "log2<mode>2"
17396 [(use (match_operand:MODEF 0 "register_operand" ""))
17397 (use (match_operand:MODEF 1 "register_operand" ""))]
17398 "TARGET_USE_FANCY_MATH_387
17399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17400 || TARGET_MIX_SSE_I387)
17401 && flag_unsafe_math_optimizations"
17403 rtx op0 = gen_reg_rtx (XFmode);
17405 rtx op2 = gen_reg_rtx (XFmode);
17406 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17408 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17409 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17413 (define_insn "fyl2xp1xf3_i387"
17414 [(set (match_operand:XF 0 "register_operand" "=f")
17415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17416 (match_operand:XF 2 "register_operand" "u")]
17418 (clobber (match_scratch:XF 3 "=2"))]
17419 "TARGET_USE_FANCY_MATH_387
17420 && flag_unsafe_math_optimizations"
17422 [(set_attr "type" "fpspc")
17423 (set_attr "mode" "XF")])
17425 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17426 [(set (match_operand:XF 0 "register_operand" "=f")
17427 (unspec:XF [(float_extend:XF
17428 (match_operand:MODEF 1 "register_operand" "0"))
17429 (match_operand:XF 2 "register_operand" "u")]
17431 (clobber (match_scratch:XF 3 "=2"))]
17432 "TARGET_USE_FANCY_MATH_387
17433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434 || TARGET_MIX_SSE_I387)
17435 && flag_unsafe_math_optimizations"
17437 [(set_attr "type" "fpspc")
17438 (set_attr "mode" "XF")])
17440 (define_expand "log1pxf2"
17441 [(use (match_operand:XF 0 "register_operand" ""))
17442 (use (match_operand:XF 1 "register_operand" ""))]
17443 "TARGET_USE_FANCY_MATH_387
17444 && flag_unsafe_math_optimizations"
17446 if (optimize_insn_for_size_p ())
17449 ix86_emit_i387_log1p (operands[0], operands[1]);
17453 (define_expand "log1p<mode>2"
17454 [(use (match_operand:MODEF 0 "register_operand" ""))
17455 (use (match_operand:MODEF 1 "register_operand" ""))]
17456 "TARGET_USE_FANCY_MATH_387
17457 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17458 || TARGET_MIX_SSE_I387)
17459 && flag_unsafe_math_optimizations"
17463 if (optimize_insn_for_size_p ())
17466 op0 = gen_reg_rtx (XFmode);
17468 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17470 ix86_emit_i387_log1p (op0, operands[1]);
17471 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17475 (define_insn "fxtractxf3_i387"
17476 [(set (match_operand:XF 0 "register_operand" "=f")
17477 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17478 UNSPEC_XTRACT_FRACT))
17479 (set (match_operand:XF 1 "register_operand" "=u")
17480 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17481 "TARGET_USE_FANCY_MATH_387
17482 && flag_unsafe_math_optimizations"
17484 [(set_attr "type" "fpspc")
17485 (set_attr "mode" "XF")])
17487 (define_insn "fxtract_extend<mode>xf3_i387"
17488 [(set (match_operand:XF 0 "register_operand" "=f")
17489 (unspec:XF [(float_extend:XF
17490 (match_operand:MODEF 2 "register_operand" "0"))]
17491 UNSPEC_XTRACT_FRACT))
17492 (set (match_operand:XF 1 "register_operand" "=u")
17493 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17494 "TARGET_USE_FANCY_MATH_387
17495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17496 || TARGET_MIX_SSE_I387)
17497 && flag_unsafe_math_optimizations"
17499 [(set_attr "type" "fpspc")
17500 (set_attr "mode" "XF")])
17502 (define_expand "logbxf2"
17503 [(parallel [(set (match_dup 2)
17504 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17505 UNSPEC_XTRACT_FRACT))
17506 (set (match_operand:XF 0 "register_operand" "")
17507 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17508 "TARGET_USE_FANCY_MATH_387
17509 && flag_unsafe_math_optimizations"
17511 operands[2] = gen_reg_rtx (XFmode);
17514 (define_expand "logb<mode>2"
17515 [(use (match_operand:MODEF 0 "register_operand" ""))
17516 (use (match_operand:MODEF 1 "register_operand" ""))]
17517 "TARGET_USE_FANCY_MATH_387
17518 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17519 || TARGET_MIX_SSE_I387)
17520 && flag_unsafe_math_optimizations"
17522 rtx op0 = gen_reg_rtx (XFmode);
17523 rtx op1 = gen_reg_rtx (XFmode);
17525 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17530 (define_expand "ilogbxf2"
17531 [(use (match_operand:SI 0 "register_operand" ""))
17532 (use (match_operand:XF 1 "register_operand" ""))]
17533 "TARGET_USE_FANCY_MATH_387
17534 && flag_unsafe_math_optimizations"
17538 if (optimize_insn_for_size_p ())
17541 op0 = gen_reg_rtx (XFmode);
17542 op1 = gen_reg_rtx (XFmode);
17544 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17545 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17549 (define_expand "ilogb<mode>2"
17550 [(use (match_operand:SI 0 "register_operand" ""))
17551 (use (match_operand:MODEF 1 "register_operand" ""))]
17552 "TARGET_USE_FANCY_MATH_387
17553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17554 || TARGET_MIX_SSE_I387)
17555 && flag_unsafe_math_optimizations"
17559 if (optimize_insn_for_size_p ())
17562 op0 = gen_reg_rtx (XFmode);
17563 op1 = gen_reg_rtx (XFmode);
17565 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17566 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17570 (define_insn "*f2xm1xf2_i387"
17571 [(set (match_operand:XF 0 "register_operand" "=f")
17572 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17574 "TARGET_USE_FANCY_MATH_387
17575 && flag_unsafe_math_optimizations"
17577 [(set_attr "type" "fpspc")
17578 (set_attr "mode" "XF")])
17580 (define_insn "*fscalexf4_i387"
17581 [(set (match_operand:XF 0 "register_operand" "=f")
17582 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17583 (match_operand:XF 3 "register_operand" "1")]
17584 UNSPEC_FSCALE_FRACT))
17585 (set (match_operand:XF 1 "register_operand" "=u")
17586 (unspec:XF [(match_dup 2) (match_dup 3)]
17587 UNSPEC_FSCALE_EXP))]
17588 "TARGET_USE_FANCY_MATH_387
17589 && flag_unsafe_math_optimizations"
17591 [(set_attr "type" "fpspc")
17592 (set_attr "mode" "XF")])
17594 (define_expand "expNcorexf3"
17595 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17596 (match_operand:XF 2 "register_operand" "")))
17597 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17598 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17599 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17600 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17601 (parallel [(set (match_operand:XF 0 "register_operand" "")
17602 (unspec:XF [(match_dup 8) (match_dup 4)]
17603 UNSPEC_FSCALE_FRACT))
17605 (unspec:XF [(match_dup 8) (match_dup 4)]
17606 UNSPEC_FSCALE_EXP))])]
17607 "TARGET_USE_FANCY_MATH_387
17608 && flag_unsafe_math_optimizations"
17612 if (optimize_insn_for_size_p ())
17615 for (i = 3; i < 10; i++)
17616 operands[i] = gen_reg_rtx (XFmode);
17618 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17621 (define_expand "expxf2"
17622 [(use (match_operand:XF 0 "register_operand" ""))
17623 (use (match_operand:XF 1 "register_operand" ""))]
17624 "TARGET_USE_FANCY_MATH_387
17625 && flag_unsafe_math_optimizations"
17629 if (optimize_insn_for_size_p ())
17632 op2 = gen_reg_rtx (XFmode);
17633 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17635 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17639 (define_expand "exp<mode>2"
17640 [(use (match_operand:MODEF 0 "register_operand" ""))
17641 (use (match_operand:MODEF 1 "general_operand" ""))]
17642 "TARGET_USE_FANCY_MATH_387
17643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17644 || TARGET_MIX_SSE_I387)
17645 && flag_unsafe_math_optimizations"
17649 if (optimize_insn_for_size_p ())
17652 op0 = gen_reg_rtx (XFmode);
17653 op1 = gen_reg_rtx (XFmode);
17655 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17656 emit_insn (gen_expxf2 (op0, op1));
17657 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17661 (define_expand "exp10xf2"
17662 [(use (match_operand:XF 0 "register_operand" ""))
17663 (use (match_operand:XF 1 "register_operand" ""))]
17664 "TARGET_USE_FANCY_MATH_387
17665 && flag_unsafe_math_optimizations"
17669 if (optimize_insn_for_size_p ())
17672 op2 = gen_reg_rtx (XFmode);
17673 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17675 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17679 (define_expand "exp10<mode>2"
17680 [(use (match_operand:MODEF 0 "register_operand" ""))
17681 (use (match_operand:MODEF 1 "general_operand" ""))]
17682 "TARGET_USE_FANCY_MATH_387
17683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17684 || TARGET_MIX_SSE_I387)
17685 && flag_unsafe_math_optimizations"
17689 if (optimize_insn_for_size_p ())
17692 op0 = gen_reg_rtx (XFmode);
17693 op1 = gen_reg_rtx (XFmode);
17695 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17696 emit_insn (gen_exp10xf2 (op0, op1));
17697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17701 (define_expand "exp2xf2"
17702 [(use (match_operand:XF 0 "register_operand" ""))
17703 (use (match_operand:XF 1 "register_operand" ""))]
17704 "TARGET_USE_FANCY_MATH_387
17705 && flag_unsafe_math_optimizations"
17709 if (optimize_insn_for_size_p ())
17712 op2 = gen_reg_rtx (XFmode);
17713 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17715 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17719 (define_expand "exp2<mode>2"
17720 [(use (match_operand:MODEF 0 "register_operand" ""))
17721 (use (match_operand:MODEF 1 "general_operand" ""))]
17722 "TARGET_USE_FANCY_MATH_387
17723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17724 || TARGET_MIX_SSE_I387)
17725 && flag_unsafe_math_optimizations"
17729 if (optimize_insn_for_size_p ())
17732 op0 = gen_reg_rtx (XFmode);
17733 op1 = gen_reg_rtx (XFmode);
17735 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17736 emit_insn (gen_exp2xf2 (op0, op1));
17737 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17741 (define_expand "expm1xf2"
17742 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17744 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17745 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17746 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17747 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17748 (parallel [(set (match_dup 7)
17749 (unspec:XF [(match_dup 6) (match_dup 4)]
17750 UNSPEC_FSCALE_FRACT))
17752 (unspec:XF [(match_dup 6) (match_dup 4)]
17753 UNSPEC_FSCALE_EXP))])
17754 (parallel [(set (match_dup 10)
17755 (unspec:XF [(match_dup 9) (match_dup 8)]
17756 UNSPEC_FSCALE_FRACT))
17757 (set (match_dup 11)
17758 (unspec:XF [(match_dup 9) (match_dup 8)]
17759 UNSPEC_FSCALE_EXP))])
17760 (set (match_dup 12) (minus:XF (match_dup 10)
17761 (float_extend:XF (match_dup 13))))
17762 (set (match_operand:XF 0 "register_operand" "")
17763 (plus:XF (match_dup 12) (match_dup 7)))]
17764 "TARGET_USE_FANCY_MATH_387
17765 && flag_unsafe_math_optimizations"
17769 if (optimize_insn_for_size_p ())
17772 for (i = 2; i < 13; i++)
17773 operands[i] = gen_reg_rtx (XFmode);
17776 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17778 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17781 (define_expand "expm1<mode>2"
17782 [(use (match_operand:MODEF 0 "register_operand" ""))
17783 (use (match_operand:MODEF 1 "general_operand" ""))]
17784 "TARGET_USE_FANCY_MATH_387
17785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17786 || TARGET_MIX_SSE_I387)
17787 && flag_unsafe_math_optimizations"
17791 if (optimize_insn_for_size_p ())
17794 op0 = gen_reg_rtx (XFmode);
17795 op1 = gen_reg_rtx (XFmode);
17797 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17798 emit_insn (gen_expm1xf2 (op0, op1));
17799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17803 (define_expand "ldexpxf3"
17804 [(set (match_dup 3)
17805 (float:XF (match_operand:SI 2 "register_operand" "")))
17806 (parallel [(set (match_operand:XF 0 " register_operand" "")
17807 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17809 UNSPEC_FSCALE_FRACT))
17811 (unspec:XF [(match_dup 1) (match_dup 3)]
17812 UNSPEC_FSCALE_EXP))])]
17813 "TARGET_USE_FANCY_MATH_387
17814 && flag_unsafe_math_optimizations"
17816 if (optimize_insn_for_size_p ())
17819 operands[3] = gen_reg_rtx (XFmode);
17820 operands[4] = gen_reg_rtx (XFmode);
17823 (define_expand "ldexp<mode>3"
17824 [(use (match_operand:MODEF 0 "register_operand" ""))
17825 (use (match_operand:MODEF 1 "general_operand" ""))
17826 (use (match_operand:SI 2 "register_operand" ""))]
17827 "TARGET_USE_FANCY_MATH_387
17828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17829 || TARGET_MIX_SSE_I387)
17830 && flag_unsafe_math_optimizations"
17834 if (optimize_insn_for_size_p ())
17837 op0 = gen_reg_rtx (XFmode);
17838 op1 = gen_reg_rtx (XFmode);
17840 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17841 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17842 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17846 (define_expand "scalbxf3"
17847 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17848 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17849 (match_operand:XF 2 "register_operand" "")]
17850 UNSPEC_FSCALE_FRACT))
17852 (unspec:XF [(match_dup 1) (match_dup 2)]
17853 UNSPEC_FSCALE_EXP))])]
17854 "TARGET_USE_FANCY_MATH_387
17855 && flag_unsafe_math_optimizations"
17857 if (optimize_insn_for_size_p ())
17860 operands[3] = gen_reg_rtx (XFmode);
17863 (define_expand "scalb<mode>3"
17864 [(use (match_operand:MODEF 0 "register_operand" ""))
17865 (use (match_operand:MODEF 1 "general_operand" ""))
17866 (use (match_operand:MODEF 2 "register_operand" ""))]
17867 "TARGET_USE_FANCY_MATH_387
17868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17869 || TARGET_MIX_SSE_I387)
17870 && flag_unsafe_math_optimizations"
17874 if (optimize_insn_for_size_p ())
17877 op0 = gen_reg_rtx (XFmode);
17878 op1 = gen_reg_rtx (XFmode);
17879 op2 = gen_reg_rtx (XFmode);
17881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17882 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17883 emit_insn (gen_scalbxf3 (op0, op1, op2));
17884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17889 (define_insn "sse4_1_round<mode>2"
17890 [(set (match_operand:MODEF 0 "register_operand" "=x")
17891 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17892 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17895 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17896 [(set_attr "type" "ssecvt")
17897 (set_attr "prefix_extra" "1")
17898 (set_attr "prefix" "maybe_vex")
17899 (set_attr "mode" "<MODE>")])
17901 (define_insn "rintxf2"
17902 [(set (match_operand:XF 0 "register_operand" "=f")
17903 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17905 "TARGET_USE_FANCY_MATH_387
17906 && flag_unsafe_math_optimizations"
17908 [(set_attr "type" "fpspc")
17909 (set_attr "mode" "XF")])
17911 (define_expand "rint<mode>2"
17912 [(use (match_operand:MODEF 0 "register_operand" ""))
17913 (use (match_operand:MODEF 1 "register_operand" ""))]
17914 "(TARGET_USE_FANCY_MATH_387
17915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17916 || TARGET_MIX_SSE_I387)
17917 && flag_unsafe_math_optimizations)
17918 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919 && !flag_trapping_math)"
17921 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922 && !flag_trapping_math)
17924 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17927 emit_insn (gen_sse4_1_round<mode>2
17928 (operands[0], operands[1], GEN_INT (0x04)));
17930 ix86_expand_rint (operand0, operand1);
17934 rtx op0 = gen_reg_rtx (XFmode);
17935 rtx op1 = gen_reg_rtx (XFmode);
17937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17938 emit_insn (gen_rintxf2 (op0, op1));
17940 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17945 (define_expand "round<mode>2"
17946 [(match_operand:MODEF 0 "register_operand" "")
17947 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17948 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17949 && !flag_trapping_math && !flag_rounding_math"
17951 if (optimize_insn_for_size_p ())
17953 if (TARGET_64BIT || (<MODE>mode != DFmode))
17954 ix86_expand_round (operand0, operand1);
17956 ix86_expand_rounddf_32 (operand0, operand1);
17960 (define_insn_and_split "*fistdi2_1"
17961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17962 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17964 "TARGET_USE_FANCY_MATH_387
17965 && !(reload_completed || reload_in_progress)"
17970 if (memory_operand (operands[0], VOIDmode))
17971 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17974 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17975 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17980 [(set_attr "type" "fpspc")
17981 (set_attr "mode" "DI")])
17983 (define_insn "fistdi2"
17984 [(set (match_operand:DI 0 "memory_operand" "=m")
17985 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17987 (clobber (match_scratch:XF 2 "=&1f"))]
17988 "TARGET_USE_FANCY_MATH_387"
17989 "* return output_fix_trunc (insn, operands, 0);"
17990 [(set_attr "type" "fpspc")
17991 (set_attr "mode" "DI")])
17993 (define_insn "fistdi2_with_temp"
17994 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17995 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17997 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17998 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17999 "TARGET_USE_FANCY_MATH_387"
18001 [(set_attr "type" "fpspc")
18002 (set_attr "mode" "DI")])
18005 [(set (match_operand:DI 0 "register_operand" "")
18006 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18008 (clobber (match_operand:DI 2 "memory_operand" ""))
18009 (clobber (match_scratch 3 ""))]
18011 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18012 (clobber (match_dup 3))])
18013 (set (match_dup 0) (match_dup 2))]
18017 [(set (match_operand:DI 0 "memory_operand" "")
18018 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18020 (clobber (match_operand:DI 2 "memory_operand" ""))
18021 (clobber (match_scratch 3 ""))]
18023 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18024 (clobber (match_dup 3))])]
18027 (define_insn_and_split "*fist<mode>2_1"
18028 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18029 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18031 "TARGET_USE_FANCY_MATH_387
18032 && !(reload_completed || reload_in_progress)"
18037 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18038 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18042 [(set_attr "type" "fpspc")
18043 (set_attr "mode" "<MODE>")])
18045 (define_insn "fist<mode>2"
18046 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18047 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18049 "TARGET_USE_FANCY_MATH_387"
18050 "* return output_fix_trunc (insn, operands, 0);"
18051 [(set_attr "type" "fpspc")
18052 (set_attr "mode" "<MODE>")])
18054 (define_insn "fist<mode>2_with_temp"
18055 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18056 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18058 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18059 "TARGET_USE_FANCY_MATH_387"
18061 [(set_attr "type" "fpspc")
18062 (set_attr "mode" "<MODE>")])
18065 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18066 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18068 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18070 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18071 (set (match_dup 0) (match_dup 2))]
18075 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18076 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18078 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18080 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18083 (define_expand "lrintxf<mode>2"
18084 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18085 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18087 "TARGET_USE_FANCY_MATH_387"
18090 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18091 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18092 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18093 UNSPEC_FIX_NOTRUNC))]
18094 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18095 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18098 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18099 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18100 (match_operand:MODEF 1 "register_operand" "")]
18101 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18102 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18103 && !flag_trapping_math && !flag_rounding_math"
18105 if (optimize_insn_for_size_p ())
18107 ix86_expand_lround (operand0, operand1);
18111 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18112 (define_insn_and_split "frndintxf2_floor"
18113 [(set (match_operand:XF 0 "register_operand" "")
18114 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18115 UNSPEC_FRNDINT_FLOOR))
18116 (clobber (reg:CC FLAGS_REG))]
18117 "TARGET_USE_FANCY_MATH_387
18118 && flag_unsafe_math_optimizations
18119 && !(reload_completed || reload_in_progress)"
18124 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18126 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18127 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18129 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18130 operands[2], operands[3]));
18133 [(set_attr "type" "frndint")
18134 (set_attr "i387_cw" "floor")
18135 (set_attr "mode" "XF")])
18137 (define_insn "frndintxf2_floor_i387"
18138 [(set (match_operand:XF 0 "register_operand" "=f")
18139 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18140 UNSPEC_FRNDINT_FLOOR))
18141 (use (match_operand:HI 2 "memory_operand" "m"))
18142 (use (match_operand:HI 3 "memory_operand" "m"))]
18143 "TARGET_USE_FANCY_MATH_387
18144 && flag_unsafe_math_optimizations"
18145 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18146 [(set_attr "type" "frndint")
18147 (set_attr "i387_cw" "floor")
18148 (set_attr "mode" "XF")])
18150 (define_expand "floorxf2"
18151 [(use (match_operand:XF 0 "register_operand" ""))
18152 (use (match_operand:XF 1 "register_operand" ""))]
18153 "TARGET_USE_FANCY_MATH_387
18154 && flag_unsafe_math_optimizations"
18156 if (optimize_insn_for_size_p ())
18158 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18162 (define_expand "floor<mode>2"
18163 [(use (match_operand:MODEF 0 "register_operand" ""))
18164 (use (match_operand:MODEF 1 "register_operand" ""))]
18165 "(TARGET_USE_FANCY_MATH_387
18166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18167 || TARGET_MIX_SSE_I387)
18168 && flag_unsafe_math_optimizations)
18169 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18170 && !flag_trapping_math)"
18172 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173 && !flag_trapping_math
18174 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18176 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18179 emit_insn (gen_sse4_1_round<mode>2
18180 (operands[0], operands[1], GEN_INT (0x01)));
18181 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18182 ix86_expand_floorceil (operand0, operand1, true);
18184 ix86_expand_floorceildf_32 (operand0, operand1, true);
18190 if (optimize_insn_for_size_p ())
18193 op0 = gen_reg_rtx (XFmode);
18194 op1 = gen_reg_rtx (XFmode);
18195 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18196 emit_insn (gen_frndintxf2_floor (op0, op1));
18198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18203 (define_insn_and_split "*fist<mode>2_floor_1"
18204 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18205 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18206 UNSPEC_FIST_FLOOR))
18207 (clobber (reg:CC FLAGS_REG))]
18208 "TARGET_USE_FANCY_MATH_387
18209 && flag_unsafe_math_optimizations
18210 && !(reload_completed || reload_in_progress)"
18215 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18217 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18218 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18219 if (memory_operand (operands[0], VOIDmode))
18220 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18221 operands[2], operands[3]));
18224 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18225 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18226 operands[2], operands[3],
18231 [(set_attr "type" "fistp")
18232 (set_attr "i387_cw" "floor")
18233 (set_attr "mode" "<MODE>")])
18235 (define_insn "fistdi2_floor"
18236 [(set (match_operand:DI 0 "memory_operand" "=m")
18237 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18238 UNSPEC_FIST_FLOOR))
18239 (use (match_operand:HI 2 "memory_operand" "m"))
18240 (use (match_operand:HI 3 "memory_operand" "m"))
18241 (clobber (match_scratch:XF 4 "=&1f"))]
18242 "TARGET_USE_FANCY_MATH_387
18243 && flag_unsafe_math_optimizations"
18244 "* return output_fix_trunc (insn, operands, 0);"
18245 [(set_attr "type" "fistp")
18246 (set_attr "i387_cw" "floor")
18247 (set_attr "mode" "DI")])
18249 (define_insn "fistdi2_floor_with_temp"
18250 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18251 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18252 UNSPEC_FIST_FLOOR))
18253 (use (match_operand:HI 2 "memory_operand" "m,m"))
18254 (use (match_operand:HI 3 "memory_operand" "m,m"))
18255 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18256 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18257 "TARGET_USE_FANCY_MATH_387
18258 && flag_unsafe_math_optimizations"
18260 [(set_attr "type" "fistp")
18261 (set_attr "i387_cw" "floor")
18262 (set_attr "mode" "DI")])
18265 [(set (match_operand:DI 0 "register_operand" "")
18266 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18267 UNSPEC_FIST_FLOOR))
18268 (use (match_operand:HI 2 "memory_operand" ""))
18269 (use (match_operand:HI 3 "memory_operand" ""))
18270 (clobber (match_operand:DI 4 "memory_operand" ""))
18271 (clobber (match_scratch 5 ""))]
18273 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18274 (use (match_dup 2))
18275 (use (match_dup 3))
18276 (clobber (match_dup 5))])
18277 (set (match_dup 0) (match_dup 4))]
18281 [(set (match_operand:DI 0 "memory_operand" "")
18282 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18283 UNSPEC_FIST_FLOOR))
18284 (use (match_operand:HI 2 "memory_operand" ""))
18285 (use (match_operand:HI 3 "memory_operand" ""))
18286 (clobber (match_operand:DI 4 "memory_operand" ""))
18287 (clobber (match_scratch 5 ""))]
18289 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18290 (use (match_dup 2))
18291 (use (match_dup 3))
18292 (clobber (match_dup 5))])]
18295 (define_insn "fist<mode>2_floor"
18296 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18297 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18298 UNSPEC_FIST_FLOOR))
18299 (use (match_operand:HI 2 "memory_operand" "m"))
18300 (use (match_operand:HI 3 "memory_operand" "m"))]
18301 "TARGET_USE_FANCY_MATH_387
18302 && flag_unsafe_math_optimizations"
18303 "* return output_fix_trunc (insn, operands, 0);"
18304 [(set_attr "type" "fistp")
18305 (set_attr "i387_cw" "floor")
18306 (set_attr "mode" "<MODE>")])
18308 (define_insn "fist<mode>2_floor_with_temp"
18309 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18311 UNSPEC_FIST_FLOOR))
18312 (use (match_operand:HI 2 "memory_operand" "m,m"))
18313 (use (match_operand:HI 3 "memory_operand" "m,m"))
18314 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18315 "TARGET_USE_FANCY_MATH_387
18316 && flag_unsafe_math_optimizations"
18318 [(set_attr "type" "fistp")
18319 (set_attr "i387_cw" "floor")
18320 (set_attr "mode" "<MODE>")])
18323 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18324 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18325 UNSPEC_FIST_FLOOR))
18326 (use (match_operand:HI 2 "memory_operand" ""))
18327 (use (match_operand:HI 3 "memory_operand" ""))
18328 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18330 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18331 UNSPEC_FIST_FLOOR))
18332 (use (match_dup 2))
18333 (use (match_dup 3))])
18334 (set (match_dup 0) (match_dup 4))]
18338 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18339 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18340 UNSPEC_FIST_FLOOR))
18341 (use (match_operand:HI 2 "memory_operand" ""))
18342 (use (match_operand:HI 3 "memory_operand" ""))
18343 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18345 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18346 UNSPEC_FIST_FLOOR))
18347 (use (match_dup 2))
18348 (use (match_dup 3))])]
18351 (define_expand "lfloorxf<mode>2"
18352 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18353 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18354 UNSPEC_FIST_FLOOR))
18355 (clobber (reg:CC FLAGS_REG))])]
18356 "TARGET_USE_FANCY_MATH_387
18357 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18358 && flag_unsafe_math_optimizations"
18361 (define_expand "lfloor<mode>di2"
18362 [(match_operand:DI 0 "nonimmediate_operand" "")
18363 (match_operand:MODEF 1 "register_operand" "")]
18364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18365 && !flag_trapping_math"
18367 if (optimize_insn_for_size_p ())
18369 ix86_expand_lfloorceil (operand0, operand1, true);
18373 (define_expand "lfloor<mode>si2"
18374 [(match_operand:SI 0 "nonimmediate_operand" "")
18375 (match_operand:MODEF 1 "register_operand" "")]
18376 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18377 && !flag_trapping_math"
18379 if (optimize_insn_for_size_p () && TARGET_64BIT)
18381 ix86_expand_lfloorceil (operand0, operand1, true);
18385 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18386 (define_insn_and_split "frndintxf2_ceil"
18387 [(set (match_operand:XF 0 "register_operand" "")
18388 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18389 UNSPEC_FRNDINT_CEIL))
18390 (clobber (reg:CC FLAGS_REG))]
18391 "TARGET_USE_FANCY_MATH_387
18392 && flag_unsafe_math_optimizations
18393 && !(reload_completed || reload_in_progress)"
18398 ix86_optimize_mode_switching[I387_CEIL] = 1;
18400 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18401 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18403 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18404 operands[2], operands[3]));
18407 [(set_attr "type" "frndint")
18408 (set_attr "i387_cw" "ceil")
18409 (set_attr "mode" "XF")])
18411 (define_insn "frndintxf2_ceil_i387"
18412 [(set (match_operand:XF 0 "register_operand" "=f")
18413 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18414 UNSPEC_FRNDINT_CEIL))
18415 (use (match_operand:HI 2 "memory_operand" "m"))
18416 (use (match_operand:HI 3 "memory_operand" "m"))]
18417 "TARGET_USE_FANCY_MATH_387
18418 && flag_unsafe_math_optimizations"
18419 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18420 [(set_attr "type" "frndint")
18421 (set_attr "i387_cw" "ceil")
18422 (set_attr "mode" "XF")])
18424 (define_expand "ceilxf2"
18425 [(use (match_operand:XF 0 "register_operand" ""))
18426 (use (match_operand:XF 1 "register_operand" ""))]
18427 "TARGET_USE_FANCY_MATH_387
18428 && flag_unsafe_math_optimizations"
18430 if (optimize_insn_for_size_p ())
18432 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18436 (define_expand "ceil<mode>2"
18437 [(use (match_operand:MODEF 0 "register_operand" ""))
18438 (use (match_operand:MODEF 1 "register_operand" ""))]
18439 "(TARGET_USE_FANCY_MATH_387
18440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18441 || TARGET_MIX_SSE_I387)
18442 && flag_unsafe_math_optimizations)
18443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18444 && !flag_trapping_math)"
18446 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447 && !flag_trapping_math
18448 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18451 emit_insn (gen_sse4_1_round<mode>2
18452 (operands[0], operands[1], GEN_INT (0x02)));
18453 else if (optimize_insn_for_size_p ())
18455 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18456 ix86_expand_floorceil (operand0, operand1, false);
18458 ix86_expand_floorceildf_32 (operand0, operand1, false);
18464 if (optimize_insn_for_size_p ())
18467 op0 = gen_reg_rtx (XFmode);
18468 op1 = gen_reg_rtx (XFmode);
18469 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18470 emit_insn (gen_frndintxf2_ceil (op0, op1));
18472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18477 (define_insn_and_split "*fist<mode>2_ceil_1"
18478 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18479 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18481 (clobber (reg:CC FLAGS_REG))]
18482 "TARGET_USE_FANCY_MATH_387
18483 && flag_unsafe_math_optimizations
18484 && !(reload_completed || reload_in_progress)"
18489 ix86_optimize_mode_switching[I387_CEIL] = 1;
18491 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18492 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18493 if (memory_operand (operands[0], VOIDmode))
18494 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18495 operands[2], operands[3]));
18498 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18499 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18500 operands[2], operands[3],
18505 [(set_attr "type" "fistp")
18506 (set_attr "i387_cw" "ceil")
18507 (set_attr "mode" "<MODE>")])
18509 (define_insn "fistdi2_ceil"
18510 [(set (match_operand:DI 0 "memory_operand" "=m")
18511 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18513 (use (match_operand:HI 2 "memory_operand" "m"))
18514 (use (match_operand:HI 3 "memory_operand" "m"))
18515 (clobber (match_scratch:XF 4 "=&1f"))]
18516 "TARGET_USE_FANCY_MATH_387
18517 && flag_unsafe_math_optimizations"
18518 "* return output_fix_trunc (insn, operands, 0);"
18519 [(set_attr "type" "fistp")
18520 (set_attr "i387_cw" "ceil")
18521 (set_attr "mode" "DI")])
18523 (define_insn "fistdi2_ceil_with_temp"
18524 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18525 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18527 (use (match_operand:HI 2 "memory_operand" "m,m"))
18528 (use (match_operand:HI 3 "memory_operand" "m,m"))
18529 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18530 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18531 "TARGET_USE_FANCY_MATH_387
18532 && flag_unsafe_math_optimizations"
18534 [(set_attr "type" "fistp")
18535 (set_attr "i387_cw" "ceil")
18536 (set_attr "mode" "DI")])
18539 [(set (match_operand:DI 0 "register_operand" "")
18540 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18542 (use (match_operand:HI 2 "memory_operand" ""))
18543 (use (match_operand:HI 3 "memory_operand" ""))
18544 (clobber (match_operand:DI 4 "memory_operand" ""))
18545 (clobber (match_scratch 5 ""))]
18547 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18548 (use (match_dup 2))
18549 (use (match_dup 3))
18550 (clobber (match_dup 5))])
18551 (set (match_dup 0) (match_dup 4))]
18555 [(set (match_operand:DI 0 "memory_operand" "")
18556 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18558 (use (match_operand:HI 2 "memory_operand" ""))
18559 (use (match_operand:HI 3 "memory_operand" ""))
18560 (clobber (match_operand:DI 4 "memory_operand" ""))
18561 (clobber (match_scratch 5 ""))]
18563 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18564 (use (match_dup 2))
18565 (use (match_dup 3))
18566 (clobber (match_dup 5))])]
18569 (define_insn "fist<mode>2_ceil"
18570 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18571 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18573 (use (match_operand:HI 2 "memory_operand" "m"))
18574 (use (match_operand:HI 3 "memory_operand" "m"))]
18575 "TARGET_USE_FANCY_MATH_387
18576 && flag_unsafe_math_optimizations"
18577 "* return output_fix_trunc (insn, operands, 0);"
18578 [(set_attr "type" "fistp")
18579 (set_attr "i387_cw" "ceil")
18580 (set_attr "mode" "<MODE>")])
18582 (define_insn "fist<mode>2_ceil_with_temp"
18583 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18584 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18586 (use (match_operand:HI 2 "memory_operand" "m,m"))
18587 (use (match_operand:HI 3 "memory_operand" "m,m"))
18588 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18589 "TARGET_USE_FANCY_MATH_387
18590 && flag_unsafe_math_optimizations"
18592 [(set_attr "type" "fistp")
18593 (set_attr "i387_cw" "ceil")
18594 (set_attr "mode" "<MODE>")])
18597 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18598 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18600 (use (match_operand:HI 2 "memory_operand" ""))
18601 (use (match_operand:HI 3 "memory_operand" ""))
18602 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18604 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18606 (use (match_dup 2))
18607 (use (match_dup 3))])
18608 (set (match_dup 0) (match_dup 4))]
18612 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18613 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18615 (use (match_operand:HI 2 "memory_operand" ""))
18616 (use (match_operand:HI 3 "memory_operand" ""))
18617 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18619 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18621 (use (match_dup 2))
18622 (use (match_dup 3))])]
18625 (define_expand "lceilxf<mode>2"
18626 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18627 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18629 (clobber (reg:CC FLAGS_REG))])]
18630 "TARGET_USE_FANCY_MATH_387
18631 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18632 && flag_unsafe_math_optimizations"
18635 (define_expand "lceil<mode>di2"
18636 [(match_operand:DI 0 "nonimmediate_operand" "")
18637 (match_operand:MODEF 1 "register_operand" "")]
18638 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18639 && !flag_trapping_math"
18641 ix86_expand_lfloorceil (operand0, operand1, false);
18645 (define_expand "lceil<mode>si2"
18646 [(match_operand:SI 0 "nonimmediate_operand" "")
18647 (match_operand:MODEF 1 "register_operand" "")]
18648 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18649 && !flag_trapping_math"
18651 ix86_expand_lfloorceil (operand0, operand1, false);
18655 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18656 (define_insn_and_split "frndintxf2_trunc"
18657 [(set (match_operand:XF 0 "register_operand" "")
18658 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18659 UNSPEC_FRNDINT_TRUNC))
18660 (clobber (reg:CC FLAGS_REG))]
18661 "TARGET_USE_FANCY_MATH_387
18662 && flag_unsafe_math_optimizations
18663 && !(reload_completed || reload_in_progress)"
18668 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18670 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18671 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18673 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18674 operands[2], operands[3]));
18677 [(set_attr "type" "frndint")
18678 (set_attr "i387_cw" "trunc")
18679 (set_attr "mode" "XF")])
18681 (define_insn "frndintxf2_trunc_i387"
18682 [(set (match_operand:XF 0 "register_operand" "=f")
18683 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18684 UNSPEC_FRNDINT_TRUNC))
18685 (use (match_operand:HI 2 "memory_operand" "m"))
18686 (use (match_operand:HI 3 "memory_operand" "m"))]
18687 "TARGET_USE_FANCY_MATH_387
18688 && flag_unsafe_math_optimizations"
18689 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18690 [(set_attr "type" "frndint")
18691 (set_attr "i387_cw" "trunc")
18692 (set_attr "mode" "XF")])
18694 (define_expand "btruncxf2"
18695 [(use (match_operand:XF 0 "register_operand" ""))
18696 (use (match_operand:XF 1 "register_operand" ""))]
18697 "TARGET_USE_FANCY_MATH_387
18698 && flag_unsafe_math_optimizations"
18700 if (optimize_insn_for_size_p ())
18702 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18706 (define_expand "btrunc<mode>2"
18707 [(use (match_operand:MODEF 0 "register_operand" ""))
18708 (use (match_operand:MODEF 1 "register_operand" ""))]
18709 "(TARGET_USE_FANCY_MATH_387
18710 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18711 || TARGET_MIX_SSE_I387)
18712 && flag_unsafe_math_optimizations)
18713 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18714 && !flag_trapping_math)"
18716 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717 && !flag_trapping_math
18718 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18721 emit_insn (gen_sse4_1_round<mode>2
18722 (operands[0], operands[1], GEN_INT (0x03)));
18723 else if (optimize_insn_for_size_p ())
18725 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18726 ix86_expand_trunc (operand0, operand1);
18728 ix86_expand_truncdf_32 (operand0, operand1);
18734 if (optimize_insn_for_size_p ())
18737 op0 = gen_reg_rtx (XFmode);
18738 op1 = gen_reg_rtx (XFmode);
18739 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18740 emit_insn (gen_frndintxf2_trunc (op0, op1));
18742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18747 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18748 (define_insn_and_split "frndintxf2_mask_pm"
18749 [(set (match_operand:XF 0 "register_operand" "")
18750 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18751 UNSPEC_FRNDINT_MASK_PM))
18752 (clobber (reg:CC FLAGS_REG))]
18753 "TARGET_USE_FANCY_MATH_387
18754 && flag_unsafe_math_optimizations
18755 && !(reload_completed || reload_in_progress)"
18760 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18762 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18763 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18765 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18766 operands[2], operands[3]));
18769 [(set_attr "type" "frndint")
18770 (set_attr "i387_cw" "mask_pm")
18771 (set_attr "mode" "XF")])
18773 (define_insn "frndintxf2_mask_pm_i387"
18774 [(set (match_operand:XF 0 "register_operand" "=f")
18775 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18776 UNSPEC_FRNDINT_MASK_PM))
18777 (use (match_operand:HI 2 "memory_operand" "m"))
18778 (use (match_operand:HI 3 "memory_operand" "m"))]
18779 "TARGET_USE_FANCY_MATH_387
18780 && flag_unsafe_math_optimizations"
18781 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18782 [(set_attr "type" "frndint")
18783 (set_attr "i387_cw" "mask_pm")
18784 (set_attr "mode" "XF")])
18786 (define_expand "nearbyintxf2"
18787 [(use (match_operand:XF 0 "register_operand" ""))
18788 (use (match_operand:XF 1 "register_operand" ""))]
18789 "TARGET_USE_FANCY_MATH_387
18790 && flag_unsafe_math_optimizations"
18792 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18797 (define_expand "nearbyint<mode>2"
18798 [(use (match_operand:MODEF 0 "register_operand" ""))
18799 (use (match_operand:MODEF 1 "register_operand" ""))]
18800 "TARGET_USE_FANCY_MATH_387
18801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18802 || TARGET_MIX_SSE_I387)
18803 && flag_unsafe_math_optimizations"
18805 rtx op0 = gen_reg_rtx (XFmode);
18806 rtx op1 = gen_reg_rtx (XFmode);
18808 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18809 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18815 (define_insn "fxam<mode>2_i387"
18816 [(set (match_operand:HI 0 "register_operand" "=a")
18818 [(match_operand:X87MODEF 1 "register_operand" "f")]
18820 "TARGET_USE_FANCY_MATH_387"
18821 "fxam\n\tfnstsw\t%0"
18822 [(set_attr "type" "multi")
18823 (set_attr "unit" "i387")
18824 (set_attr "mode" "<MODE>")])
18826 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18827 [(set (match_operand:HI 0 "register_operand" "")
18829 [(match_operand:MODEF 1 "memory_operand" "")]
18831 "TARGET_USE_FANCY_MATH_387
18832 && !(reload_completed || reload_in_progress)"
18835 [(set (match_dup 2)(match_dup 1))
18837 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18839 operands[2] = gen_reg_rtx (<MODE>mode);
18841 MEM_VOLATILE_P (operands[1]) = 1;
18843 [(set_attr "type" "multi")
18844 (set_attr "unit" "i387")
18845 (set_attr "mode" "<MODE>")])
18847 (define_expand "isinfxf2"
18848 [(use (match_operand:SI 0 "register_operand" ""))
18849 (use (match_operand:XF 1 "register_operand" ""))]
18850 "TARGET_USE_FANCY_MATH_387
18851 && TARGET_C99_FUNCTIONS"
18853 rtx mask = GEN_INT (0x45);
18854 rtx val = GEN_INT (0x05);
18858 rtx scratch = gen_reg_rtx (HImode);
18859 rtx res = gen_reg_rtx (QImode);
18861 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18863 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18864 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18865 cond = gen_rtx_fmt_ee (EQ, QImode,
18866 gen_rtx_REG (CCmode, FLAGS_REG),
18868 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18869 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18873 (define_expand "isinf<mode>2"
18874 [(use (match_operand:SI 0 "register_operand" ""))
18875 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18876 "TARGET_USE_FANCY_MATH_387
18877 && TARGET_C99_FUNCTIONS
18878 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18880 rtx mask = GEN_INT (0x45);
18881 rtx val = GEN_INT (0x05);
18885 rtx scratch = gen_reg_rtx (HImode);
18886 rtx res = gen_reg_rtx (QImode);
18888 /* Remove excess precision by forcing value through memory. */
18889 if (memory_operand (operands[1], VOIDmode))
18890 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18893 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18894 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18896 emit_move_insn (temp, operands[1]);
18897 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18900 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18901 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18902 cond = gen_rtx_fmt_ee (EQ, QImode,
18903 gen_rtx_REG (CCmode, FLAGS_REG),
18905 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18906 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18910 (define_expand "signbit<mode>2"
18911 [(use (match_operand:SI 0 "register_operand" ""))
18912 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18913 "TARGET_USE_FANCY_MATH_387
18914 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18916 rtx mask = GEN_INT (0x0200);
18918 rtx scratch = gen_reg_rtx (HImode);
18920 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18921 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18925 ;; Block operation instructions
18928 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18931 [(set_attr "length" "1")
18932 (set_attr "length_immediate" "0")
18933 (set_attr "modrm" "0")])
18935 (define_expand "movmemsi"
18936 [(use (match_operand:BLK 0 "memory_operand" ""))
18937 (use (match_operand:BLK 1 "memory_operand" ""))
18938 (use (match_operand:SI 2 "nonmemory_operand" ""))
18939 (use (match_operand:SI 3 "const_int_operand" ""))
18940 (use (match_operand:SI 4 "const_int_operand" ""))
18941 (use (match_operand:SI 5 "const_int_operand" ""))]
18944 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18945 operands[4], operands[5]))
18951 (define_expand "movmemdi"
18952 [(use (match_operand:BLK 0 "memory_operand" ""))
18953 (use (match_operand:BLK 1 "memory_operand" ""))
18954 (use (match_operand:DI 2 "nonmemory_operand" ""))
18955 (use (match_operand:DI 3 "const_int_operand" ""))
18956 (use (match_operand:SI 4 "const_int_operand" ""))
18957 (use (match_operand:SI 5 "const_int_operand" ""))]
18960 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18961 operands[4], operands[5]))
18967 ;; Most CPUs don't like single string operations
18968 ;; Handle this case here to simplify previous expander.
18970 (define_expand "strmov"
18971 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18972 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18973 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18974 (clobber (reg:CC FLAGS_REG))])
18975 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18976 (clobber (reg:CC FLAGS_REG))])]
18979 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18981 /* If .md ever supports :P for Pmode, these can be directly
18982 in the pattern above. */
18983 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18984 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18986 /* Can't use this if the user has appropriated esi or edi. */
18987 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18988 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18990 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18991 operands[2], operands[3],
18992 operands[5], operands[6]));
18996 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18999 (define_expand "strmov_singleop"
19000 [(parallel [(set (match_operand 1 "memory_operand" "")
19001 (match_operand 3 "memory_operand" ""))
19002 (set (match_operand 0 "register_operand" "")
19003 (match_operand 4 "" ""))
19004 (set (match_operand 2 "register_operand" "")
19005 (match_operand 5 "" ""))])]
19007 "ix86_current_function_needs_cld = 1;")
19009 (define_insn "*strmovdi_rex_1"
19010 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19011 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19012 (set (match_operand:DI 0 "register_operand" "=D")
19013 (plus:DI (match_dup 2)
19015 (set (match_operand:DI 1 "register_operand" "=S")
19016 (plus:DI (match_dup 3)
19020 [(set_attr "type" "str")
19021 (set_attr "mode" "DI")
19022 (set_attr "memory" "both")])
19024 (define_insn "*strmovsi_1"
19025 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19026 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19027 (set (match_operand:SI 0 "register_operand" "=D")
19028 (plus:SI (match_dup 2)
19030 (set (match_operand:SI 1 "register_operand" "=S")
19031 (plus:SI (match_dup 3)
19035 [(set_attr "type" "str")
19036 (set_attr "mode" "SI")
19037 (set_attr "memory" "both")])
19039 (define_insn "*strmovsi_rex_1"
19040 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19041 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19042 (set (match_operand:DI 0 "register_operand" "=D")
19043 (plus:DI (match_dup 2)
19045 (set (match_operand:DI 1 "register_operand" "=S")
19046 (plus:DI (match_dup 3)
19050 [(set_attr "type" "str")
19051 (set_attr "mode" "SI")
19052 (set_attr "memory" "both")])
19054 (define_insn "*strmovhi_1"
19055 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19056 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19057 (set (match_operand:SI 0 "register_operand" "=D")
19058 (plus:SI (match_dup 2)
19060 (set (match_operand:SI 1 "register_operand" "=S")
19061 (plus:SI (match_dup 3)
19065 [(set_attr "type" "str")
19066 (set_attr "memory" "both")
19067 (set_attr "mode" "HI")])
19069 (define_insn "*strmovhi_rex_1"
19070 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19071 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19072 (set (match_operand:DI 0 "register_operand" "=D")
19073 (plus:DI (match_dup 2)
19075 (set (match_operand:DI 1 "register_operand" "=S")
19076 (plus:DI (match_dup 3)
19080 [(set_attr "type" "str")
19081 (set_attr "memory" "both")
19082 (set_attr "mode" "HI")])
19084 (define_insn "*strmovqi_1"
19085 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19086 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19087 (set (match_operand:SI 0 "register_operand" "=D")
19088 (plus:SI (match_dup 2)
19090 (set (match_operand:SI 1 "register_operand" "=S")
19091 (plus:SI (match_dup 3)
19095 [(set_attr "type" "str")
19096 (set_attr "memory" "both")
19097 (set_attr "mode" "QI")])
19099 (define_insn "*strmovqi_rex_1"
19100 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19101 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19102 (set (match_operand:DI 0 "register_operand" "=D")
19103 (plus:DI (match_dup 2)
19105 (set (match_operand:DI 1 "register_operand" "=S")
19106 (plus:DI (match_dup 3)
19110 [(set_attr "type" "str")
19111 (set_attr "memory" "both")
19112 (set_attr "mode" "QI")])
19114 (define_expand "rep_mov"
19115 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19116 (set (match_operand 0 "register_operand" "")
19117 (match_operand 5 "" ""))
19118 (set (match_operand 2 "register_operand" "")
19119 (match_operand 6 "" ""))
19120 (set (match_operand 1 "memory_operand" "")
19121 (match_operand 3 "memory_operand" ""))
19122 (use (match_dup 4))])]
19124 "ix86_current_function_needs_cld = 1;")
19126 (define_insn "*rep_movdi_rex64"
19127 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19128 (set (match_operand:DI 0 "register_operand" "=D")
19129 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19131 (match_operand:DI 3 "register_operand" "0")))
19132 (set (match_operand:DI 1 "register_operand" "=S")
19133 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19134 (match_operand:DI 4 "register_operand" "1")))
19135 (set (mem:BLK (match_dup 3))
19136 (mem:BLK (match_dup 4)))
19137 (use (match_dup 5))]
19140 [(set_attr "type" "str")
19141 (set_attr "prefix_rep" "1")
19142 (set_attr "memory" "both")
19143 (set_attr "mode" "DI")])
19145 (define_insn "*rep_movsi"
19146 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19147 (set (match_operand:SI 0 "register_operand" "=D")
19148 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19150 (match_operand:SI 3 "register_operand" "0")))
19151 (set (match_operand:SI 1 "register_operand" "=S")
19152 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19153 (match_operand:SI 4 "register_operand" "1")))
19154 (set (mem:BLK (match_dup 3))
19155 (mem:BLK (match_dup 4)))
19156 (use (match_dup 5))]
19159 [(set_attr "type" "str")
19160 (set_attr "prefix_rep" "1")
19161 (set_attr "memory" "both")
19162 (set_attr "mode" "SI")])
19164 (define_insn "*rep_movsi_rex64"
19165 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19166 (set (match_operand:DI 0 "register_operand" "=D")
19167 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19169 (match_operand:DI 3 "register_operand" "0")))
19170 (set (match_operand:DI 1 "register_operand" "=S")
19171 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19172 (match_operand:DI 4 "register_operand" "1")))
19173 (set (mem:BLK (match_dup 3))
19174 (mem:BLK (match_dup 4)))
19175 (use (match_dup 5))]
19178 [(set_attr "type" "str")
19179 (set_attr "prefix_rep" "1")
19180 (set_attr "memory" "both")
19181 (set_attr "mode" "SI")])
19183 (define_insn "*rep_movqi"
19184 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19185 (set (match_operand:SI 0 "register_operand" "=D")
19186 (plus:SI (match_operand:SI 3 "register_operand" "0")
19187 (match_operand:SI 5 "register_operand" "2")))
19188 (set (match_operand:SI 1 "register_operand" "=S")
19189 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19190 (set (mem:BLK (match_dup 3))
19191 (mem:BLK (match_dup 4)))
19192 (use (match_dup 5))]
19195 [(set_attr "type" "str")
19196 (set_attr "prefix_rep" "1")
19197 (set_attr "memory" "both")
19198 (set_attr "mode" "SI")])
19200 (define_insn "*rep_movqi_rex64"
19201 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19202 (set (match_operand:DI 0 "register_operand" "=D")
19203 (plus:DI (match_operand:DI 3 "register_operand" "0")
19204 (match_operand:DI 5 "register_operand" "2")))
19205 (set (match_operand:DI 1 "register_operand" "=S")
19206 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19207 (set (mem:BLK (match_dup 3))
19208 (mem:BLK (match_dup 4)))
19209 (use (match_dup 5))]
19212 [(set_attr "type" "str")
19213 (set_attr "prefix_rep" "1")
19214 (set_attr "memory" "both")
19215 (set_attr "mode" "SI")])
19217 (define_expand "setmemsi"
19218 [(use (match_operand:BLK 0 "memory_operand" ""))
19219 (use (match_operand:SI 1 "nonmemory_operand" ""))
19220 (use (match_operand 2 "const_int_operand" ""))
19221 (use (match_operand 3 "const_int_operand" ""))
19222 (use (match_operand:SI 4 "const_int_operand" ""))
19223 (use (match_operand:SI 5 "const_int_operand" ""))]
19226 if (ix86_expand_setmem (operands[0], operands[1],
19227 operands[2], operands[3],
19228 operands[4], operands[5]))
19234 (define_expand "setmemdi"
19235 [(use (match_operand:BLK 0 "memory_operand" ""))
19236 (use (match_operand:DI 1 "nonmemory_operand" ""))
19237 (use (match_operand 2 "const_int_operand" ""))
19238 (use (match_operand 3 "const_int_operand" ""))
19239 (use (match_operand 4 "const_int_operand" ""))
19240 (use (match_operand 5 "const_int_operand" ""))]
19243 if (ix86_expand_setmem (operands[0], operands[1],
19244 operands[2], operands[3],
19245 operands[4], operands[5]))
19251 ;; Most CPUs don't like single string operations
19252 ;; Handle this case here to simplify previous expander.
19254 (define_expand "strset"
19255 [(set (match_operand 1 "memory_operand" "")
19256 (match_operand 2 "register_operand" ""))
19257 (parallel [(set (match_operand 0 "register_operand" "")
19259 (clobber (reg:CC FLAGS_REG))])]
19262 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19263 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19265 /* If .md ever supports :P for Pmode, this can be directly
19266 in the pattern above. */
19267 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19268 GEN_INT (GET_MODE_SIZE (GET_MODE
19270 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19272 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19278 (define_expand "strset_singleop"
19279 [(parallel [(set (match_operand 1 "memory_operand" "")
19280 (match_operand 2 "register_operand" ""))
19281 (set (match_operand 0 "register_operand" "")
19282 (match_operand 3 "" ""))])]
19284 "ix86_current_function_needs_cld = 1;")
19286 (define_insn "*strsetdi_rex_1"
19287 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19288 (match_operand:DI 2 "register_operand" "a"))
19289 (set (match_operand:DI 0 "register_operand" "=D")
19290 (plus:DI (match_dup 1)
19294 [(set_attr "type" "str")
19295 (set_attr "memory" "store")
19296 (set_attr "mode" "DI")])
19298 (define_insn "*strsetsi_1"
19299 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19300 (match_operand:SI 2 "register_operand" "a"))
19301 (set (match_operand:SI 0 "register_operand" "=D")
19302 (plus:SI (match_dup 1)
19306 [(set_attr "type" "str")
19307 (set_attr "memory" "store")
19308 (set_attr "mode" "SI")])
19310 (define_insn "*strsetsi_rex_1"
19311 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19312 (match_operand:SI 2 "register_operand" "a"))
19313 (set (match_operand:DI 0 "register_operand" "=D")
19314 (plus:DI (match_dup 1)
19318 [(set_attr "type" "str")
19319 (set_attr "memory" "store")
19320 (set_attr "mode" "SI")])
19322 (define_insn "*strsethi_1"
19323 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19324 (match_operand:HI 2 "register_operand" "a"))
19325 (set (match_operand:SI 0 "register_operand" "=D")
19326 (plus:SI (match_dup 1)
19330 [(set_attr "type" "str")
19331 (set_attr "memory" "store")
19332 (set_attr "mode" "HI")])
19334 (define_insn "*strsethi_rex_1"
19335 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19336 (match_operand:HI 2 "register_operand" "a"))
19337 (set (match_operand:DI 0 "register_operand" "=D")
19338 (plus:DI (match_dup 1)
19342 [(set_attr "type" "str")
19343 (set_attr "memory" "store")
19344 (set_attr "mode" "HI")])
19346 (define_insn "*strsetqi_1"
19347 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19348 (match_operand:QI 2 "register_operand" "a"))
19349 (set (match_operand:SI 0 "register_operand" "=D")
19350 (plus:SI (match_dup 1)
19354 [(set_attr "type" "str")
19355 (set_attr "memory" "store")
19356 (set_attr "mode" "QI")])
19358 (define_insn "*strsetqi_rex_1"
19359 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19360 (match_operand:QI 2 "register_operand" "a"))
19361 (set (match_operand:DI 0 "register_operand" "=D")
19362 (plus:DI (match_dup 1)
19366 [(set_attr "type" "str")
19367 (set_attr "memory" "store")
19368 (set_attr "mode" "QI")])
19370 (define_expand "rep_stos"
19371 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19372 (set (match_operand 0 "register_operand" "")
19373 (match_operand 4 "" ""))
19374 (set (match_operand 2 "memory_operand" "") (const_int 0))
19375 (use (match_operand 3 "register_operand" ""))
19376 (use (match_dup 1))])]
19378 "ix86_current_function_needs_cld = 1;")
19380 (define_insn "*rep_stosdi_rex64"
19381 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19382 (set (match_operand:DI 0 "register_operand" "=D")
19383 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19385 (match_operand:DI 3 "register_operand" "0")))
19386 (set (mem:BLK (match_dup 3))
19388 (use (match_operand:DI 2 "register_operand" "a"))
19389 (use (match_dup 4))]
19392 [(set_attr "type" "str")
19393 (set_attr "prefix_rep" "1")
19394 (set_attr "memory" "store")
19395 (set_attr "mode" "DI")])
19397 (define_insn "*rep_stossi"
19398 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19399 (set (match_operand:SI 0 "register_operand" "=D")
19400 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19402 (match_operand:SI 3 "register_operand" "0")))
19403 (set (mem:BLK (match_dup 3))
19405 (use (match_operand:SI 2 "register_operand" "a"))
19406 (use (match_dup 4))]
19409 [(set_attr "type" "str")
19410 (set_attr "prefix_rep" "1")
19411 (set_attr "memory" "store")
19412 (set_attr "mode" "SI")])
19414 (define_insn "*rep_stossi_rex64"
19415 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19416 (set (match_operand:DI 0 "register_operand" "=D")
19417 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19419 (match_operand:DI 3 "register_operand" "0")))
19420 (set (mem:BLK (match_dup 3))
19422 (use (match_operand:SI 2 "register_operand" "a"))
19423 (use (match_dup 4))]
19426 [(set_attr "type" "str")
19427 (set_attr "prefix_rep" "1")
19428 (set_attr "memory" "store")
19429 (set_attr "mode" "SI")])
19431 (define_insn "*rep_stosqi"
19432 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19433 (set (match_operand:SI 0 "register_operand" "=D")
19434 (plus:SI (match_operand:SI 3 "register_operand" "0")
19435 (match_operand:SI 4 "register_operand" "1")))
19436 (set (mem:BLK (match_dup 3))
19438 (use (match_operand:QI 2 "register_operand" "a"))
19439 (use (match_dup 4))]
19442 [(set_attr "type" "str")
19443 (set_attr "prefix_rep" "1")
19444 (set_attr "memory" "store")
19445 (set_attr "mode" "QI")])
19447 (define_insn "*rep_stosqi_rex64"
19448 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19449 (set (match_operand:DI 0 "register_operand" "=D")
19450 (plus:DI (match_operand:DI 3 "register_operand" "0")
19451 (match_operand:DI 4 "register_operand" "1")))
19452 (set (mem:BLK (match_dup 3))
19454 (use (match_operand:QI 2 "register_operand" "a"))
19455 (use (match_dup 4))]
19458 [(set_attr "type" "str")
19459 (set_attr "prefix_rep" "1")
19460 (set_attr "memory" "store")
19461 (set_attr "mode" "QI")])
19463 (define_expand "cmpstrnsi"
19464 [(set (match_operand:SI 0 "register_operand" "")
19465 (compare:SI (match_operand:BLK 1 "general_operand" "")
19466 (match_operand:BLK 2 "general_operand" "")))
19467 (use (match_operand 3 "general_operand" ""))
19468 (use (match_operand 4 "immediate_operand" ""))]
19471 rtx addr1, addr2, out, outlow, count, countreg, align;
19473 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19476 /* Can't use this if the user has appropriated esi or edi. */
19477 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19482 out = gen_reg_rtx (SImode);
19484 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19485 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19486 if (addr1 != XEXP (operands[1], 0))
19487 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19488 if (addr2 != XEXP (operands[2], 0))
19489 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19491 count = operands[3];
19492 countreg = ix86_zero_extend_to_Pmode (count);
19494 /* %%% Iff we are testing strict equality, we can use known alignment
19495 to good advantage. This may be possible with combine, particularly
19496 once cc0 is dead. */
19497 align = operands[4];
19499 if (CONST_INT_P (count))
19501 if (INTVAL (count) == 0)
19503 emit_move_insn (operands[0], const0_rtx);
19506 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19507 operands[1], operands[2]));
19512 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19514 emit_insn (gen_cmpsi_1 (countreg, countreg));
19515 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19516 operands[1], operands[2]));
19519 outlow = gen_lowpart (QImode, out);
19520 emit_insn (gen_cmpintqi (outlow));
19521 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19523 if (operands[0] != out)
19524 emit_move_insn (operands[0], out);
19529 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19531 (define_expand "cmpintqi"
19532 [(set (match_dup 1)
19533 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19535 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19536 (parallel [(set (match_operand:QI 0 "register_operand" "")
19537 (minus:QI (match_dup 1)
19539 (clobber (reg:CC FLAGS_REG))])]
19541 "operands[1] = gen_reg_rtx (QImode);
19542 operands[2] = gen_reg_rtx (QImode);")
19544 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19545 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19547 (define_expand "cmpstrnqi_nz_1"
19548 [(parallel [(set (reg:CC FLAGS_REG)
19549 (compare:CC (match_operand 4 "memory_operand" "")
19550 (match_operand 5 "memory_operand" "")))
19551 (use (match_operand 2 "register_operand" ""))
19552 (use (match_operand:SI 3 "immediate_operand" ""))
19553 (clobber (match_operand 0 "register_operand" ""))
19554 (clobber (match_operand 1 "register_operand" ""))
19555 (clobber (match_dup 2))])]
19557 "ix86_current_function_needs_cld = 1;")
19559 (define_insn "*cmpstrnqi_nz_1"
19560 [(set (reg:CC FLAGS_REG)
19561 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19562 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19563 (use (match_operand:SI 6 "register_operand" "2"))
19564 (use (match_operand:SI 3 "immediate_operand" "i"))
19565 (clobber (match_operand:SI 0 "register_operand" "=S"))
19566 (clobber (match_operand:SI 1 "register_operand" "=D"))
19567 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19570 [(set_attr "type" "str")
19571 (set_attr "mode" "QI")
19572 (set_attr "prefix_rep" "1")])
19574 (define_insn "*cmpstrnqi_nz_rex_1"
19575 [(set (reg:CC FLAGS_REG)
19576 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19577 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19578 (use (match_operand:DI 6 "register_operand" "2"))
19579 (use (match_operand:SI 3 "immediate_operand" "i"))
19580 (clobber (match_operand:DI 0 "register_operand" "=S"))
19581 (clobber (match_operand:DI 1 "register_operand" "=D"))
19582 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19585 [(set_attr "type" "str")
19586 (set_attr "mode" "QI")
19587 (set_attr "prefix_rep" "1")])
19589 ;; The same, but the count is not known to not be zero.
19591 (define_expand "cmpstrnqi_1"
19592 [(parallel [(set (reg:CC FLAGS_REG)
19593 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19595 (compare:CC (match_operand 4 "memory_operand" "")
19596 (match_operand 5 "memory_operand" ""))
19598 (use (match_operand:SI 3 "immediate_operand" ""))
19599 (use (reg:CC FLAGS_REG))
19600 (clobber (match_operand 0 "register_operand" ""))
19601 (clobber (match_operand 1 "register_operand" ""))
19602 (clobber (match_dup 2))])]
19604 "ix86_current_function_needs_cld = 1;")
19606 (define_insn "*cmpstrnqi_1"
19607 [(set (reg:CC FLAGS_REG)
19608 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19610 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19611 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19613 (use (match_operand:SI 3 "immediate_operand" "i"))
19614 (use (reg:CC FLAGS_REG))
19615 (clobber (match_operand:SI 0 "register_operand" "=S"))
19616 (clobber (match_operand:SI 1 "register_operand" "=D"))
19617 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19620 [(set_attr "type" "str")
19621 (set_attr "mode" "QI")
19622 (set_attr "prefix_rep" "1")])
19624 (define_insn "*cmpstrnqi_rex_1"
19625 [(set (reg:CC FLAGS_REG)
19626 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19628 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19629 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19631 (use (match_operand:SI 3 "immediate_operand" "i"))
19632 (use (reg:CC FLAGS_REG))
19633 (clobber (match_operand:DI 0 "register_operand" "=S"))
19634 (clobber (match_operand:DI 1 "register_operand" "=D"))
19635 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19638 [(set_attr "type" "str")
19639 (set_attr "mode" "QI")
19640 (set_attr "prefix_rep" "1")])
19642 (define_expand "strlensi"
19643 [(set (match_operand:SI 0 "register_operand" "")
19644 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19645 (match_operand:QI 2 "immediate_operand" "")
19646 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19649 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19655 (define_expand "strlendi"
19656 [(set (match_operand:DI 0 "register_operand" "")
19657 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19658 (match_operand:QI 2 "immediate_operand" "")
19659 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19662 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19668 (define_expand "strlenqi_1"
19669 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19670 (clobber (match_operand 1 "register_operand" ""))
19671 (clobber (reg:CC FLAGS_REG))])]
19673 "ix86_current_function_needs_cld = 1;")
19675 (define_insn "*strlenqi_1"
19676 [(set (match_operand:SI 0 "register_operand" "=&c")
19677 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19678 (match_operand:QI 2 "register_operand" "a")
19679 (match_operand:SI 3 "immediate_operand" "i")
19680 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19681 (clobber (match_operand:SI 1 "register_operand" "=D"))
19682 (clobber (reg:CC FLAGS_REG))]
19685 [(set_attr "type" "str")
19686 (set_attr "mode" "QI")
19687 (set_attr "prefix_rep" "1")])
19689 (define_insn "*strlenqi_rex_1"
19690 [(set (match_operand:DI 0 "register_operand" "=&c")
19691 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19692 (match_operand:QI 2 "register_operand" "a")
19693 (match_operand:DI 3 "immediate_operand" "i")
19694 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19695 (clobber (match_operand:DI 1 "register_operand" "=D"))
19696 (clobber (reg:CC FLAGS_REG))]
19699 [(set_attr "type" "str")
19700 (set_attr "mode" "QI")
19701 (set_attr "prefix_rep" "1")])
19703 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19704 ;; handled in combine, but it is not currently up to the task.
19705 ;; When used for their truth value, the cmpstrn* expanders generate
19714 ;; The intermediate three instructions are unnecessary.
19716 ;; This one handles cmpstrn*_nz_1...
19719 (set (reg:CC FLAGS_REG)
19720 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19721 (mem:BLK (match_operand 5 "register_operand" ""))))
19722 (use (match_operand 6 "register_operand" ""))
19723 (use (match_operand:SI 3 "immediate_operand" ""))
19724 (clobber (match_operand 0 "register_operand" ""))
19725 (clobber (match_operand 1 "register_operand" ""))
19726 (clobber (match_operand 2 "register_operand" ""))])
19727 (set (match_operand:QI 7 "register_operand" "")
19728 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19729 (set (match_operand:QI 8 "register_operand" "")
19730 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19731 (set (reg FLAGS_REG)
19732 (compare (match_dup 7) (match_dup 8)))
19734 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19736 (set (reg:CC FLAGS_REG)
19737 (compare:CC (mem:BLK (match_dup 4))
19738 (mem:BLK (match_dup 5))))
19739 (use (match_dup 6))
19740 (use (match_dup 3))
19741 (clobber (match_dup 0))
19742 (clobber (match_dup 1))
19743 (clobber (match_dup 2))])]
19746 ;; ...and this one handles cmpstrn*_1.
19749 (set (reg:CC FLAGS_REG)
19750 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19752 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19753 (mem:BLK (match_operand 5 "register_operand" "")))
19755 (use (match_operand:SI 3 "immediate_operand" ""))
19756 (use (reg:CC FLAGS_REG))
19757 (clobber (match_operand 0 "register_operand" ""))
19758 (clobber (match_operand 1 "register_operand" ""))
19759 (clobber (match_operand 2 "register_operand" ""))])
19760 (set (match_operand:QI 7 "register_operand" "")
19761 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19762 (set (match_operand:QI 8 "register_operand" "")
19763 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19764 (set (reg FLAGS_REG)
19765 (compare (match_dup 7) (match_dup 8)))
19767 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19769 (set (reg:CC FLAGS_REG)
19770 (if_then_else:CC (ne (match_dup 6)
19772 (compare:CC (mem:BLK (match_dup 4))
19773 (mem:BLK (match_dup 5)))
19775 (use (match_dup 3))
19776 (use (reg:CC FLAGS_REG))
19777 (clobber (match_dup 0))
19778 (clobber (match_dup 1))
19779 (clobber (match_dup 2))])]
19784 ;; Conditional move instructions.
19786 (define_expand "movdicc"
19787 [(set (match_operand:DI 0 "register_operand" "")
19788 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19789 (match_operand:DI 2 "general_operand" "")
19790 (match_operand:DI 3 "general_operand" "")))]
19792 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19794 (define_insn "x86_movdicc_0_m1_rex64"
19795 [(set (match_operand:DI 0 "register_operand" "=r")
19796 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19799 (clobber (reg:CC FLAGS_REG))]
19802 ; Since we don't have the proper number of operands for an alu insn,
19803 ; fill in all the blanks.
19804 [(set_attr "type" "alu")
19805 (set_attr "pent_pair" "pu")
19806 (set_attr "memory" "none")
19807 (set_attr "imm_disp" "false")
19808 (set_attr "mode" "DI")
19809 (set_attr "length_immediate" "0")])
19811 (define_insn "*x86_movdicc_0_m1_se"
19812 [(set (match_operand:DI 0 "register_operand" "=r")
19813 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19816 (clobber (reg:CC FLAGS_REG))]
19819 [(set_attr "type" "alu")
19820 (set_attr "pent_pair" "pu")
19821 (set_attr "memory" "none")
19822 (set_attr "imm_disp" "false")
19823 (set_attr "mode" "DI")
19824 (set_attr "length_immediate" "0")])
19826 (define_insn "*movdicc_c_rex64"
19827 [(set (match_operand:DI 0 "register_operand" "=r,r")
19828 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19829 [(reg FLAGS_REG) (const_int 0)])
19830 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19831 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19832 "TARGET_64BIT && TARGET_CMOVE
19833 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19835 cmov%O2%C1\t{%2, %0|%0, %2}
19836 cmov%O2%c1\t{%3, %0|%0, %3}"
19837 [(set_attr "type" "icmov")
19838 (set_attr "mode" "DI")])
19840 (define_expand "movsicc"
19841 [(set (match_operand:SI 0 "register_operand" "")
19842 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19843 (match_operand:SI 2 "general_operand" "")
19844 (match_operand:SI 3 "general_operand" "")))]
19846 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19848 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19849 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19850 ;; So just document what we're doing explicitly.
19852 (define_insn "x86_movsicc_0_m1"
19853 [(set (match_operand:SI 0 "register_operand" "=r")
19854 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19857 (clobber (reg:CC FLAGS_REG))]
19860 ; Since we don't have the proper number of operands for an alu insn,
19861 ; fill in all the blanks.
19862 [(set_attr "type" "alu")
19863 (set_attr "pent_pair" "pu")
19864 (set_attr "memory" "none")
19865 (set_attr "imm_disp" "false")
19866 (set_attr "mode" "SI")
19867 (set_attr "length_immediate" "0")])
19869 (define_insn "*x86_movsicc_0_m1_se"
19870 [(set (match_operand:SI 0 "register_operand" "=r")
19871 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19874 (clobber (reg:CC FLAGS_REG))]
19877 [(set_attr "type" "alu")
19878 (set_attr "pent_pair" "pu")
19879 (set_attr "memory" "none")
19880 (set_attr "imm_disp" "false")
19881 (set_attr "mode" "SI")
19882 (set_attr "length_immediate" "0")])
19884 (define_insn "*movsicc_noc"
19885 [(set (match_operand:SI 0 "register_operand" "=r,r")
19886 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19887 [(reg FLAGS_REG) (const_int 0)])
19888 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19889 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19891 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19893 cmov%O2%C1\t{%2, %0|%0, %2}
19894 cmov%O2%c1\t{%3, %0|%0, %3}"
19895 [(set_attr "type" "icmov")
19896 (set_attr "mode" "SI")])
19898 (define_expand "movhicc"
19899 [(set (match_operand:HI 0 "register_operand" "")
19900 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19901 (match_operand:HI 2 "general_operand" "")
19902 (match_operand:HI 3 "general_operand" "")))]
19903 "TARGET_HIMODE_MATH"
19904 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19906 (define_insn "*movhicc_noc"
19907 [(set (match_operand:HI 0 "register_operand" "=r,r")
19908 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19909 [(reg FLAGS_REG) (const_int 0)])
19910 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19911 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19913 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19915 cmov%O2%C1\t{%2, %0|%0, %2}
19916 cmov%O2%c1\t{%3, %0|%0, %3}"
19917 [(set_attr "type" "icmov")
19918 (set_attr "mode" "HI")])
19920 (define_expand "movqicc"
19921 [(set (match_operand:QI 0 "register_operand" "")
19922 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19923 (match_operand:QI 2 "general_operand" "")
19924 (match_operand:QI 3 "general_operand" "")))]
19925 "TARGET_QIMODE_MATH"
19926 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19928 (define_insn_and_split "*movqicc_noc"
19929 [(set (match_operand:QI 0 "register_operand" "=r,r")
19930 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19931 [(match_operand 4 "flags_reg_operand" "")
19933 (match_operand:QI 2 "register_operand" "r,0")
19934 (match_operand:QI 3 "register_operand" "0,r")))]
19935 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19937 "&& reload_completed"
19938 [(set (match_dup 0)
19939 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19942 "operands[0] = gen_lowpart (SImode, operands[0]);
19943 operands[2] = gen_lowpart (SImode, operands[2]);
19944 operands[3] = gen_lowpart (SImode, operands[3]);"
19945 [(set_attr "type" "icmov")
19946 (set_attr "mode" "SI")])
19948 (define_expand "mov<mode>cc"
19949 [(set (match_operand:X87MODEF 0 "register_operand" "")
19950 (if_then_else:X87MODEF
19951 (match_operand 1 "comparison_operator" "")
19952 (match_operand:X87MODEF 2 "register_operand" "")
19953 (match_operand:X87MODEF 3 "register_operand" "")))]
19954 "(TARGET_80387 && TARGET_CMOVE)
19955 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19956 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19958 (define_insn "*movsfcc_1_387"
19959 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19960 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19961 [(reg FLAGS_REG) (const_int 0)])
19962 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19963 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19964 "TARGET_80387 && TARGET_CMOVE
19965 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19967 fcmov%F1\t{%2, %0|%0, %2}
19968 fcmov%f1\t{%3, %0|%0, %3}
19969 cmov%O2%C1\t{%2, %0|%0, %2}
19970 cmov%O2%c1\t{%3, %0|%0, %3}"
19971 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19972 (set_attr "mode" "SF,SF,SI,SI")])
19974 (define_insn "*movdfcc_1"
19975 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19976 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19977 [(reg FLAGS_REG) (const_int 0)])
19978 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19979 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19980 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19981 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19983 fcmov%F1\t{%2, %0|%0, %2}
19984 fcmov%f1\t{%3, %0|%0, %3}
19987 [(set_attr "type" "fcmov,fcmov,multi,multi")
19988 (set_attr "mode" "DF")])
19990 (define_insn "*movdfcc_1_rex64"
19991 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19992 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19993 [(reg FLAGS_REG) (const_int 0)])
19994 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19995 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19996 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19997 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19999 fcmov%F1\t{%2, %0|%0, %2}
20000 fcmov%f1\t{%3, %0|%0, %3}
20001 cmov%O2%C1\t{%2, %0|%0, %2}
20002 cmov%O2%c1\t{%3, %0|%0, %3}"
20003 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20004 (set_attr "mode" "DF")])
20007 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20008 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20009 [(match_operand 4 "flags_reg_operand" "")
20011 (match_operand:DF 2 "nonimmediate_operand" "")
20012 (match_operand:DF 3 "nonimmediate_operand" "")))]
20013 "!TARGET_64BIT && reload_completed"
20014 [(set (match_dup 2)
20015 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20019 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20022 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20023 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20025 (define_insn "*movxfcc_1"
20026 [(set (match_operand:XF 0 "register_operand" "=f,f")
20027 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20028 [(reg FLAGS_REG) (const_int 0)])
20029 (match_operand:XF 2 "register_operand" "f,0")
20030 (match_operand:XF 3 "register_operand" "0,f")))]
20031 "TARGET_80387 && TARGET_CMOVE"
20033 fcmov%F1\t{%2, %0|%0, %2}
20034 fcmov%f1\t{%3, %0|%0, %3}"
20035 [(set_attr "type" "fcmov")
20036 (set_attr "mode" "XF")])
20038 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20039 ;; the scalar versions to have only XMM registers as operands.
20041 ;; SSE5 conditional move
20042 (define_insn "*sse5_pcmov_<mode>"
20043 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20044 (if_then_else:MODEF
20045 (match_operand:MODEF 1 "register_operand" "x,0")
20046 (match_operand:MODEF 2 "register_operand" "0,x")
20047 (match_operand:MODEF 3 "register_operand" "x,x")))]
20048 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20049 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20050 [(set_attr "type" "sse4arg")])
20052 ;; These versions of the min/max patterns are intentionally ignorant of
20053 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20054 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20055 ;; are undefined in this condition, we're certain this is correct.
20057 (define_insn "*avx_<code><mode>3"
20058 [(set (match_operand:MODEF 0 "register_operand" "=x")
20060 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20061 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20062 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20063 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20064 [(set_attr "type" "sseadd")
20065 (set_attr "prefix" "vex")
20066 (set_attr "mode" "<MODE>")])
20068 (define_insn "<code><mode>3"
20069 [(set (match_operand:MODEF 0 "register_operand" "=x")
20071 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20072 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20074 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20075 [(set_attr "type" "sseadd")
20076 (set_attr "mode" "<MODE>")])
20078 ;; These versions of the min/max patterns implement exactly the operations
20079 ;; min = (op1 < op2 ? op1 : op2)
20080 ;; max = (!(op1 < op2) ? op1 : op2)
20081 ;; Their operands are not commutative, and thus they may be used in the
20082 ;; presence of -0.0 and NaN.
20084 (define_insn "*avx_ieee_smin<mode>3"
20085 [(set (match_operand:MODEF 0 "register_operand" "=x")
20087 [(match_operand:MODEF 1 "register_operand" "x")
20088 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20090 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20091 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20092 [(set_attr "type" "sseadd")
20093 (set_attr "prefix" "vex")
20094 (set_attr "mode" "<MODE>")])
20096 (define_insn "*ieee_smin<mode>3"
20097 [(set (match_operand:MODEF 0 "register_operand" "=x")
20099 [(match_operand:MODEF 1 "register_operand" "0")
20100 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20102 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20103 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20104 [(set_attr "type" "sseadd")
20105 (set_attr "mode" "<MODE>")])
20107 (define_insn "*avx_ieee_smax<mode>3"
20108 [(set (match_operand:MODEF 0 "register_operand" "=x")
20110 [(match_operand:MODEF 1 "register_operand" "0")
20111 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20113 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20114 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20115 [(set_attr "type" "sseadd")
20116 (set_attr "prefix" "vex")
20117 (set_attr "mode" "<MODE>")])
20119 (define_insn "*ieee_smax<mode>3"
20120 [(set (match_operand:MODEF 0 "register_operand" "=x")
20122 [(match_operand:MODEF 1 "register_operand" "0")
20123 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20125 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20126 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20127 [(set_attr "type" "sseadd")
20128 (set_attr "mode" "<MODE>")])
20130 ;; Make two stack loads independent:
20132 ;; fld %st(0) -> fld bb
20133 ;; fmul bb fmul %st(1), %st
20135 ;; Actually we only match the last two instructions for simplicity.
20137 [(set (match_operand 0 "fp_register_operand" "")
20138 (match_operand 1 "fp_register_operand" ""))
20140 (match_operator 2 "binary_fp_operator"
20142 (match_operand 3 "memory_operand" "")]))]
20143 "REGNO (operands[0]) != REGNO (operands[1])"
20144 [(set (match_dup 0) (match_dup 3))
20145 (set (match_dup 0) (match_dup 4))]
20147 ;; The % modifier is not operational anymore in peephole2's, so we have to
20148 ;; swap the operands manually in the case of addition and multiplication.
20149 "if (COMMUTATIVE_ARITH_P (operands[2]))
20150 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20151 operands[0], operands[1]);
20153 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20154 operands[1], operands[0]);")
20156 ;; Conditional addition patterns
20157 (define_expand "add<mode>cc"
20158 [(match_operand:SWI 0 "register_operand" "")
20159 (match_operand 1 "comparison_operator" "")
20160 (match_operand:SWI 2 "register_operand" "")
20161 (match_operand:SWI 3 "const_int_operand" "")]
20163 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20166 ;; Misc patterns (?)
20168 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20169 ;; Otherwise there will be nothing to keep
20171 ;; [(set (reg ebp) (reg esp))]
20172 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20173 ;; (clobber (eflags)]
20174 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20176 ;; in proper program order.
20177 (define_insn "pro_epilogue_adjust_stack_1"
20178 [(set (match_operand:SI 0 "register_operand" "=r,r")
20179 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20180 (match_operand:SI 2 "immediate_operand" "i,i")))
20181 (clobber (reg:CC FLAGS_REG))
20182 (clobber (mem:BLK (scratch)))]
20185 switch (get_attr_type (insn))
20188 return "mov{l}\t{%1, %0|%0, %1}";
20191 if (CONST_INT_P (operands[2])
20192 && (INTVAL (operands[2]) == 128
20193 || (INTVAL (operands[2]) < 0
20194 && INTVAL (operands[2]) != -128)))
20196 operands[2] = GEN_INT (-INTVAL (operands[2]));
20197 return "sub{l}\t{%2, %0|%0, %2}";
20199 return "add{l}\t{%2, %0|%0, %2}";
20202 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20203 return "lea{l}\t{%a2, %0|%0, %a2}";
20206 gcc_unreachable ();
20209 [(set (attr "type")
20210 (cond [(eq_attr "alternative" "0")
20211 (const_string "alu")
20212 (match_operand:SI 2 "const0_operand" "")
20213 (const_string "imov")
20215 (const_string "lea")))
20216 (set_attr "mode" "SI")])
20218 (define_insn "pro_epilogue_adjust_stack_rex64"
20219 [(set (match_operand:DI 0 "register_operand" "=r,r")
20220 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20221 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20222 (clobber (reg:CC FLAGS_REG))
20223 (clobber (mem:BLK (scratch)))]
20226 switch (get_attr_type (insn))
20229 return "mov{q}\t{%1, %0|%0, %1}";
20232 if (CONST_INT_P (operands[2])
20233 /* Avoid overflows. */
20234 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20235 && (INTVAL (operands[2]) == 128
20236 || (INTVAL (operands[2]) < 0
20237 && INTVAL (operands[2]) != -128)))
20239 operands[2] = GEN_INT (-INTVAL (operands[2]));
20240 return "sub{q}\t{%2, %0|%0, %2}";
20242 return "add{q}\t{%2, %0|%0, %2}";
20245 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20246 return "lea{q}\t{%a2, %0|%0, %a2}";
20249 gcc_unreachable ();
20252 [(set (attr "type")
20253 (cond [(eq_attr "alternative" "0")
20254 (const_string "alu")
20255 (match_operand:DI 2 "const0_operand" "")
20256 (const_string "imov")
20258 (const_string "lea")))
20259 (set_attr "mode" "DI")])
20261 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20262 [(set (match_operand:DI 0 "register_operand" "=r,r")
20263 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20264 (match_operand:DI 3 "immediate_operand" "i,i")))
20265 (use (match_operand:DI 2 "register_operand" "r,r"))
20266 (clobber (reg:CC FLAGS_REG))
20267 (clobber (mem:BLK (scratch)))]
20270 switch (get_attr_type (insn))
20273 return "add{q}\t{%2, %0|%0, %2}";
20276 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20277 return "lea{q}\t{%a2, %0|%0, %a2}";
20280 gcc_unreachable ();
20283 [(set_attr "type" "alu,lea")
20284 (set_attr "mode" "DI")])
20286 (define_insn "allocate_stack_worker_32"
20287 [(set (match_operand:SI 0 "register_operand" "=a")
20288 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20289 UNSPECV_STACK_PROBE))
20290 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20291 (clobber (reg:CC FLAGS_REG))]
20292 "!TARGET_64BIT && TARGET_STACK_PROBE"
20294 [(set_attr "type" "multi")
20295 (set_attr "length" "5")])
20297 (define_insn "allocate_stack_worker_64"
20298 [(set (match_operand:DI 0 "register_operand" "=a")
20299 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20300 UNSPECV_STACK_PROBE))
20301 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20302 (clobber (reg:DI R10_REG))
20303 (clobber (reg:DI R11_REG))
20304 (clobber (reg:CC FLAGS_REG))]
20305 "TARGET_64BIT && TARGET_STACK_PROBE"
20307 [(set_attr "type" "multi")
20308 (set_attr "length" "5")])
20310 (define_expand "allocate_stack"
20311 [(match_operand 0 "register_operand" "")
20312 (match_operand 1 "general_operand" "")]
20313 "TARGET_STACK_PROBE"
20317 #ifndef CHECK_STACK_LIMIT
20318 #define CHECK_STACK_LIMIT 0
20321 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20322 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20324 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20325 stack_pointer_rtx, 0, OPTAB_DIRECT);
20326 if (x != stack_pointer_rtx)
20327 emit_move_insn (stack_pointer_rtx, x);
20331 x = copy_to_mode_reg (Pmode, operands[1]);
20333 x = gen_allocate_stack_worker_64 (x, x);
20335 x = gen_allocate_stack_worker_32 (x, x);
20339 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20343 (define_expand "builtin_setjmp_receiver"
20344 [(label_ref (match_operand 0 "" ""))]
20345 "!TARGET_64BIT && flag_pic"
20351 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20352 rtx label_rtx = gen_label_rtx ();
20353 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20354 xops[0] = xops[1] = picreg;
20355 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20356 ix86_expand_binary_operator (MINUS, SImode, xops);
20360 emit_insn (gen_set_got (pic_offset_table_rtx));
20364 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20367 [(set (match_operand 0 "register_operand" "")
20368 (match_operator 3 "promotable_binary_operator"
20369 [(match_operand 1 "register_operand" "")
20370 (match_operand 2 "aligned_operand" "")]))
20371 (clobber (reg:CC FLAGS_REG))]
20372 "! TARGET_PARTIAL_REG_STALL && reload_completed
20373 && ((GET_MODE (operands[0]) == HImode
20374 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20375 /* ??? next two lines just !satisfies_constraint_K (...) */
20376 || !CONST_INT_P (operands[2])
20377 || satisfies_constraint_K (operands[2])))
20378 || (GET_MODE (operands[0]) == QImode
20379 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20380 [(parallel [(set (match_dup 0)
20381 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20382 (clobber (reg:CC FLAGS_REG))])]
20383 "operands[0] = gen_lowpart (SImode, operands[0]);
20384 operands[1] = gen_lowpart (SImode, operands[1]);
20385 if (GET_CODE (operands[3]) != ASHIFT)
20386 operands[2] = gen_lowpart (SImode, operands[2]);
20387 PUT_MODE (operands[3], SImode);")
20389 ; Promote the QImode tests, as i386 has encoding of the AND
20390 ; instruction with 32-bit sign-extended immediate and thus the
20391 ; instruction size is unchanged, except in the %eax case for
20392 ; which it is increased by one byte, hence the ! optimize_size.
20394 [(set (match_operand 0 "flags_reg_operand" "")
20395 (match_operator 2 "compare_operator"
20396 [(and (match_operand 3 "aligned_operand" "")
20397 (match_operand 4 "const_int_operand" ""))
20399 (set (match_operand 1 "register_operand" "")
20400 (and (match_dup 3) (match_dup 4)))]
20401 "! TARGET_PARTIAL_REG_STALL && reload_completed
20402 && optimize_insn_for_speed_p ()
20403 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20404 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20405 /* Ensure that the operand will remain sign-extended immediate. */
20406 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20407 [(parallel [(set (match_dup 0)
20408 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20411 (and:SI (match_dup 3) (match_dup 4)))])]
20414 = gen_int_mode (INTVAL (operands[4])
20415 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20416 operands[1] = gen_lowpart (SImode, operands[1]);
20417 operands[3] = gen_lowpart (SImode, operands[3]);
20420 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20421 ; the TEST instruction with 32-bit sign-extended immediate and thus
20422 ; the instruction size would at least double, which is not what we
20423 ; want even with ! optimize_size.
20425 [(set (match_operand 0 "flags_reg_operand" "")
20426 (match_operator 1 "compare_operator"
20427 [(and (match_operand:HI 2 "aligned_operand" "")
20428 (match_operand:HI 3 "const_int_operand" ""))
20430 "! TARGET_PARTIAL_REG_STALL && reload_completed
20431 && ! TARGET_FAST_PREFIX
20432 && optimize_insn_for_speed_p ()
20433 /* Ensure that the operand will remain sign-extended immediate. */
20434 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20435 [(set (match_dup 0)
20436 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20440 = gen_int_mode (INTVAL (operands[3])
20441 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20442 operands[2] = gen_lowpart (SImode, operands[2]);
20446 [(set (match_operand 0 "register_operand" "")
20447 (neg (match_operand 1 "register_operand" "")))
20448 (clobber (reg:CC FLAGS_REG))]
20449 "! TARGET_PARTIAL_REG_STALL && reload_completed
20450 && (GET_MODE (operands[0]) == HImode
20451 || (GET_MODE (operands[0]) == QImode
20452 && (TARGET_PROMOTE_QImode
20453 || optimize_insn_for_size_p ())))"
20454 [(parallel [(set (match_dup 0)
20455 (neg:SI (match_dup 1)))
20456 (clobber (reg:CC FLAGS_REG))])]
20457 "operands[0] = gen_lowpart (SImode, operands[0]);
20458 operands[1] = gen_lowpart (SImode, operands[1]);")
20461 [(set (match_operand 0 "register_operand" "")
20462 (not (match_operand 1 "register_operand" "")))]
20463 "! TARGET_PARTIAL_REG_STALL && reload_completed
20464 && (GET_MODE (operands[0]) == HImode
20465 || (GET_MODE (operands[0]) == QImode
20466 && (TARGET_PROMOTE_QImode
20467 || optimize_insn_for_size_p ())))"
20468 [(set (match_dup 0)
20469 (not:SI (match_dup 1)))]
20470 "operands[0] = gen_lowpart (SImode, operands[0]);
20471 operands[1] = gen_lowpart (SImode, operands[1]);")
20474 [(set (match_operand 0 "register_operand" "")
20475 (if_then_else (match_operator 1 "comparison_operator"
20476 [(reg FLAGS_REG) (const_int 0)])
20477 (match_operand 2 "register_operand" "")
20478 (match_operand 3 "register_operand" "")))]
20479 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20480 && (GET_MODE (operands[0]) == HImode
20481 || (GET_MODE (operands[0]) == QImode
20482 && (TARGET_PROMOTE_QImode
20483 || optimize_insn_for_size_p ())))"
20484 [(set (match_dup 0)
20485 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20486 "operands[0] = gen_lowpart (SImode, operands[0]);
20487 operands[2] = gen_lowpart (SImode, operands[2]);
20488 operands[3] = gen_lowpart (SImode, operands[3]);")
20491 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20492 ;; transform a complex memory operation into two memory to register operations.
20494 ;; Don't push memory operands
20496 [(set (match_operand:SI 0 "push_operand" "")
20497 (match_operand:SI 1 "memory_operand" ""))
20498 (match_scratch:SI 2 "r")]
20499 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20500 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20501 [(set (match_dup 2) (match_dup 1))
20502 (set (match_dup 0) (match_dup 2))]
20506 [(set (match_operand:DI 0 "push_operand" "")
20507 (match_operand:DI 1 "memory_operand" ""))
20508 (match_scratch:DI 2 "r")]
20509 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20510 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20511 [(set (match_dup 2) (match_dup 1))
20512 (set (match_dup 0) (match_dup 2))]
20515 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20518 [(set (match_operand:SF 0 "push_operand" "")
20519 (match_operand:SF 1 "memory_operand" ""))
20520 (match_scratch:SF 2 "r")]
20521 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20522 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20523 [(set (match_dup 2) (match_dup 1))
20524 (set (match_dup 0) (match_dup 2))]
20528 [(set (match_operand:HI 0 "push_operand" "")
20529 (match_operand:HI 1 "memory_operand" ""))
20530 (match_scratch:HI 2 "r")]
20531 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20532 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20533 [(set (match_dup 2) (match_dup 1))
20534 (set (match_dup 0) (match_dup 2))]
20538 [(set (match_operand:QI 0 "push_operand" "")
20539 (match_operand:QI 1 "memory_operand" ""))
20540 (match_scratch:QI 2 "q")]
20541 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20542 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20543 [(set (match_dup 2) (match_dup 1))
20544 (set (match_dup 0) (match_dup 2))]
20547 ;; Don't move an immediate directly to memory when the instruction
20550 [(match_scratch:SI 1 "r")
20551 (set (match_operand:SI 0 "memory_operand" "")
20553 "optimize_insn_for_speed_p ()
20554 && ! TARGET_USE_MOV0
20555 && TARGET_SPLIT_LONG_MOVES
20556 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20557 && peep2_regno_dead_p (0, FLAGS_REG)"
20558 [(parallel [(set (match_dup 1) (const_int 0))
20559 (clobber (reg:CC FLAGS_REG))])
20560 (set (match_dup 0) (match_dup 1))]
20564 [(match_scratch:HI 1 "r")
20565 (set (match_operand:HI 0 "memory_operand" "")
20567 "optimize_insn_for_speed_p ()
20568 && ! TARGET_USE_MOV0
20569 && TARGET_SPLIT_LONG_MOVES
20570 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20571 && peep2_regno_dead_p (0, FLAGS_REG)"
20572 [(parallel [(set (match_dup 2) (const_int 0))
20573 (clobber (reg:CC FLAGS_REG))])
20574 (set (match_dup 0) (match_dup 1))]
20575 "operands[2] = gen_lowpart (SImode, operands[1]);")
20578 [(match_scratch:QI 1 "q")
20579 (set (match_operand:QI 0 "memory_operand" "")
20581 "optimize_insn_for_speed_p ()
20582 && ! TARGET_USE_MOV0
20583 && TARGET_SPLIT_LONG_MOVES
20584 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20585 && peep2_regno_dead_p (0, FLAGS_REG)"
20586 [(parallel [(set (match_dup 2) (const_int 0))
20587 (clobber (reg:CC FLAGS_REG))])
20588 (set (match_dup 0) (match_dup 1))]
20589 "operands[2] = gen_lowpart (SImode, operands[1]);")
20592 [(match_scratch:SI 2 "r")
20593 (set (match_operand:SI 0 "memory_operand" "")
20594 (match_operand:SI 1 "immediate_operand" ""))]
20595 "optimize_insn_for_speed_p ()
20596 && TARGET_SPLIT_LONG_MOVES
20597 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20598 [(set (match_dup 2) (match_dup 1))
20599 (set (match_dup 0) (match_dup 2))]
20603 [(match_scratch:HI 2 "r")
20604 (set (match_operand:HI 0 "memory_operand" "")
20605 (match_operand:HI 1 "immediate_operand" ""))]
20606 "optimize_insn_for_speed_p ()
20607 && TARGET_SPLIT_LONG_MOVES
20608 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20609 [(set (match_dup 2) (match_dup 1))
20610 (set (match_dup 0) (match_dup 2))]
20614 [(match_scratch:QI 2 "q")
20615 (set (match_operand:QI 0 "memory_operand" "")
20616 (match_operand:QI 1 "immediate_operand" ""))]
20617 "optimize_insn_for_speed_p ()
20618 && TARGET_SPLIT_LONG_MOVES
20619 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20620 [(set (match_dup 2) (match_dup 1))
20621 (set (match_dup 0) (match_dup 2))]
20624 ;; Don't compare memory with zero, load and use a test instead.
20626 [(set (match_operand 0 "flags_reg_operand" "")
20627 (match_operator 1 "compare_operator"
20628 [(match_operand:SI 2 "memory_operand" "")
20630 (match_scratch:SI 3 "r")]
20631 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20632 [(set (match_dup 3) (match_dup 2))
20633 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20636 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20637 ;; Don't split NOTs with a displacement operand, because resulting XOR
20638 ;; will not be pairable anyway.
20640 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20641 ;; represented using a modRM byte. The XOR replacement is long decoded,
20642 ;; so this split helps here as well.
20644 ;; Note: Can't do this as a regular split because we can't get proper
20645 ;; lifetime information then.
20648 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20649 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20650 "optimize_insn_for_speed_p ()
20651 && ((TARGET_NOT_UNPAIRABLE
20652 && (!MEM_P (operands[0])
20653 || !memory_displacement_operand (operands[0], SImode)))
20654 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20655 && peep2_regno_dead_p (0, FLAGS_REG)"
20656 [(parallel [(set (match_dup 0)
20657 (xor:SI (match_dup 1) (const_int -1)))
20658 (clobber (reg:CC FLAGS_REG))])]
20662 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20663 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20664 "optimize_insn_for_speed_p ()
20665 && ((TARGET_NOT_UNPAIRABLE
20666 && (!MEM_P (operands[0])
20667 || !memory_displacement_operand (operands[0], HImode)))
20668 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20669 && peep2_regno_dead_p (0, FLAGS_REG)"
20670 [(parallel [(set (match_dup 0)
20671 (xor:HI (match_dup 1) (const_int -1)))
20672 (clobber (reg:CC FLAGS_REG))])]
20676 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20677 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20678 "optimize_insn_for_speed_p ()
20679 && ((TARGET_NOT_UNPAIRABLE
20680 && (!MEM_P (operands[0])
20681 || !memory_displacement_operand (operands[0], QImode)))
20682 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20683 && peep2_regno_dead_p (0, FLAGS_REG)"
20684 [(parallel [(set (match_dup 0)
20685 (xor:QI (match_dup 1) (const_int -1)))
20686 (clobber (reg:CC FLAGS_REG))])]
20689 ;; Non pairable "test imm, reg" instructions can be translated to
20690 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20691 ;; byte opcode instead of two, have a short form for byte operands),
20692 ;; so do it for other CPUs as well. Given that the value was dead,
20693 ;; this should not create any new dependencies. Pass on the sub-word
20694 ;; versions if we're concerned about partial register stalls.
20697 [(set (match_operand 0 "flags_reg_operand" "")
20698 (match_operator 1 "compare_operator"
20699 [(and:SI (match_operand:SI 2 "register_operand" "")
20700 (match_operand:SI 3 "immediate_operand" ""))
20702 "ix86_match_ccmode (insn, CCNOmode)
20703 && (true_regnum (operands[2]) != AX_REG
20704 || satisfies_constraint_K (operands[3]))
20705 && peep2_reg_dead_p (1, operands[2])"
20707 [(set (match_dup 0)
20708 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20711 (and:SI (match_dup 2) (match_dup 3)))])]
20714 ;; We don't need to handle HImode case, because it will be promoted to SImode
20715 ;; on ! TARGET_PARTIAL_REG_STALL
20718 [(set (match_operand 0 "flags_reg_operand" "")
20719 (match_operator 1 "compare_operator"
20720 [(and:QI (match_operand:QI 2 "register_operand" "")
20721 (match_operand:QI 3 "immediate_operand" ""))
20723 "! TARGET_PARTIAL_REG_STALL
20724 && ix86_match_ccmode (insn, CCNOmode)
20725 && true_regnum (operands[2]) != AX_REG
20726 && peep2_reg_dead_p (1, operands[2])"
20728 [(set (match_dup 0)
20729 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20732 (and:QI (match_dup 2) (match_dup 3)))])]
20736 [(set (match_operand 0 "flags_reg_operand" "")
20737 (match_operator 1 "compare_operator"
20740 (match_operand 2 "ext_register_operand" "")
20743 (match_operand 3 "const_int_operand" ""))
20745 "! TARGET_PARTIAL_REG_STALL
20746 && ix86_match_ccmode (insn, CCNOmode)
20747 && true_regnum (operands[2]) != AX_REG
20748 && peep2_reg_dead_p (1, operands[2])"
20749 [(parallel [(set (match_dup 0)
20758 (set (zero_extract:SI (match_dup 2)
20769 ;; Don't do logical operations with memory inputs.
20771 [(match_scratch:SI 2 "r")
20772 (parallel [(set (match_operand:SI 0 "register_operand" "")
20773 (match_operator:SI 3 "arith_or_logical_operator"
20775 (match_operand:SI 1 "memory_operand" "")]))
20776 (clobber (reg:CC FLAGS_REG))])]
20777 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20778 [(set (match_dup 2) (match_dup 1))
20779 (parallel [(set (match_dup 0)
20780 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20781 (clobber (reg:CC FLAGS_REG))])]
20785 [(match_scratch:SI 2 "r")
20786 (parallel [(set (match_operand:SI 0 "register_operand" "")
20787 (match_operator:SI 3 "arith_or_logical_operator"
20788 [(match_operand:SI 1 "memory_operand" "")
20790 (clobber (reg:CC FLAGS_REG))])]
20791 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20792 [(set (match_dup 2) (match_dup 1))
20793 (parallel [(set (match_dup 0)
20794 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20795 (clobber (reg:CC FLAGS_REG))])]
20798 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20799 ;; refers to the destination of the load!
20802 [(set (match_operand:SI 0 "register_operand" "")
20803 (match_operand:SI 1 "register_operand" ""))
20804 (parallel [(set (match_dup 0)
20805 (match_operator:SI 3 "commutative_operator"
20807 (match_operand:SI 2 "memory_operand" "")]))
20808 (clobber (reg:CC FLAGS_REG))])]
20809 "REGNO (operands[0]) != REGNO (operands[1])
20810 && GENERAL_REGNO_P (REGNO (operands[0]))
20811 && GENERAL_REGNO_P (REGNO (operands[1]))"
20812 [(set (match_dup 0) (match_dup 4))
20813 (parallel [(set (match_dup 0)
20814 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20815 (clobber (reg:CC FLAGS_REG))])]
20816 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20819 [(set (match_operand 0 "register_operand" "")
20820 (match_operand 1 "register_operand" ""))
20822 (match_operator 3 "commutative_operator"
20824 (match_operand 2 "memory_operand" "")]))]
20825 "REGNO (operands[0]) != REGNO (operands[1])
20826 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20827 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20828 [(set (match_dup 0) (match_dup 2))
20830 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20833 ; Don't do logical operations with memory outputs
20835 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20836 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20837 ; the same decoder scheduling characteristics as the original.
20840 [(match_scratch:SI 2 "r")
20841 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20842 (match_operator:SI 3 "arith_or_logical_operator"
20844 (match_operand:SI 1 "nonmemory_operand" "")]))
20845 (clobber (reg:CC FLAGS_REG))])]
20846 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20847 [(set (match_dup 2) (match_dup 0))
20848 (parallel [(set (match_dup 2)
20849 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20850 (clobber (reg:CC FLAGS_REG))])
20851 (set (match_dup 0) (match_dup 2))]
20855 [(match_scratch:SI 2 "r")
20856 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20857 (match_operator:SI 3 "arith_or_logical_operator"
20858 [(match_operand:SI 1 "nonmemory_operand" "")
20860 (clobber (reg:CC FLAGS_REG))])]
20861 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20862 [(set (match_dup 2) (match_dup 0))
20863 (parallel [(set (match_dup 2)
20864 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20865 (clobber (reg:CC FLAGS_REG))])
20866 (set (match_dup 0) (match_dup 2))]
20869 ;; Attempt to always use XOR for zeroing registers.
20871 [(set (match_operand 0 "register_operand" "")
20872 (match_operand 1 "const0_operand" ""))]
20873 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20874 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20875 && GENERAL_REG_P (operands[0])
20876 && peep2_regno_dead_p (0, FLAGS_REG)"
20877 [(parallel [(set (match_dup 0) (const_int 0))
20878 (clobber (reg:CC FLAGS_REG))])]
20880 operands[0] = gen_lowpart (word_mode, operands[0]);
20884 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20886 "(GET_MODE (operands[0]) == QImode
20887 || GET_MODE (operands[0]) == HImode)
20888 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20889 && peep2_regno_dead_p (0, FLAGS_REG)"
20890 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20891 (clobber (reg:CC FLAGS_REG))])])
20893 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20895 [(set (match_operand 0 "register_operand" "")
20897 "(GET_MODE (operands[0]) == HImode
20898 || GET_MODE (operands[0]) == SImode
20899 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20900 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20901 && peep2_regno_dead_p (0, FLAGS_REG)"
20902 [(parallel [(set (match_dup 0) (const_int -1))
20903 (clobber (reg:CC FLAGS_REG))])]
20904 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20907 ;; Attempt to convert simple leas to adds. These can be created by
20910 [(set (match_operand:SI 0 "register_operand" "")
20911 (plus:SI (match_dup 0)
20912 (match_operand:SI 1 "nonmemory_operand" "")))]
20913 "peep2_regno_dead_p (0, FLAGS_REG)"
20914 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20915 (clobber (reg:CC FLAGS_REG))])]
20919 [(set (match_operand:SI 0 "register_operand" "")
20920 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20921 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20922 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20923 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20924 (clobber (reg:CC FLAGS_REG))])]
20925 "operands[2] = gen_lowpart (SImode, operands[2]);")
20928 [(set (match_operand:DI 0 "register_operand" "")
20929 (plus:DI (match_dup 0)
20930 (match_operand:DI 1 "x86_64_general_operand" "")))]
20931 "peep2_regno_dead_p (0, FLAGS_REG)"
20932 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20933 (clobber (reg:CC FLAGS_REG))])]
20937 [(set (match_operand:SI 0 "register_operand" "")
20938 (mult:SI (match_dup 0)
20939 (match_operand:SI 1 "const_int_operand" "")))]
20940 "exact_log2 (INTVAL (operands[1])) >= 0
20941 && peep2_regno_dead_p (0, FLAGS_REG)"
20942 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20943 (clobber (reg:CC FLAGS_REG))])]
20944 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20947 [(set (match_operand:DI 0 "register_operand" "")
20948 (mult:DI (match_dup 0)
20949 (match_operand:DI 1 "const_int_operand" "")))]
20950 "exact_log2 (INTVAL (operands[1])) >= 0
20951 && peep2_regno_dead_p (0, FLAGS_REG)"
20952 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20953 (clobber (reg:CC FLAGS_REG))])]
20954 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20957 [(set (match_operand:SI 0 "register_operand" "")
20958 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20959 (match_operand:DI 2 "const_int_operand" "")) 0))]
20960 "exact_log2 (INTVAL (operands[2])) >= 0
20961 && REGNO (operands[0]) == REGNO (operands[1])
20962 && peep2_regno_dead_p (0, FLAGS_REG)"
20963 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20964 (clobber (reg:CC FLAGS_REG))])]
20965 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20967 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20968 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20969 ;; many CPUs it is also faster, since special hardware to avoid esp
20970 ;; dependencies is present.
20972 ;; While some of these conversions may be done using splitters, we use peepholes
20973 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20975 ;; Convert prologue esp subtractions to push.
20976 ;; We need register to push. In order to keep verify_flow_info happy we have
20978 ;; - use scratch and clobber it in order to avoid dependencies
20979 ;; - use already live register
20980 ;; We can't use the second way right now, since there is no reliable way how to
20981 ;; verify that given register is live. First choice will also most likely in
20982 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20983 ;; call clobbered registers are dead. We may want to use base pointer as an
20984 ;; alternative when no register is available later.
20987 [(match_scratch:SI 0 "r")
20988 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20989 (clobber (reg:CC FLAGS_REG))
20990 (clobber (mem:BLK (scratch)))])]
20991 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20992 [(clobber (match_dup 0))
20993 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20994 (clobber (mem:BLK (scratch)))])])
20997 [(match_scratch:SI 0 "r")
20998 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20999 (clobber (reg:CC FLAGS_REG))
21000 (clobber (mem:BLK (scratch)))])]
21001 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21002 [(clobber (match_dup 0))
21003 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21004 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21005 (clobber (mem:BLK (scratch)))])])
21007 ;; Convert esp subtractions to push.
21009 [(match_scratch:SI 0 "r")
21010 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21011 (clobber (reg:CC FLAGS_REG))])]
21012 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21013 [(clobber (match_dup 0))
21014 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21017 [(match_scratch:SI 0 "r")
21018 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21019 (clobber (reg:CC FLAGS_REG))])]
21020 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21021 [(clobber (match_dup 0))
21022 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21023 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21025 ;; Convert epilogue deallocator to pop.
21027 [(match_scratch:SI 0 "r")
21028 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21029 (clobber (reg:CC FLAGS_REG))
21030 (clobber (mem:BLK (scratch)))])]
21031 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21032 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21033 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21034 (clobber (mem:BLK (scratch)))])]
21037 ;; Two pops case is tricky, since pop causes dependency on destination register.
21038 ;; We use two registers if available.
21040 [(match_scratch:SI 0 "r")
21041 (match_scratch:SI 1 "r")
21042 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21043 (clobber (reg:CC FLAGS_REG))
21044 (clobber (mem:BLK (scratch)))])]
21045 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21046 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21047 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21048 (clobber (mem:BLK (scratch)))])
21049 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21050 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21054 [(match_scratch:SI 0 "r")
21055 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21056 (clobber (reg:CC FLAGS_REG))
21057 (clobber (mem:BLK (scratch)))])]
21058 "optimize_insn_for_size_p ()"
21059 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21060 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21061 (clobber (mem:BLK (scratch)))])
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)))])]
21066 ;; Convert esp additions to pop.
21068 [(match_scratch:SI 0 "r")
21069 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21070 (clobber (reg:CC FLAGS_REG))])]
21072 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21073 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21076 ;; Two pops case is tricky, since pop causes dependency on destination register.
21077 ;; We use two registers if available.
21079 [(match_scratch:SI 0 "r")
21080 (match_scratch:SI 1 "r")
21081 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21082 (clobber (reg:CC FLAGS_REG))])]
21084 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21086 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21087 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21091 [(match_scratch:SI 0 "r")
21092 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21093 (clobber (reg:CC FLAGS_REG))])]
21094 "optimize_insn_for_size_p ()"
21095 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21096 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21097 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21098 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21101 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21102 ;; required and register dies. Similarly for 128 to -128.
21104 [(set (match_operand 0 "flags_reg_operand" "")
21105 (match_operator 1 "compare_operator"
21106 [(match_operand 2 "register_operand" "")
21107 (match_operand 3 "const_int_operand" "")]))]
21108 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21109 && incdec_operand (operands[3], GET_MODE (operands[3])))
21110 || (!TARGET_FUSE_CMP_AND_BRANCH
21111 && INTVAL (operands[3]) == 128))
21112 && ix86_match_ccmode (insn, CCGCmode)
21113 && peep2_reg_dead_p (1, operands[2])"
21114 [(parallel [(set (match_dup 0)
21115 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21116 (clobber (match_dup 2))])]
21120 [(match_scratch:DI 0 "r")
21121 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21122 (clobber (reg:CC FLAGS_REG))
21123 (clobber (mem:BLK (scratch)))])]
21124 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21125 [(clobber (match_dup 0))
21126 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21127 (clobber (mem:BLK (scratch)))])])
21130 [(match_scratch:DI 0 "r")
21131 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21132 (clobber (reg:CC FLAGS_REG))
21133 (clobber (mem:BLK (scratch)))])]
21134 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21135 [(clobber (match_dup 0))
21136 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21137 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21138 (clobber (mem:BLK (scratch)))])])
21140 ;; Convert esp subtractions to push.
21142 [(match_scratch:DI 0 "r")
21143 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21144 (clobber (reg:CC FLAGS_REG))])]
21145 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21146 [(clobber (match_dup 0))
21147 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21150 [(match_scratch:DI 0 "r")
21151 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21152 (clobber (reg:CC FLAGS_REG))])]
21153 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21154 [(clobber (match_dup 0))
21155 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21156 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21158 ;; Convert epilogue deallocator to pop.
21160 [(match_scratch:DI 0 "r")
21161 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21162 (clobber (reg:CC FLAGS_REG))
21163 (clobber (mem:BLK (scratch)))])]
21164 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21165 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21166 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21167 (clobber (mem:BLK (scratch)))])]
21170 ;; Two pops case is tricky, since pop causes dependency on destination register.
21171 ;; We use two registers if available.
21173 [(match_scratch:DI 0 "r")
21174 (match_scratch:DI 1 "r")
21175 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21176 (clobber (reg:CC FLAGS_REG))
21177 (clobber (mem:BLK (scratch)))])]
21178 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21179 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21180 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21181 (clobber (mem:BLK (scratch)))])
21182 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21183 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21187 [(match_scratch:DI 0 "r")
21188 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21189 (clobber (reg:CC FLAGS_REG))
21190 (clobber (mem:BLK (scratch)))])]
21191 "optimize_insn_for_size_p ()"
21192 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21193 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21194 (clobber (mem:BLK (scratch)))])
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)))])]
21199 ;; Convert esp additions to pop.
21201 [(match_scratch:DI 0 "r")
21202 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21203 (clobber (reg:CC FLAGS_REG))])]
21205 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21206 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21209 ;; Two pops case is tricky, since pop causes dependency on destination register.
21210 ;; We use two registers if available.
21212 [(match_scratch:DI 0 "r")
21213 (match_scratch:DI 1 "r")
21214 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21215 (clobber (reg:CC FLAGS_REG))])]
21217 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21218 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21219 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21220 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21224 [(match_scratch:DI 0 "r")
21225 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21226 (clobber (reg:CC FLAGS_REG))])]
21227 "optimize_insn_for_size_p ()"
21228 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21229 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21230 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21231 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21234 ;; Convert imul by three, five and nine into lea
21237 [(set (match_operand:SI 0 "register_operand" "")
21238 (mult:SI (match_operand:SI 1 "register_operand" "")
21239 (match_operand:SI 2 "const_int_operand" "")))
21240 (clobber (reg:CC FLAGS_REG))])]
21241 "INTVAL (operands[2]) == 3
21242 || INTVAL (operands[2]) == 5
21243 || INTVAL (operands[2]) == 9"
21244 [(set (match_dup 0)
21245 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21247 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21251 [(set (match_operand:SI 0 "register_operand" "")
21252 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21253 (match_operand:SI 2 "const_int_operand" "")))
21254 (clobber (reg:CC FLAGS_REG))])]
21255 "optimize_insn_for_speed_p ()
21256 && (INTVAL (operands[2]) == 3
21257 || INTVAL (operands[2]) == 5
21258 || INTVAL (operands[2]) == 9)"
21259 [(set (match_dup 0) (match_dup 1))
21261 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21263 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21267 [(set (match_operand:DI 0 "register_operand" "")
21268 (mult:DI (match_operand:DI 1 "register_operand" "")
21269 (match_operand:DI 2 "const_int_operand" "")))
21270 (clobber (reg:CC FLAGS_REG))])]
21272 && (INTVAL (operands[2]) == 3
21273 || INTVAL (operands[2]) == 5
21274 || INTVAL (operands[2]) == 9)"
21275 [(set (match_dup 0)
21276 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21278 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21282 [(set (match_operand:DI 0 "register_operand" "")
21283 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21284 (match_operand:DI 2 "const_int_operand" "")))
21285 (clobber (reg:CC FLAGS_REG))])]
21287 && optimize_insn_for_speed_p ()
21288 && (INTVAL (operands[2]) == 3
21289 || INTVAL (operands[2]) == 5
21290 || INTVAL (operands[2]) == 9)"
21291 [(set (match_dup 0) (match_dup 1))
21293 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21295 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21297 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21298 ;; imul $32bit_imm, reg, reg is direct decoded.
21300 [(match_scratch:DI 3 "r")
21301 (parallel [(set (match_operand:DI 0 "register_operand" "")
21302 (mult:DI (match_operand:DI 1 "memory_operand" "")
21303 (match_operand:DI 2 "immediate_operand" "")))
21304 (clobber (reg:CC FLAGS_REG))])]
21305 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21306 && !satisfies_constraint_K (operands[2])"
21307 [(set (match_dup 3) (match_dup 1))
21308 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21309 (clobber (reg:CC FLAGS_REG))])]
21313 [(match_scratch:SI 3 "r")
21314 (parallel [(set (match_operand:SI 0 "register_operand" "")
21315 (mult:SI (match_operand:SI 1 "memory_operand" "")
21316 (match_operand:SI 2 "immediate_operand" "")))
21317 (clobber (reg:CC FLAGS_REG))])]
21318 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21319 && !satisfies_constraint_K (operands[2])"
21320 [(set (match_dup 3) (match_dup 1))
21321 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21322 (clobber (reg:CC FLAGS_REG))])]
21326 [(match_scratch:SI 3 "r")
21327 (parallel [(set (match_operand:DI 0 "register_operand" "")
21329 (mult:SI (match_operand:SI 1 "memory_operand" "")
21330 (match_operand:SI 2 "immediate_operand" ""))))
21331 (clobber (reg:CC FLAGS_REG))])]
21332 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21333 && !satisfies_constraint_K (operands[2])"
21334 [(set (match_dup 3) (match_dup 1))
21335 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21336 (clobber (reg:CC FLAGS_REG))])]
21339 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21340 ;; Convert it into imul reg, reg
21341 ;; It would be better to force assembler to encode instruction using long
21342 ;; immediate, but there is apparently no way to do so.
21344 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21345 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21346 (match_operand:DI 2 "const_int_operand" "")))
21347 (clobber (reg:CC FLAGS_REG))])
21348 (match_scratch:DI 3 "r")]
21349 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21350 && satisfies_constraint_K (operands[2])"
21351 [(set (match_dup 3) (match_dup 2))
21352 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21353 (clobber (reg:CC FLAGS_REG))])]
21355 if (!rtx_equal_p (operands[0], operands[1]))
21356 emit_move_insn (operands[0], operands[1]);
21360 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21361 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21362 (match_operand:SI 2 "const_int_operand" "")))
21363 (clobber (reg:CC FLAGS_REG))])
21364 (match_scratch:SI 3 "r")]
21365 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21366 && satisfies_constraint_K (operands[2])"
21367 [(set (match_dup 3) (match_dup 2))
21368 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21369 (clobber (reg:CC FLAGS_REG))])]
21371 if (!rtx_equal_p (operands[0], operands[1]))
21372 emit_move_insn (operands[0], operands[1]);
21376 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21377 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21378 (match_operand:HI 2 "immediate_operand" "")))
21379 (clobber (reg:CC FLAGS_REG))])
21380 (match_scratch:HI 3 "r")]
21381 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21382 [(set (match_dup 3) (match_dup 2))
21383 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21384 (clobber (reg:CC FLAGS_REG))])]
21386 if (!rtx_equal_p (operands[0], operands[1]))
21387 emit_move_insn (operands[0], operands[1]);
21390 ;; After splitting up read-modify operations, array accesses with memory
21391 ;; operands might end up in form:
21393 ;; movl 4(%esp), %edx
21395 ;; instead of pre-splitting:
21397 ;; addl 4(%esp), %eax
21399 ;; movl 4(%esp), %edx
21400 ;; leal (%edx,%eax,4), %eax
21403 [(parallel [(set (match_operand 0 "register_operand" "")
21404 (ashift (match_operand 1 "register_operand" "")
21405 (match_operand 2 "const_int_operand" "")))
21406 (clobber (reg:CC FLAGS_REG))])
21407 (set (match_operand 3 "register_operand")
21408 (match_operand 4 "x86_64_general_operand" ""))
21409 (parallel [(set (match_operand 5 "register_operand" "")
21410 (plus (match_operand 6 "register_operand" "")
21411 (match_operand 7 "register_operand" "")))
21412 (clobber (reg:CC FLAGS_REG))])]
21413 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21414 /* Validate MODE for lea. */
21415 && ((!TARGET_PARTIAL_REG_STALL
21416 && (GET_MODE (operands[0]) == QImode
21417 || GET_MODE (operands[0]) == HImode))
21418 || GET_MODE (operands[0]) == SImode
21419 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21420 /* We reorder load and the shift. */
21421 && !rtx_equal_p (operands[1], operands[3])
21422 && !reg_overlap_mentioned_p (operands[0], operands[4])
21423 /* Last PLUS must consist of operand 0 and 3. */
21424 && !rtx_equal_p (operands[0], operands[3])
21425 && (rtx_equal_p (operands[3], operands[6])
21426 || rtx_equal_p (operands[3], operands[7]))
21427 && (rtx_equal_p (operands[0], operands[6])
21428 || rtx_equal_p (operands[0], operands[7]))
21429 /* The intermediate operand 0 must die or be same as output. */
21430 && (rtx_equal_p (operands[0], operands[5])
21431 || peep2_reg_dead_p (3, operands[0]))"
21432 [(set (match_dup 3) (match_dup 4))
21433 (set (match_dup 0) (match_dup 1))]
21435 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21436 int scale = 1 << INTVAL (operands[2]);
21437 rtx index = gen_lowpart (Pmode, operands[1]);
21438 rtx base = gen_lowpart (Pmode, operands[3]);
21439 rtx dest = gen_lowpart (mode, operands[5]);
21441 operands[1] = gen_rtx_PLUS (Pmode, base,
21442 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21444 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21445 operands[0] = dest;
21448 ;; Call-value patterns last so that the wildcard operand does not
21449 ;; disrupt insn-recog's switch tables.
21451 (define_insn "*call_value_pop_0"
21452 [(set (match_operand 0 "" "")
21453 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21454 (match_operand:SI 2 "" "")))
21455 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21456 (match_operand:SI 3 "immediate_operand" "")))]
21459 if (SIBLING_CALL_P (insn))
21462 return "call\t%P1";
21464 [(set_attr "type" "callv")])
21466 (define_insn "*call_value_pop_1"
21467 [(set (match_operand 0 "" "")
21468 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21469 (match_operand:SI 2 "" "")))
21470 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21471 (match_operand:SI 3 "immediate_operand" "i")))]
21474 if (constant_call_address_operand (operands[1], Pmode))
21476 if (SIBLING_CALL_P (insn))
21479 return "call\t%P1";
21481 if (SIBLING_CALL_P (insn))
21484 return "call\t%A1";
21486 [(set_attr "type" "callv")])
21488 (define_insn "*call_value_0"
21489 [(set (match_operand 0 "" "")
21490 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21491 (match_operand:SI 2 "" "")))]
21494 if (SIBLING_CALL_P (insn))
21497 return "call\t%P1";
21499 [(set_attr "type" "callv")])
21501 (define_insn "*call_value_0_rex64"
21502 [(set (match_operand 0 "" "")
21503 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21504 (match_operand:DI 2 "const_int_operand" "")))]
21507 if (SIBLING_CALL_P (insn))
21510 return "call\t%P1";
21512 [(set_attr "type" "callv")])
21514 (define_insn "*call_value_0_rex64_ms_sysv"
21515 [(set (match_operand 0 "" "")
21516 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21517 (match_operand:DI 2 "const_int_operand" "")))
21518 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21519 (clobber (reg:TI XMM6_REG))
21520 (clobber (reg:TI XMM7_REG))
21521 (clobber (reg:TI XMM8_REG))
21522 (clobber (reg:TI XMM9_REG))
21523 (clobber (reg:TI XMM10_REG))
21524 (clobber (reg:TI XMM11_REG))
21525 (clobber (reg:TI XMM12_REG))
21526 (clobber (reg:TI XMM13_REG))
21527 (clobber (reg:TI XMM14_REG))
21528 (clobber (reg:TI XMM15_REG))
21529 (clobber (reg:DI SI_REG))
21530 (clobber (reg:DI DI_REG))]
21531 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21533 if (SIBLING_CALL_P (insn))
21536 return "call\t%P1";
21538 [(set_attr "type" "callv")])
21540 (define_insn "*call_value_1"
21541 [(set (match_operand 0 "" "")
21542 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21543 (match_operand:SI 2 "" "")))]
21544 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21546 if (constant_call_address_operand (operands[1], Pmode))
21547 return "call\t%P1";
21548 return "call\t%A1";
21550 [(set_attr "type" "callv")])
21552 (define_insn "*sibcall_value_1"
21553 [(set (match_operand 0 "" "")
21554 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21555 (match_operand:SI 2 "" "")))]
21556 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21560 [(set_attr "type" "callv")])
21562 (define_insn "*call_value_1_rex64"
21563 [(set (match_operand 0 "" "")
21564 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21565 (match_operand:DI 2 "" "")))]
21566 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21567 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21569 if (constant_call_address_operand (operands[1], Pmode))
21570 return "call\t%P1";
21571 return "call\t%A1";
21573 [(set_attr "type" "callv")])
21575 (define_insn "*call_value_1_rex64_ms_sysv"
21576 [(set (match_operand 0 "" "")
21577 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21578 (match_operand:DI 2 "" "")))
21579 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21580 (clobber (reg:TI 27))
21581 (clobber (reg:TI 28))
21582 (clobber (reg:TI 45))
21583 (clobber (reg:TI 46))
21584 (clobber (reg:TI 47))
21585 (clobber (reg:TI 48))
21586 (clobber (reg:TI 49))
21587 (clobber (reg:TI 50))
21588 (clobber (reg:TI 51))
21589 (clobber (reg:TI 52))
21590 (clobber (reg:DI SI_REG))
21591 (clobber (reg:DI DI_REG))]
21592 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21594 if (constant_call_address_operand (operands[1], Pmode))
21595 return "call\t%P1";
21596 return "call\t%A1";
21598 [(set_attr "type" "callv")])
21600 (define_insn "*call_value_1_rex64_large"
21601 [(set (match_operand 0 "" "")
21602 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21603 (match_operand:DI 2 "" "")))]
21604 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21606 [(set_attr "type" "callv")])
21608 (define_insn "*sibcall_value_1_rex64"
21609 [(set (match_operand 0 "" "")
21610 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21611 (match_operand:DI 2 "" "")))]
21612 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21616 [(set_attr "type" "callv")])
21618 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21619 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21620 ;; caught for use by garbage collectors and the like. Using an insn that
21621 ;; maps to SIGILL makes it more likely the program will rightfully die.
21622 ;; Keeping with tradition, "6" is in honor of #UD.
21623 (define_insn "trap"
21624 [(trap_if (const_int 1) (const_int 6))]
21626 { return ASM_SHORT "0x0b0f"; }
21627 [(set_attr "length" "2")])
21629 (define_expand "sse_prologue_save"
21630 [(parallel [(set (match_operand:BLK 0 "" "")
21631 (unspec:BLK [(reg:DI 21)
21638 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21639 (use (match_operand:DI 1 "register_operand" ""))
21640 (use (match_operand:DI 2 "immediate_operand" ""))
21641 (use (label_ref:DI (match_operand 3 "" "")))])]
21645 (define_insn "*sse_prologue_save_insn"
21646 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21647 (match_operand:DI 4 "const_int_operand" "n")))
21648 (unspec:BLK [(reg:DI 21)
21655 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21656 (use (match_operand:DI 1 "register_operand" "r"))
21657 (use (match_operand:DI 2 "const_int_operand" "i"))
21658 (use (label_ref:DI (match_operand 3 "" "X")))]
21660 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21661 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21664 operands[0] = gen_rtx_MEM (Pmode,
21665 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21666 /* VEX instruction with a REX prefix will #UD. */
21667 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21668 gcc_unreachable ();
21670 output_asm_insn ("jmp\t%A1", operands);
21671 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21673 operands[4] = adjust_address (operands[0], DImode, i*16);
21674 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21675 PUT_MODE (operands[4], TImode);
21676 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21677 output_asm_insn ("rex", operands);
21678 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21680 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21681 CODE_LABEL_NUMBER (operands[3]));
21684 [(set_attr "type" "other")
21685 (set_attr "length_immediate" "0")
21686 (set_attr "length_address" "0")
21687 (set (attr "length")
21689 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21690 (const_string "34")
21691 (const_string "42")))
21692 (set_attr "memory" "store")
21693 (set_attr "modrm" "0")
21694 (set_attr "prefix" "maybe_vex")
21695 (set_attr "mode" "DI")])
21697 (define_expand "prefetch"
21698 [(prefetch (match_operand 0 "address_operand" "")
21699 (match_operand:SI 1 "const_int_operand" "")
21700 (match_operand:SI 2 "const_int_operand" ""))]
21701 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21703 int rw = INTVAL (operands[1]);
21704 int locality = INTVAL (operands[2]);
21706 gcc_assert (rw == 0 || rw == 1);
21707 gcc_assert (locality >= 0 && locality <= 3);
21708 gcc_assert (GET_MODE (operands[0]) == Pmode
21709 || GET_MODE (operands[0]) == VOIDmode);
21711 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21712 supported by SSE counterpart or the SSE prefetch is not available
21713 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21715 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21716 operands[2] = GEN_INT (3);
21718 operands[1] = const0_rtx;
21721 (define_insn "*prefetch_sse"
21722 [(prefetch (match_operand:SI 0 "address_operand" "p")
21724 (match_operand:SI 1 "const_int_operand" ""))]
21725 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21727 static const char * const patterns[4] = {
21728 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21731 int locality = INTVAL (operands[1]);
21732 gcc_assert (locality >= 0 && locality <= 3);
21734 return patterns[locality];
21736 [(set_attr "type" "sse")
21737 (set_attr "memory" "none")])
21739 (define_insn "*prefetch_sse_rex"
21740 [(prefetch (match_operand:DI 0 "address_operand" "p")
21742 (match_operand:SI 1 "const_int_operand" ""))]
21743 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21745 static const char * const patterns[4] = {
21746 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21749 int locality = INTVAL (operands[1]);
21750 gcc_assert (locality >= 0 && locality <= 3);
21752 return patterns[locality];
21754 [(set_attr "type" "sse")
21755 (set_attr "memory" "none")])
21757 (define_insn "*prefetch_3dnow"
21758 [(prefetch (match_operand:SI 0 "address_operand" "p")
21759 (match_operand:SI 1 "const_int_operand" "n")
21761 "TARGET_3DNOW && !TARGET_64BIT"
21763 if (INTVAL (operands[1]) == 0)
21764 return "prefetch\t%a0";
21766 return "prefetchw\t%a0";
21768 [(set_attr "type" "mmx")
21769 (set_attr "memory" "none")])
21771 (define_insn "*prefetch_3dnow_rex"
21772 [(prefetch (match_operand:DI 0 "address_operand" "p")
21773 (match_operand:SI 1 "const_int_operand" "n")
21775 "TARGET_3DNOW && TARGET_64BIT"
21777 if (INTVAL (operands[1]) == 0)
21778 return "prefetch\t%a0";
21780 return "prefetchw\t%a0";
21782 [(set_attr "type" "mmx")
21783 (set_attr "memory" "none")])
21785 (define_expand "stack_protect_set"
21786 [(match_operand 0 "memory_operand" "")
21787 (match_operand 1 "memory_operand" "")]
21790 #ifdef TARGET_THREAD_SSP_OFFSET
21792 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21793 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21795 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21796 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21799 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21801 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21806 (define_insn "stack_protect_set_si"
21807 [(set (match_operand:SI 0 "memory_operand" "=m")
21808 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21809 (set (match_scratch:SI 2 "=&r") (const_int 0))
21810 (clobber (reg:CC FLAGS_REG))]
21812 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21813 [(set_attr "type" "multi")])
21815 (define_insn "stack_protect_set_di"
21816 [(set (match_operand:DI 0 "memory_operand" "=m")
21817 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21818 (set (match_scratch:DI 2 "=&r") (const_int 0))
21819 (clobber (reg:CC FLAGS_REG))]
21821 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21822 [(set_attr "type" "multi")])
21824 (define_insn "stack_tls_protect_set_si"
21825 [(set (match_operand:SI 0 "memory_operand" "=m")
21826 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21827 (set (match_scratch:SI 2 "=&r") (const_int 0))
21828 (clobber (reg:CC FLAGS_REG))]
21830 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21831 [(set_attr "type" "multi")])
21833 (define_insn "stack_tls_protect_set_di"
21834 [(set (match_operand:DI 0 "memory_operand" "=m")
21835 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21836 (set (match_scratch:DI 2 "=&r") (const_int 0))
21837 (clobber (reg:CC FLAGS_REG))]
21840 /* The kernel uses a different segment register for performance reasons; a
21841 system call would not have to trash the userspace segment register,
21842 which would be expensive */
21843 if (ix86_cmodel != CM_KERNEL)
21844 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21846 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21848 [(set_attr "type" "multi")])
21850 (define_expand "stack_protect_test"
21851 [(match_operand 0 "memory_operand" "")
21852 (match_operand 1 "memory_operand" "")
21853 (match_operand 2 "" "")]
21856 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21857 ix86_compare_op0 = operands[0];
21858 ix86_compare_op1 = operands[1];
21859 ix86_compare_emitted = flags;
21861 #ifdef TARGET_THREAD_SSP_OFFSET
21863 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21864 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21866 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21867 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21870 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21872 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21874 emit_jump_insn (gen_beq (operands[2]));
21878 (define_insn "stack_protect_test_si"
21879 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21880 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21881 (match_operand:SI 2 "memory_operand" "m")]
21883 (clobber (match_scratch:SI 3 "=&r"))]
21885 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21886 [(set_attr "type" "multi")])
21888 (define_insn "stack_protect_test_di"
21889 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21890 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21891 (match_operand:DI 2 "memory_operand" "m")]
21893 (clobber (match_scratch:DI 3 "=&r"))]
21895 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21896 [(set_attr "type" "multi")])
21898 (define_insn "stack_tls_protect_test_si"
21899 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21900 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21901 (match_operand:SI 2 "const_int_operand" "i")]
21902 UNSPEC_SP_TLS_TEST))
21903 (clobber (match_scratch:SI 3 "=r"))]
21905 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21906 [(set_attr "type" "multi")])
21908 (define_insn "stack_tls_protect_test_di"
21909 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21910 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21911 (match_operand:DI 2 "const_int_operand" "i")]
21912 UNSPEC_SP_TLS_TEST))
21913 (clobber (match_scratch:DI 3 "=r"))]
21916 /* The kernel uses a different segment register for performance reasons; a
21917 system call would not have to trash the userspace segment register,
21918 which would be expensive */
21919 if (ix86_cmodel != CM_KERNEL)
21920 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21922 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21924 [(set_attr "type" "multi")])
21926 (define_mode_iterator CRC32MODE [QI HI SI])
21927 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21928 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21930 (define_insn "sse4_2_crc32<mode>"
21931 [(set (match_operand:SI 0 "register_operand" "=r")
21933 [(match_operand:SI 1 "register_operand" "0")
21934 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21937 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21938 [(set_attr "type" "sselog1")
21939 (set_attr "prefix_rep" "1")
21940 (set_attr "prefix_extra" "1")
21941 (set_attr "mode" "SI")])
21943 (define_insn "sse4_2_crc32di"
21944 [(set (match_operand:DI 0 "register_operand" "=r")
21946 [(match_operand:DI 1 "register_operand" "0")
21947 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21949 "TARGET_SSE4_2 && TARGET_64BIT"
21950 "crc32q\t{%2, %0|%0, %2}"
21951 [(set_attr "type" "sselog1")
21952 (set_attr "prefix_rep" "1")
21953 (set_attr "prefix_extra" "1")
21954 (set_attr "mode" "DI")])
21958 (include "sync.md")