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)
153 (UNSPEC_SP_TLS_SET 102)
154 (UNSPEC_SP_TLS_TEST 103)
164 (UNSPEC_INSERTQI 132)
169 (UNSPEC_INSERTPS 135)
171 (UNSPEC_MOVNTDQA 137)
173 (UNSPEC_PHMINPOSUW 139)
179 (UNSPEC_PCMPESTR 144)
180 (UNSPEC_PCMPISTR 145)
183 (UNSPEC_SSE5_INTRINSIC 150)
184 (UNSPEC_SSE5_UNSIGNED_CMP 151)
185 (UNSPEC_SSE5_TRUEFALSE 152)
186 (UNSPEC_SSE5_PERMUTE 153)
188 (UNSPEC_CVTPH2PS 155)
189 (UNSPEC_CVTPS2PH 156)
193 (UNSPEC_AESENCLAST 160)
195 (UNSPEC_AESDECLAST 162)
197 (UNSPEC_AESKEYGENASSIST 164)
205 (UNSPEC_VPERMIL2F128 168)
206 (UNSPEC_MASKLOAD 169)
207 (UNSPEC_MASKSTORE 170)
213 [(UNSPECV_BLOCKAGE 0)
214 (UNSPECV_STACK_PROBE 1)
226 (UNSPECV_PROLOGUE_USE 14)
228 (UNSPECV_VZEROALL 16)
229 (UNSPECV_VZEROUPPER 17)
232 ;; Constants to represent pcomtrue/pcomfalse variants
242 ;; Constants used in the SSE5 pperm instruction
244 [(PPERM_SRC 0x00) /* copy source */
245 (PPERM_INVERT 0x20) /* invert source */
246 (PPERM_REVERSE 0x40) /* bit reverse source */
247 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
248 (PPERM_ZERO 0x80) /* all 0's */
249 (PPERM_ONES 0xa0) /* all 1's */
250 (PPERM_SIGN 0xc0) /* propagate sign bit */
251 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
252 (PPERM_SRC1 0x00) /* use first source byte */
253 (PPERM_SRC2 0x10) /* use second source byte */
256 ;; Registers by name.
290 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293 ;; In C guard expressions, put expressions which may be compile-time
294 ;; constants first. This allows for better optimization. For
295 ;; example, write "TARGET_64BIT && reload_completed", not
296 ;; "reload_completed && TARGET_64BIT".
300 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
302 (const (symbol_ref "ix86_schedule")))
304 ;; A basic instruction type. Refinements due to arguments to be
305 ;; provided in other attributes.
308 alu,alu1,negnot,imov,imovx,lea,
309 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
310 icmp,test,ibr,setcc,icmov,
311 push,pop,call,callv,leave,
313 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
314 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
315 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
317 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
318 (const_string "other"))
320 ;; Main data type used by the insn
322 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
323 (const_string "unknown"))
325 ;; The CPU unit operations uses.
326 (define_attr "unit" "integer,i387,sse,mmx,unknown"
327 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
328 (const_string "i387")
329 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
330 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
331 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
333 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
335 (eq_attr "type" "other")
336 (const_string "unknown")]
337 (const_string "integer")))
339 ;; The (bounding maximum) length of an instruction immediate.
340 (define_attr "length_immediate" ""
341 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344 (eq_attr "unit" "i387,sse,mmx")
346 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
348 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
349 (eq_attr "type" "imov,test")
350 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
351 (eq_attr "type" "call")
352 (if_then_else (match_operand 0 "constant_call_address_operand" "")
355 (eq_attr "type" "callv")
356 (if_then_else (match_operand 1 "constant_call_address_operand" "")
359 ;; We don't know the size before shorten_branches. Expect
360 ;; the instruction to fit for better scheduling.
361 (eq_attr "type" "ibr")
364 (symbol_ref "/* Update immediate_length and other attributes! */
365 gcc_unreachable (),1")))
367 ;; The (bounding maximum) length of an instruction address.
368 (define_attr "length_address" ""
369 (cond [(eq_attr "type" "str,other,multi,fxch")
371 (and (eq_attr "type" "call")
372 (match_operand 0 "constant_call_address_operand" ""))
374 (and (eq_attr "type" "callv")
375 (match_operand 1 "constant_call_address_operand" ""))
378 (symbol_ref "ix86_attr_length_address_default (insn)")))
380 ;; Set when length prefix is used.
381 (define_attr "prefix_data16" ""
382 (if_then_else (ior (eq_attr "mode" "HI")
383 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
387 ;; Set when string REP prefix is used.
388 (define_attr "prefix_rep" ""
389 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
393 ;; Set when 0f opcode prefix is used.
394 (define_attr "prefix_0f" ""
396 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
397 (eq_attr "unit" "sse,mmx"))
401 ;; Set when REX opcode prefix is used.
402 (define_attr "prefix_rex" ""
403 (cond [(and (eq_attr "mode" "DI")
404 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
406 (and (eq_attr "mode" "QI")
407 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
410 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
416 ;; There are also additional prefixes in SSSE3.
417 (define_attr "prefix_extra" "" (const_int 0))
419 ;; Prefix used: original, VEX or maybe VEX.
420 (define_attr "prefix" "orig,vex,maybe_vex"
421 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
423 (const_string "orig")))
425 ;; There is a 8bit immediate for VEX.
426 (define_attr "prefix_vex_imm8" "" (const_int 0))
428 ;; VEX W bit is used.
429 (define_attr "prefix_vex_w" "" (const_int 0))
431 ;; The length of VEX prefix
432 (define_attr "length_vex" ""
433 (if_then_else (eq_attr "prefix_0f" "1")
434 (if_then_else (eq_attr "prefix_vex_w" "1")
435 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
436 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
437 (if_then_else (eq_attr "prefix_vex_w" "1")
438 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
439 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
441 ;; Set when modrm byte is used.
442 (define_attr "modrm" ""
443 (cond [(eq_attr "type" "str,leave")
445 (eq_attr "unit" "i387")
447 (and (eq_attr "type" "incdec")
448 (ior (match_operand:SI 1 "register_operand" "")
449 (match_operand:HI 1 "register_operand" "")))
451 (and (eq_attr "type" "push")
452 (not (match_operand 1 "memory_operand" "")))
454 (and (eq_attr "type" "pop")
455 (not (match_operand 0 "memory_operand" "")))
457 (and (eq_attr "type" "imov")
458 (ior (and (match_operand 0 "register_operand" "")
459 (match_operand 1 "immediate_operand" ""))
460 (ior (and (match_operand 0 "ax_reg_operand" "")
461 (match_operand 1 "memory_displacement_only_operand" ""))
462 (and (match_operand 0 "memory_displacement_only_operand" "")
463 (match_operand 1 "ax_reg_operand" "")))))
465 (and (eq_attr "type" "call")
466 (match_operand 0 "constant_call_address_operand" ""))
468 (and (eq_attr "type" "callv")
469 (match_operand 1 "constant_call_address_operand" ""))
474 ;; The (bounding maximum) length of an instruction in bytes.
475 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
476 ;; Later we may want to split them and compute proper length as for
478 (define_attr "length" ""
479 (cond [(eq_attr "type" "other,multi,fistp,frndint")
481 (eq_attr "type" "fcmp")
483 (eq_attr "unit" "i387")
485 (plus (attr "prefix_data16")
486 (attr "length_address")))
487 (ior (eq_attr "prefix" "vex")
488 (and (eq_attr "prefix" "maybe_vex")
489 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
490 (plus (attr "length_vex")
491 (plus (attr "prefix_vex_imm8")
493 (attr "length_address"))))]
494 (plus (plus (attr "modrm")
495 (plus (attr "prefix_0f")
496 (plus (attr "prefix_rex")
497 (plus (attr "prefix_extra")
499 (plus (attr "prefix_rep")
500 (plus (attr "prefix_data16")
501 (plus (attr "length_immediate")
502 (attr "length_address")))))))
504 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
505 ;; `store' if there is a simple memory reference therein, or `unknown'
506 ;; if the instruction is complex.
508 (define_attr "memory" "none,load,store,both,unknown"
509 (cond [(eq_attr "type" "other,multi,str")
510 (const_string "unknown")
511 (eq_attr "type" "lea,fcmov,fpspc")
512 (const_string "none")
513 (eq_attr "type" "fistp,leave")
514 (const_string "both")
515 (eq_attr "type" "frndint")
516 (const_string "load")
517 (eq_attr "type" "push")
518 (if_then_else (match_operand 1 "memory_operand" "")
519 (const_string "both")
520 (const_string "store"))
521 (eq_attr "type" "pop")
522 (if_then_else (match_operand 0 "memory_operand" "")
523 (const_string "both")
524 (const_string "load"))
525 (eq_attr "type" "setcc")
526 (if_then_else (match_operand 0 "memory_operand" "")
527 (const_string "store")
528 (const_string "none"))
529 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
530 (if_then_else (ior (match_operand 0 "memory_operand" "")
531 (match_operand 1 "memory_operand" ""))
532 (const_string "load")
533 (const_string "none"))
534 (eq_attr "type" "ibr")
535 (if_then_else (match_operand 0 "memory_operand" "")
536 (const_string "load")
537 (const_string "none"))
538 (eq_attr "type" "call")
539 (if_then_else (match_operand 0 "constant_call_address_operand" "")
540 (const_string "none")
541 (const_string "load"))
542 (eq_attr "type" "callv")
543 (if_then_else (match_operand 1 "constant_call_address_operand" "")
544 (const_string "none")
545 (const_string "load"))
546 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
547 (match_operand 1 "memory_operand" ""))
548 (const_string "both")
549 (and (match_operand 0 "memory_operand" "")
550 (match_operand 1 "memory_operand" ""))
551 (const_string "both")
552 (match_operand 0 "memory_operand" "")
553 (const_string "store")
554 (match_operand 1 "memory_operand" "")
555 (const_string "load")
557 "!alu1,negnot,ishift1,
558 imov,imovx,icmp,test,bitmanip,
560 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
561 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
562 (match_operand 2 "memory_operand" ""))
563 (const_string "load")
564 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
565 (match_operand 3 "memory_operand" ""))
566 (const_string "load")
568 (const_string "none")))
570 ;; Indicates if an instruction has both an immediate and a displacement.
572 (define_attr "imm_disp" "false,true,unknown"
573 (cond [(eq_attr "type" "other,multi")
574 (const_string "unknown")
575 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
576 (and (match_operand 0 "memory_displacement_operand" "")
577 (match_operand 1 "immediate_operand" "")))
578 (const_string "true")
579 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
580 (and (match_operand 0 "memory_displacement_operand" "")
581 (match_operand 2 "immediate_operand" "")))
582 (const_string "true")
584 (const_string "false")))
586 ;; Indicates if an FP operation has an integer source.
588 (define_attr "fp_int_src" "false,true"
589 (const_string "false"))
591 ;; Defines rounding mode of an FP operation.
593 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
594 (const_string "any"))
596 ;; Describe a user's asm statement.
597 (define_asm_attributes
598 [(set_attr "length" "128")
599 (set_attr "type" "multi")])
601 ;; All integer comparison codes.
602 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
604 ;; All floating-point comparison codes.
605 (define_code_iterator fp_cond [unordered ordered
606 uneq unge ungt unle unlt ltgt ])
608 (define_code_iterator plusminus [plus minus])
610 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
612 ;; Base name for define_insn
613 (define_code_attr plusminus_insn
614 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
615 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
617 ;; Base name for insn mnemonic.
618 (define_code_attr plusminus_mnemonic
619 [(plus "add") (ss_plus "adds") (us_plus "addus")
620 (minus "sub") (ss_minus "subs") (us_minus "subus")])
622 ;; Mark commutative operators as such in constraints.
623 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
624 (minus "") (ss_minus "") (us_minus "")])
626 ;; Mapping of signed max and min
627 (define_code_iterator smaxmin [smax smin])
629 ;; Mapping of unsigned max and min
630 (define_code_iterator umaxmin [umax umin])
632 ;; Mapping of signed/unsigned max and min
633 (define_code_iterator maxmin [smax smin umax umin])
635 ;; Base name for integer and FP insn mnemonic
636 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
637 (umax "maxu") (umin "minu")])
638 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
640 ;; Mapping of parallel logic operators
641 (define_code_iterator plogic [and ior xor])
643 ;; Base name for insn mnemonic.
644 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
646 ;; Mapping of abs neg operators
647 (define_code_iterator absneg [abs neg])
649 ;; Base name for x87 insn mnemonic.
650 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
652 ;; All single word integer modes.
653 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
655 ;; Single word integer modes without QImode.
656 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
658 ;; Instruction suffix for integer modes.
659 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
661 ;; Register class for integer modes.
662 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
664 ;; Immediate operand constraint for integer modes.
665 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
667 ;; General operand predicate for integer modes.
668 (define_mode_attr general_operand
669 [(QI "general_operand")
670 (HI "general_operand")
671 (SI "general_operand")
672 (DI "x86_64_general_operand")])
674 ;; SSE and x87 SFmode and DFmode floating point modes
675 (define_mode_iterator MODEF [SF DF])
677 ;; All x87 floating point modes
678 (define_mode_iterator X87MODEF [SF DF XF])
680 ;; All integer modes handled by x87 fisttp operator.
681 (define_mode_iterator X87MODEI [HI SI DI])
683 ;; All integer modes handled by integer x87 operators.
684 (define_mode_iterator X87MODEI12 [HI SI])
686 ;; All integer modes handled by SSE cvtts?2si* operators.
687 (define_mode_iterator SSEMODEI24 [SI DI])
689 ;; SSE asm suffix for floating point modes
690 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
692 ;; SSE vector mode corresponding to a scalar mode
693 (define_mode_attr ssevecmode
694 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
696 ;; Instruction suffix for REX 64bit operators.
697 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
699 ;; This mode iterator allows :P to be used for patterns that operate on
700 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
701 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
704 ;; Scheduling descriptions
706 (include "pentium.md")
709 (include "athlon.md")
713 ;; Operand and operator predicates and constraints
715 (include "predicates.md")
716 (include "constraints.md")
719 ;; Compare instructions.
721 ;; All compare insns have expanders that save the operands away without
722 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
723 ;; after the cmp) will actually emit the cmpM.
725 (define_expand "cmpti"
726 [(set (reg:CC FLAGS_REG)
727 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
728 (match_operand:TI 1 "x86_64_general_operand" "")))]
731 if (MEM_P (operands[0]) && MEM_P (operands[1]))
732 operands[0] = force_reg (TImode, operands[0]);
733 ix86_compare_op0 = operands[0];
734 ix86_compare_op1 = operands[1];
738 (define_expand "cmpdi"
739 [(set (reg:CC FLAGS_REG)
740 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
741 (match_operand:DI 1 "x86_64_general_operand" "")))]
744 if (MEM_P (operands[0]) && MEM_P (operands[1]))
745 operands[0] = force_reg (DImode, operands[0]);
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
751 (define_expand "cmpsi"
752 [(set (reg:CC FLAGS_REG)
753 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
754 (match_operand:SI 1 "general_operand" "")))]
757 if (MEM_P (operands[0]) && MEM_P (operands[1]))
758 operands[0] = force_reg (SImode, operands[0]);
759 ix86_compare_op0 = operands[0];
760 ix86_compare_op1 = operands[1];
764 (define_expand "cmphi"
765 [(set (reg:CC FLAGS_REG)
766 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
767 (match_operand:HI 1 "general_operand" "")))]
770 if (MEM_P (operands[0]) && MEM_P (operands[1]))
771 operands[0] = force_reg (HImode, operands[0]);
772 ix86_compare_op0 = operands[0];
773 ix86_compare_op1 = operands[1];
777 (define_expand "cmpqi"
778 [(set (reg:CC FLAGS_REG)
779 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
780 (match_operand:QI 1 "general_operand" "")))]
783 if (MEM_P (operands[0]) && MEM_P (operands[1]))
784 operands[0] = force_reg (QImode, operands[0]);
785 ix86_compare_op0 = operands[0];
786 ix86_compare_op1 = operands[1];
790 (define_insn "cmpdi_ccno_1_rex64"
791 [(set (reg FLAGS_REG)
792 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
793 (match_operand:DI 1 "const0_operand" "")))]
794 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
797 cmp{q}\t{%1, %0|%0, %1}"
798 [(set_attr "type" "test,icmp")
799 (set_attr "length_immediate" "0,1")
800 (set_attr "mode" "DI")])
802 (define_insn "*cmpdi_minus_1_rex64"
803 [(set (reg FLAGS_REG)
804 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
805 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
807 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
808 "cmp{q}\t{%1, %0|%0, %1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "DI")])
812 (define_expand "cmpdi_1_rex64"
813 [(set (reg:CC FLAGS_REG)
814 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
815 (match_operand:DI 1 "general_operand" "")))]
819 (define_insn "cmpdi_1_insn_rex64"
820 [(set (reg FLAGS_REG)
821 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
822 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
823 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824 "cmp{q}\t{%1, %0|%0, %1}"
825 [(set_attr "type" "icmp")
826 (set_attr "mode" "DI")])
829 (define_insn "*cmpsi_ccno_1"
830 [(set (reg FLAGS_REG)
831 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
832 (match_operand:SI 1 "const0_operand" "")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
836 cmp{l}\t{%1, %0|%0, %1}"
837 [(set_attr "type" "test,icmp")
838 (set_attr "length_immediate" "0,1")
839 (set_attr "mode" "SI")])
841 (define_insn "*cmpsi_minus_1"
842 [(set (reg FLAGS_REG)
843 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
844 (match_operand:SI 1 "general_operand" "ri,mr"))
846 "ix86_match_ccmode (insn, CCGOCmode)"
847 "cmp{l}\t{%1, %0|%0, %1}"
848 [(set_attr "type" "icmp")
849 (set_attr "mode" "SI")])
851 (define_expand "cmpsi_1"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
854 (match_operand:SI 1 "general_operand" "")))]
858 (define_insn "*cmpsi_1_insn"
859 [(set (reg FLAGS_REG)
860 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
861 (match_operand:SI 1 "general_operand" "ri,mr")))]
862 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
863 && ix86_match_ccmode (insn, CCmode)"
864 "cmp{l}\t{%1, %0|%0, %1}"
865 [(set_attr "type" "icmp")
866 (set_attr "mode" "SI")])
868 (define_insn "*cmphi_ccno_1"
869 [(set (reg FLAGS_REG)
870 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
871 (match_operand:HI 1 "const0_operand" "")))]
872 "ix86_match_ccmode (insn, CCNOmode)"
875 cmp{w}\t{%1, %0|%0, %1}"
876 [(set_attr "type" "test,icmp")
877 (set_attr "length_immediate" "0,1")
878 (set_attr "mode" "HI")])
880 (define_insn "*cmphi_minus_1"
881 [(set (reg FLAGS_REG)
882 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
883 (match_operand:HI 1 "general_operand" "rn,mr"))
885 "ix86_match_ccmode (insn, CCGOCmode)"
886 "cmp{w}\t{%1, %0|%0, %1}"
887 [(set_attr "type" "icmp")
888 (set_attr "mode" "HI")])
890 (define_insn "*cmphi_1"
891 [(set (reg FLAGS_REG)
892 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
893 (match_operand:HI 1 "general_operand" "rn,mr")))]
894 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
895 && ix86_match_ccmode (insn, CCmode)"
896 "cmp{w}\t{%1, %0|%0, %1}"
897 [(set_attr "type" "icmp")
898 (set_attr "mode" "HI")])
900 (define_insn "*cmpqi_ccno_1"
901 [(set (reg FLAGS_REG)
902 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
903 (match_operand:QI 1 "const0_operand" "")))]
904 "ix86_match_ccmode (insn, CCNOmode)"
907 cmp{b}\t{$0, %0|%0, 0}"
908 [(set_attr "type" "test,icmp")
909 (set_attr "length_immediate" "0,1")
910 (set_attr "mode" "QI")])
912 (define_insn "*cmpqi_1"
913 [(set (reg FLAGS_REG)
914 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
915 (match_operand:QI 1 "general_operand" "qn,mq")))]
916 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
917 && ix86_match_ccmode (insn, CCmode)"
918 "cmp{b}\t{%1, %0|%0, %1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "QI")])
922 (define_insn "*cmpqi_minus_1"
923 [(set (reg FLAGS_REG)
924 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
925 (match_operand:QI 1 "general_operand" "qn,mq"))
927 "ix86_match_ccmode (insn, CCGOCmode)"
928 "cmp{b}\t{%1, %0|%0, %1}"
929 [(set_attr "type" "icmp")
930 (set_attr "mode" "QI")])
932 (define_insn "*cmpqi_ext_1"
933 [(set (reg FLAGS_REG)
935 (match_operand:QI 0 "general_operand" "Qm")
938 (match_operand 1 "ext_register_operand" "Q")
941 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
942 "cmp{b}\t{%h1, %0|%0, %h1}"
943 [(set_attr "type" "icmp")
944 (set_attr "mode" "QI")])
946 (define_insn "*cmpqi_ext_1_rex64"
947 [(set (reg FLAGS_REG)
949 (match_operand:QI 0 "register_operand" "Q")
952 (match_operand 1 "ext_register_operand" "Q")
955 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
956 "cmp{b}\t{%h1, %0|%0, %h1}"
957 [(set_attr "type" "icmp")
958 (set_attr "mode" "QI")])
960 (define_insn "*cmpqi_ext_2"
961 [(set (reg FLAGS_REG)
965 (match_operand 0 "ext_register_operand" "Q")
968 (match_operand:QI 1 "const0_operand" "")))]
969 "ix86_match_ccmode (insn, CCNOmode)"
971 [(set_attr "type" "test")
972 (set_attr "length_immediate" "0")
973 (set_attr "mode" "QI")])
975 (define_expand "cmpqi_ext_3"
976 [(set (reg:CC FLAGS_REG)
980 (match_operand 0 "ext_register_operand" "")
983 (match_operand:QI 1 "general_operand" "")))]
987 (define_insn "cmpqi_ext_3_insn"
988 [(set (reg FLAGS_REG)
992 (match_operand 0 "ext_register_operand" "Q")
995 (match_operand:QI 1 "general_operand" "Qmn")))]
996 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997 "cmp{b}\t{%1, %h0|%h0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "QI")])
1001 (define_insn "cmpqi_ext_3_insn_rex64"
1002 [(set (reg FLAGS_REG)
1006 (match_operand 0 "ext_register_operand" "Q")
1009 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1010 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%1, %h0|%h0, %1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_4"
1016 [(set (reg FLAGS_REG)
1020 (match_operand 0 "ext_register_operand" "Q")
1025 (match_operand 1 "ext_register_operand" "Q")
1027 (const_int 8)) 0)))]
1028 "ix86_match_ccmode (insn, CCmode)"
1029 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1030 [(set_attr "type" "icmp")
1031 (set_attr "mode" "QI")])
1033 ;; These implement float point compares.
1034 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1035 ;; which would allow mix and match FP modes on the compares. Which is what
1036 ;; the old patterns did, but with many more of them.
1038 (define_expand "cmpxf"
1039 [(set (reg:CC FLAGS_REG)
1040 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1041 (match_operand:XF 1 "nonmemory_operand" "")))]
1044 ix86_compare_op0 = operands[0];
1045 ix86_compare_op1 = operands[1];
1049 (define_expand "cmp<mode>"
1050 [(set (reg:CC FLAGS_REG)
1051 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1052 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1053 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1055 ix86_compare_op0 = operands[0];
1056 ix86_compare_op1 = operands[1];
1060 ;; FP compares, step 1:
1061 ;; Set the FP condition codes.
1063 ;; CCFPmode compare with exceptions
1064 ;; CCFPUmode compare with no exceptions
1066 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1067 ;; used to manage the reg stack popping would not be preserved.
1069 (define_insn "*cmpfp_0"
1070 [(set (match_operand:HI 0 "register_operand" "=a")
1073 (match_operand 1 "register_operand" "f")
1074 (match_operand 2 "const0_operand" ""))]
1076 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078 "* return output_fp_compare (insn, operands, 0, 0);"
1079 [(set_attr "type" "multi")
1080 (set_attr "unit" "i387")
1082 (cond [(match_operand:SF 1 "" "")
1084 (match_operand:DF 1 "" "")
1087 (const_string "XF")))])
1089 (define_insn_and_split "*cmpfp_0_cc"
1090 [(set (reg:CCFP FLAGS_REG)
1092 (match_operand 1 "register_operand" "f")
1093 (match_operand 2 "const0_operand" "")))
1094 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1095 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096 && TARGET_SAHF && !TARGET_CMOVE
1097 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1099 "&& reload_completed"
1102 [(compare:CCFP (match_dup 1)(match_dup 2))]
1104 (set (reg:CC FLAGS_REG)
1105 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1107 [(set_attr "type" "multi")
1108 (set_attr "unit" "i387")
1110 (cond [(match_operand:SF 1 "" "")
1112 (match_operand:DF 1 "" "")
1115 (const_string "XF")))])
1117 (define_insn "*cmpfp_xf"
1118 [(set (match_operand:HI 0 "register_operand" "=a")
1121 (match_operand:XF 1 "register_operand" "f")
1122 (match_operand:XF 2 "register_operand" "f"))]
1125 "* return output_fp_compare (insn, operands, 0, 0);"
1126 [(set_attr "type" "multi")
1127 (set_attr "unit" "i387")
1128 (set_attr "mode" "XF")])
1130 (define_insn_and_split "*cmpfp_xf_cc"
1131 [(set (reg:CCFP FLAGS_REG)
1133 (match_operand:XF 1 "register_operand" "f")
1134 (match_operand:XF 2 "register_operand" "f")))
1135 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1137 && TARGET_SAHF && !TARGET_CMOVE"
1139 "&& reload_completed"
1142 [(compare:CCFP (match_dup 1)(match_dup 2))]
1144 (set (reg:CC FLAGS_REG)
1145 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1147 [(set_attr "type" "multi")
1148 (set_attr "unit" "i387")
1149 (set_attr "mode" "XF")])
1151 (define_insn "*cmpfp_<mode>"
1152 [(set (match_operand:HI 0 "register_operand" "=a")
1155 (match_operand:MODEF 1 "register_operand" "f")
1156 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1159 "* return output_fp_compare (insn, operands, 0, 0);"
1160 [(set_attr "type" "multi")
1161 (set_attr "unit" "i387")
1162 (set_attr "mode" "<MODE>")])
1164 (define_insn_and_split "*cmpfp_<mode>_cc"
1165 [(set (reg:CCFP FLAGS_REG)
1167 (match_operand:MODEF 1 "register_operand" "f")
1168 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1169 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1171 && TARGET_SAHF && !TARGET_CMOVE"
1173 "&& reload_completed"
1176 [(compare:CCFP (match_dup 1)(match_dup 2))]
1178 (set (reg:CC FLAGS_REG)
1179 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1181 [(set_attr "type" "multi")
1182 (set_attr "unit" "i387")
1183 (set_attr "mode" "<MODE>")])
1185 (define_insn "*cmpfp_u"
1186 [(set (match_operand:HI 0 "register_operand" "=a")
1189 (match_operand 1 "register_operand" "f")
1190 (match_operand 2 "register_operand" "f"))]
1192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1194 "* return output_fp_compare (insn, operands, 0, 1);"
1195 [(set_attr "type" "multi")
1196 (set_attr "unit" "i387")
1198 (cond [(match_operand:SF 1 "" "")
1200 (match_operand:DF 1 "" "")
1203 (const_string "XF")))])
1205 (define_insn_and_split "*cmpfp_u_cc"
1206 [(set (reg:CCFPU FLAGS_REG)
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "register_operand" "f")))
1210 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && TARGET_SAHF && !TARGET_CMOVE
1213 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1215 "&& reload_completed"
1218 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1220 (set (reg:CC FLAGS_REG)
1221 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1223 [(set_attr "type" "multi")
1224 (set_attr "unit" "i387")
1226 (cond [(match_operand:SF 1 "" "")
1228 (match_operand:DF 1 "" "")
1231 (const_string "XF")))])
1233 (define_insn "*cmpfp_<mode>"
1234 [(set (match_operand:HI 0 "register_operand" "=a")
1237 (match_operand 1 "register_operand" "f")
1238 (match_operator 3 "float_operator"
1239 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1241 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1243 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1244 "* return output_fp_compare (insn, operands, 0, 0);"
1245 [(set_attr "type" "multi")
1246 (set_attr "unit" "i387")
1247 (set_attr "fp_int_src" "true")
1248 (set_attr "mode" "<MODE>")])
1250 (define_insn_and_split "*cmpfp_<mode>_cc"
1251 [(set (reg:CCFP FLAGS_REG)
1253 (match_operand 1 "register_operand" "f")
1254 (match_operator 3 "float_operator"
1255 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1256 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1258 && TARGET_SAHF && !TARGET_CMOVE
1259 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1260 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1262 "&& reload_completed"
1267 (match_op_dup 3 [(match_dup 2)]))]
1269 (set (reg:CC FLAGS_REG)
1270 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1272 [(set_attr "type" "multi")
1273 (set_attr "unit" "i387")
1274 (set_attr "fp_int_src" "true")
1275 (set_attr "mode" "<MODE>")])
1277 ;; FP compares, step 2
1278 ;; Move the fpsw to ax.
1280 (define_insn "x86_fnstsw_1"
1281 [(set (match_operand:HI 0 "register_operand" "=a")
1282 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1285 [(set_attr "length" "2")
1286 (set_attr "mode" "SI")
1287 (set_attr "unit" "i387")])
1289 ;; FP compares, step 3
1290 ;; Get ax into flags, general case.
1292 (define_insn "x86_sahf_1"
1293 [(set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1298 #ifdef HAVE_AS_IX86_SAHF
1301 return ".byte\t0x9e";
1304 [(set_attr "length" "1")
1305 (set_attr "athlon_decode" "vector")
1306 (set_attr "amdfam10_decode" "direct")
1307 (set_attr "mode" "SI")])
1309 ;; Pentium Pro can do steps 1 through 3 in one go.
1310 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1311 (define_insn "*cmpfp_i_mixed"
1312 [(set (reg:CCFP FLAGS_REG)
1313 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1314 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1315 "TARGET_MIX_SSE_I387
1316 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1317 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1318 "* return output_fp_compare (insn, operands, 1, 0);"
1319 [(set_attr "type" "fcmp,ssecomi")
1320 (set_attr "prefix" "orig,maybe_vex")
1322 (if_then_else (match_operand:SF 1 "" "")
1324 (const_string "DF")))
1325 (set_attr "athlon_decode" "vector")
1326 (set_attr "amdfam10_decode" "direct")])
1328 (define_insn "*cmpfp_i_sse"
1329 [(set (reg:CCFP FLAGS_REG)
1330 (compare:CCFP (match_operand 0 "register_operand" "x")
1331 (match_operand 1 "nonimmediate_operand" "xm")))]
1333 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1334 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1335 "* return output_fp_compare (insn, operands, 1, 0);"
1336 [(set_attr "type" "ssecomi")
1337 (set_attr "prefix" "maybe_vex")
1339 (if_then_else (match_operand:SF 1 "" "")
1341 (const_string "DF")))
1342 (set_attr "athlon_decode" "vector")
1343 (set_attr "amdfam10_decode" "direct")])
1345 (define_insn "*cmpfp_i_i387"
1346 [(set (reg:CCFP FLAGS_REG)
1347 (compare:CCFP (match_operand 0 "register_operand" "f")
1348 (match_operand 1 "register_operand" "f")))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1351 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1352 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1353 "* return output_fp_compare (insn, operands, 1, 0);"
1354 [(set_attr "type" "fcmp")
1356 (cond [(match_operand:SF 1 "" "")
1358 (match_operand:DF 1 "" "")
1361 (const_string "XF")))
1362 (set_attr "athlon_decode" "vector")
1363 (set_attr "amdfam10_decode" "direct")])
1365 (define_insn "*cmpfp_iu_mixed"
1366 [(set (reg:CCFPU FLAGS_REG)
1367 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1368 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369 "TARGET_MIX_SSE_I387
1370 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372 "* return output_fp_compare (insn, operands, 1, 1);"
1373 [(set_attr "type" "fcmp,ssecomi")
1374 (set_attr "prefix" "orig,maybe_vex")
1376 (if_then_else (match_operand:SF 1 "" "")
1378 (const_string "DF")))
1379 (set_attr "athlon_decode" "vector")
1380 (set_attr "amdfam10_decode" "direct")])
1382 (define_insn "*cmpfp_iu_sse"
1383 [(set (reg:CCFPU FLAGS_REG)
1384 (compare:CCFPU (match_operand 0 "register_operand" "x")
1385 (match_operand 1 "nonimmediate_operand" "xm")))]
1387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389 "* return output_fp_compare (insn, operands, 1, 1);"
1390 [(set_attr "type" "ssecomi")
1391 (set_attr "prefix" "maybe_vex")
1393 (if_then_else (match_operand:SF 1 "" "")
1395 (const_string "DF")))
1396 (set_attr "athlon_decode" "vector")
1397 (set_attr "amdfam10_decode" "direct")])
1399 (define_insn "*cmpfp_iu_387"
1400 [(set (reg:CCFPU FLAGS_REG)
1401 (compare:CCFPU (match_operand 0 "register_operand" "f")
1402 (match_operand 1 "register_operand" "f")))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1405 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407 "* return output_fp_compare (insn, operands, 1, 1);"
1408 [(set_attr "type" "fcmp")
1410 (cond [(match_operand:SF 1 "" "")
1412 (match_operand:DF 1 "" "")
1415 (const_string "XF")))
1416 (set_attr "athlon_decode" "vector")
1417 (set_attr "amdfam10_decode" "direct")])
1419 ;; Move instructions.
1421 ;; General case of fullword move.
1423 (define_expand "movsi"
1424 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1425 (match_operand:SI 1 "general_operand" ""))]
1427 "ix86_expand_move (SImode, operands); DONE;")
1429 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1432 ;; %%% We don't use a post-inc memory reference because x86 is not a
1433 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1434 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1435 ;; targets without our curiosities, and it is just as easy to represent
1436 ;; this differently.
1438 (define_insn "*pushsi2"
1439 [(set (match_operand:SI 0 "push_operand" "=<")
1440 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1443 [(set_attr "type" "push")
1444 (set_attr "mode" "SI")])
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushsi2_rex64"
1448 [(set (match_operand:SI 0 "push_operand" "=X")
1449 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1452 [(set_attr "type" "push")
1453 (set_attr "mode" "SI")])
1455 (define_insn "*pushsi2_prologue"
1456 [(set (match_operand:SI 0 "push_operand" "=<")
1457 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1458 (clobber (mem:BLK (scratch)))]
1461 [(set_attr "type" "push")
1462 (set_attr "mode" "SI")])
1464 (define_insn "*popsi1_epilogue"
1465 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1466 (mem:SI (reg:SI SP_REG)))
1467 (set (reg:SI SP_REG)
1468 (plus:SI (reg:SI SP_REG) (const_int 4)))
1469 (clobber (mem:BLK (scratch)))]
1472 [(set_attr "type" "pop")
1473 (set_attr "mode" "SI")])
1475 (define_insn "popsi1"
1476 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1477 (mem:SI (reg:SI SP_REG)))
1478 (set (reg:SI SP_REG)
1479 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1482 [(set_attr "type" "pop")
1483 (set_attr "mode" "SI")])
1485 (define_insn "*movsi_xor"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (match_operand:SI 1 "const0_operand" ""))
1488 (clobber (reg:CC FLAGS_REG))]
1491 [(set_attr "type" "alu1")
1492 (set_attr "mode" "SI")
1493 (set_attr "length_immediate" "0")])
1495 (define_insn "*movsi_or"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (match_operand:SI 1 "immediate_operand" "i"))
1498 (clobber (reg:CC FLAGS_REG))]
1500 && operands[1] == constm1_rtx"
1502 operands[1] = constm1_rtx;
1503 return "or{l}\t{%1, %0|%0, %1}";
1505 [(set_attr "type" "alu1")
1506 (set_attr "mode" "SI")
1507 (set_attr "length_immediate" "1")])
1509 (define_insn "*movsi_1"
1510 [(set (match_operand:SI 0 "nonimmediate_operand"
1511 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1512 (match_operand:SI 1 "general_operand"
1513 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1514 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1516 switch (get_attr_type (insn))
1519 if (get_attr_mode (insn) == MODE_TI)
1520 return "%vpxor\t%0, %d0";
1521 return "%vxorps\t%0, %d0";
1524 switch (get_attr_mode (insn))
1527 return "%vmovdqa\t{%1, %0|%0, %1}";
1529 return "%vmovaps\t{%1, %0|%0, %1}";
1531 return "%vmovd\t{%1, %0|%0, %1}";
1533 return "%vmovss\t{%1, %0|%0, %1}";
1539 return "pxor\t%0, %0";
1542 if (get_attr_mode (insn) == MODE_DI)
1543 return "movq\t{%1, %0|%0, %1}";
1544 return "movd\t{%1, %0|%0, %1}";
1547 return "lea{l}\t{%1, %0|%0, %1}";
1550 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1551 return "mov{l}\t{%1, %0|%0, %1}";
1555 (cond [(eq_attr "alternative" "2")
1556 (const_string "mmx")
1557 (eq_attr "alternative" "3,4,5")
1558 (const_string "mmxmov")
1559 (eq_attr "alternative" "6")
1560 (const_string "sselog1")
1561 (eq_attr "alternative" "7,8,9,10,11")
1562 (const_string "ssemov")
1563 (match_operand:DI 1 "pic_32bit_operand" "")
1564 (const_string "lea")
1566 (const_string "imov")))
1567 (set (attr "prefix")
1568 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1569 (const_string "orig")
1570 (const_string "maybe_vex")))
1572 (cond [(eq_attr "alternative" "2,3")
1574 (eq_attr "alternative" "6,7")
1576 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1577 (const_string "V4SF")
1578 (const_string "TI"))
1579 (and (eq_attr "alternative" "8,9,10,11")
1580 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1583 (const_string "SI")))])
1585 ;; Stores and loads of ax to arbitrary constant address.
1586 ;; We fake an second form of instruction to force reload to load address
1587 ;; into register when rax is not available
1588 (define_insn "*movabssi_1_rex64"
1589 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1590 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1591 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1593 movabs{l}\t{%1, %P0|%P0, %1}
1594 mov{l}\t{%1, %a0|%a0, %1}"
1595 [(set_attr "type" "imov")
1596 (set_attr "modrm" "0,*")
1597 (set_attr "length_address" "8,0")
1598 (set_attr "length_immediate" "0,*")
1599 (set_attr "memory" "store")
1600 (set_attr "mode" "SI")])
1602 (define_insn "*movabssi_2_rex64"
1603 [(set (match_operand:SI 0 "register_operand" "=a,r")
1604 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1607 movabs{l}\t{%P1, %0|%0, %P1}
1608 mov{l}\t{%a1, %0|%0, %a1}"
1609 [(set_attr "type" "imov")
1610 (set_attr "modrm" "0,*")
1611 (set_attr "length_address" "8,0")
1612 (set_attr "length_immediate" "0")
1613 (set_attr "memory" "load")
1614 (set_attr "mode" "SI")])
1616 (define_insn "*swapsi"
1617 [(set (match_operand:SI 0 "register_operand" "+r")
1618 (match_operand:SI 1 "register_operand" "+r"))
1623 [(set_attr "type" "imov")
1624 (set_attr "mode" "SI")
1625 (set_attr "pent_pair" "np")
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "double")])
1629 (define_expand "movhi"
1630 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1631 (match_operand:HI 1 "general_operand" ""))]
1633 "ix86_expand_move (HImode, operands); DONE;")
1635 (define_insn "*pushhi2"
1636 [(set (match_operand:HI 0 "push_operand" "=X")
1637 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1640 [(set_attr "type" "push")
1641 (set_attr "mode" "SI")])
1643 ;; For 64BIT abi we always round up to 8 bytes.
1644 (define_insn "*pushhi2_rex64"
1645 [(set (match_operand:HI 0 "push_operand" "=X")
1646 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1649 [(set_attr "type" "push")
1650 (set_attr "mode" "DI")])
1652 (define_insn "*movhi_1"
1653 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1654 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1655 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1657 switch (get_attr_type (insn))
1660 /* movzwl is faster than movw on p2 due to partial word stalls,
1661 though not as fast as an aligned movl. */
1662 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1664 if (get_attr_mode (insn) == MODE_SI)
1665 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1667 return "mov{w}\t{%1, %0|%0, %1}";
1671 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1672 (const_string "imov")
1673 (and (eq_attr "alternative" "0")
1674 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1676 (eq (symbol_ref "TARGET_HIMODE_MATH")
1678 (const_string "imov")
1679 (and (eq_attr "alternative" "1,2")
1680 (match_operand:HI 1 "aligned_operand" ""))
1681 (const_string "imov")
1682 (and (ne (symbol_ref "TARGET_MOVX")
1684 (eq_attr "alternative" "0,2"))
1685 (const_string "imovx")
1687 (const_string "imov")))
1689 (cond [(eq_attr "type" "imovx")
1691 (and (eq_attr "alternative" "1,2")
1692 (match_operand:HI 1 "aligned_operand" ""))
1694 (and (eq_attr "alternative" "0")
1695 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1697 (eq (symbol_ref "TARGET_HIMODE_MATH")
1701 (const_string "HI")))])
1703 ;; Stores and loads of ax to arbitrary constant address.
1704 ;; We fake an second form of instruction to force reload to load address
1705 ;; into register when rax is not available
1706 (define_insn "*movabshi_1_rex64"
1707 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1708 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1709 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1711 movabs{w}\t{%1, %P0|%P0, %1}
1712 mov{w}\t{%1, %a0|%a0, %1}"
1713 [(set_attr "type" "imov")
1714 (set_attr "modrm" "0,*")
1715 (set_attr "length_address" "8,0")
1716 (set_attr "length_immediate" "0,*")
1717 (set_attr "memory" "store")
1718 (set_attr "mode" "HI")])
1720 (define_insn "*movabshi_2_rex64"
1721 [(set (match_operand:HI 0 "register_operand" "=a,r")
1722 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1723 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1725 movabs{w}\t{%P1, %0|%0, %P1}
1726 mov{w}\t{%a1, %0|%0, %a1}"
1727 [(set_attr "type" "imov")
1728 (set_attr "modrm" "0,*")
1729 (set_attr "length_address" "8,0")
1730 (set_attr "length_immediate" "0")
1731 (set_attr "memory" "load")
1732 (set_attr "mode" "HI")])
1734 (define_insn "*swaphi_1"
1735 [(set (match_operand:HI 0 "register_operand" "+r")
1736 (match_operand:HI 1 "register_operand" "+r"))
1739 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1741 [(set_attr "type" "imov")
1742 (set_attr "mode" "SI")
1743 (set_attr "pent_pair" "np")
1744 (set_attr "athlon_decode" "vector")
1745 (set_attr "amdfam10_decode" "double")])
1747 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1748 (define_insn "*swaphi_2"
1749 [(set (match_operand:HI 0 "register_operand" "+r")
1750 (match_operand:HI 1 "register_operand" "+r"))
1753 "TARGET_PARTIAL_REG_STALL"
1755 [(set_attr "type" "imov")
1756 (set_attr "mode" "HI")
1757 (set_attr "pent_pair" "np")
1758 (set_attr "athlon_decode" "vector")])
1760 (define_expand "movstricthi"
1761 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1762 (match_operand:HI 1 "general_operand" ""))]
1765 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1767 /* Don't generate memory->memory moves, go through a register */
1768 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1769 operands[1] = force_reg (HImode, operands[1]);
1772 (define_insn "*movstricthi_1"
1773 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1774 (match_operand:HI 1 "general_operand" "rn,m"))]
1775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1777 "mov{w}\t{%1, %0|%0, %1}"
1778 [(set_attr "type" "imov")
1779 (set_attr "mode" "HI")])
1781 (define_insn "*movstricthi_xor"
1782 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1783 (match_operand:HI 1 "const0_operand" ""))
1784 (clobber (reg:CC FLAGS_REG))]
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "HI")
1789 (set_attr "length_immediate" "0")])
1791 (define_expand "movqi"
1792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1793 (match_operand:QI 1 "general_operand" ""))]
1795 "ix86_expand_move (QImode, operands); DONE;")
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte". But actually we use pushl, which has the effect
1799 ;; of rounding the amount pushed up to a word.
1801 (define_insn "*pushqi2"
1802 [(set (match_operand:QI 0 "push_operand" "=X")
1803 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1806 [(set_attr "type" "push")
1807 (set_attr "mode" "SI")])
1809 ;; For 64BIT abi we always round up to 8 bytes.
1810 (define_insn "*pushqi2_rex64"
1811 [(set (match_operand:QI 0 "push_operand" "=X")
1812 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1815 [(set_attr "type" "push")
1816 (set_attr "mode" "DI")])
1818 ;; Situation is quite tricky about when to choose full sized (SImode) move
1819 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1820 ;; partial register dependency machines (such as AMD Athlon), where QImode
1821 ;; moves issue extra dependency and for partial register stalls machines
1822 ;; that don't use QImode patterns (and QImode move cause stall on the next
1825 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1826 ;; register stall machines with, where we use QImode instructions, since
1827 ;; partial register stall can be caused there. Then we use movzx.
1828 (define_insn "*movqi_1"
1829 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1830 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1831 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1833 switch (get_attr_type (insn))
1836 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1837 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1839 if (get_attr_mode (insn) == MODE_SI)
1840 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1842 return "mov{b}\t{%1, %0|%0, %1}";
1846 (cond [(and (eq_attr "alternative" "5")
1847 (not (match_operand:QI 1 "aligned_operand" "")))
1848 (const_string "imovx")
1849 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1850 (const_string "imov")
1851 (and (eq_attr "alternative" "3")
1852 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1854 (eq (symbol_ref "TARGET_QIMODE_MATH")
1856 (const_string "imov")
1857 (eq_attr "alternative" "3,5")
1858 (const_string "imovx")
1859 (and (ne (symbol_ref "TARGET_MOVX")
1861 (eq_attr "alternative" "2"))
1862 (const_string "imovx")
1864 (const_string "imov")))
1866 (cond [(eq_attr "alternative" "3,4,5")
1868 (eq_attr "alternative" "6")
1870 (eq_attr "type" "imovx")
1872 (and (eq_attr "type" "imov")
1873 (and (eq_attr "alternative" "0,1")
1874 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1876 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1878 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1881 ;; Avoid partial register stalls when not using QImode arithmetic
1882 (and (eq_attr "type" "imov")
1883 (and (eq_attr "alternative" "0,1")
1884 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1886 (eq (symbol_ref "TARGET_QIMODE_MATH")
1890 (const_string "QI")))])
1892 (define_insn "*swapqi_1"
1893 [(set (match_operand:QI 0 "register_operand" "+r")
1894 (match_operand:QI 1 "register_operand" "+r"))
1897 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1899 [(set_attr "type" "imov")
1900 (set_attr "mode" "SI")
1901 (set_attr "pent_pair" "np")
1902 (set_attr "athlon_decode" "vector")
1903 (set_attr "amdfam10_decode" "vector")])
1905 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1906 (define_insn "*swapqi_2"
1907 [(set (match_operand:QI 0 "register_operand" "+q")
1908 (match_operand:QI 1 "register_operand" "+q"))
1911 "TARGET_PARTIAL_REG_STALL"
1913 [(set_attr "type" "imov")
1914 (set_attr "mode" "QI")
1915 (set_attr "pent_pair" "np")
1916 (set_attr "athlon_decode" "vector")])
1918 (define_expand "movstrictqi"
1919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1920 (match_operand:QI 1 "general_operand" ""))]
1923 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1925 /* Don't generate memory->memory moves, go through a register. */
1926 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1927 operands[1] = force_reg (QImode, operands[1]);
1930 (define_insn "*movstrictqi_1"
1931 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1932 (match_operand:QI 1 "general_operand" "*qn,m"))]
1933 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 "mov{b}\t{%1, %0|%0, %1}"
1936 [(set_attr "type" "imov")
1937 (set_attr "mode" "QI")])
1939 (define_insn "*movstrictqi_xor"
1940 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1941 (match_operand:QI 1 "const0_operand" ""))
1942 (clobber (reg:CC FLAGS_REG))]
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "QI")
1947 (set_attr "length_immediate" "0")])
1949 (define_insn "*movsi_extv_1"
1950 [(set (match_operand:SI 0 "register_operand" "=R")
1951 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1955 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1956 [(set_attr "type" "imovx")
1957 (set_attr "mode" "SI")])
1959 (define_insn "*movhi_extv_1"
1960 [(set (match_operand:HI 0 "register_operand" "=R")
1961 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1965 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1966 [(set_attr "type" "imovx")
1967 (set_attr "mode" "SI")])
1969 (define_insn "*movqi_extv_1"
1970 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1971 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1976 switch (get_attr_type (insn))
1979 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1981 return "mov{b}\t{%h1, %0|%0, %h1}";
1985 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1986 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1987 (ne (symbol_ref "TARGET_MOVX")
1989 (const_string "imovx")
1990 (const_string "imov")))
1992 (if_then_else (eq_attr "type" "imovx")
1994 (const_string "QI")))])
1996 (define_insn "*movqi_extv_1_rex64"
1997 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1998 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2003 switch (get_attr_type (insn))
2006 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2008 return "mov{b}\t{%h1, %0|%0, %h1}";
2012 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2013 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2014 (ne (symbol_ref "TARGET_MOVX")
2016 (const_string "imovx")
2017 (const_string "imov")))
2019 (if_then_else (eq_attr "type" "imovx")
2021 (const_string "QI")))])
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsqi_1_rex64"
2027 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2029 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2031 movabs{b}\t{%1, %P0|%P0, %1}
2032 mov{b}\t{%1, %a0|%a0, %1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "modrm" "0,*")
2035 (set_attr "length_address" "8,0")
2036 (set_attr "length_immediate" "0,*")
2037 (set_attr "memory" "store")
2038 (set_attr "mode" "QI")])
2040 (define_insn "*movabsqi_2_rex64"
2041 [(set (match_operand:QI 0 "register_operand" "=a,r")
2042 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2045 movabs{b}\t{%P1, %0|%0, %P1}
2046 mov{b}\t{%a1, %0|%0, %a1}"
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0")
2051 (set_attr "memory" "load")
2052 (set_attr "mode" "QI")])
2054 (define_insn "*movdi_extzv_1"
2055 [(set (match_operand:DI 0 "register_operand" "=R")
2056 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2060 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2061 [(set_attr "type" "imovx")
2062 (set_attr "mode" "DI")])
2064 (define_insn "*movsi_extzv_1"
2065 [(set (match_operand:SI 0 "register_operand" "=R")
2066 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2070 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2071 [(set_attr "type" "imovx")
2072 (set_attr "mode" "SI")])
2074 (define_insn "*movqi_extzv_2"
2075 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2076 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2081 switch (get_attr_type (insn))
2084 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2086 return "mov{b}\t{%h1, %0|%0, %h1}";
2090 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2091 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2092 (ne (symbol_ref "TARGET_MOVX")
2094 (const_string "imovx")
2095 (const_string "imov")))
2097 (if_then_else (eq_attr "type" "imovx")
2099 (const_string "QI")))])
2101 (define_insn "*movqi_extzv_2_rex64"
2102 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2103 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2108 switch (get_attr_type (insn))
2111 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2113 return "mov{b}\t{%h1, %0|%0, %h1}";
2117 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118 (ne (symbol_ref "TARGET_MOVX")
2120 (const_string "imovx")
2121 (const_string "imov")))
2123 (if_then_else (eq_attr "type" "imovx")
2125 (const_string "QI")))])
2127 (define_insn "movsi_insv_1"
2128 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2131 (match_operand:SI 1 "general_operand" "Qmn"))]
2133 "mov{b}\t{%b1, %h0|%h0, %b1}"
2134 [(set_attr "type" "imov")
2135 (set_attr "mode" "QI")])
2137 (define_insn "*movsi_insv_1_rex64"
2138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2141 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2143 "mov{b}\t{%b1, %h0|%h0, %b1}"
2144 [(set_attr "type" "imov")
2145 (set_attr "mode" "QI")])
2147 (define_insn "movdi_insv_1_rex64"
2148 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2151 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2153 "mov{b}\t{%b1, %h0|%h0, %b1}"
2154 [(set_attr "type" "imov")
2155 (set_attr "mode" "QI")])
2157 (define_insn "*movqi_insv_2"
2158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2161 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2164 "mov{b}\t{%h1, %h0|%h0, %h1}"
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "QI")])
2168 (define_expand "movdi"
2169 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170 (match_operand:DI 1 "general_operand" ""))]
2172 "ix86_expand_move (DImode, operands); DONE;")
2174 (define_insn "*pushdi"
2175 [(set (match_operand:DI 0 "push_operand" "=<")
2176 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2180 (define_insn "*pushdi2_rex64"
2181 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2182 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2187 [(set_attr "type" "push,multi")
2188 (set_attr "mode" "DI")])
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it. In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2195 [(match_scratch:DI 2 "r")
2196 (set (match_operand:DI 0 "push_operand" "")
2197 (match_operand:DI 1 "immediate_operand" ""))]
2198 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2199 && !x86_64_immediate_operand (operands[1], DImode)"
2200 [(set (match_dup 2) (match_dup 1))
2201 (set (match_dup 0) (match_dup 2))]
2204 ;; We need to define this as both peepholer and splitter for case
2205 ;; peephole2 pass is not run.
2206 ;; "&& 1" is needed to keep it from matching the previous pattern.
2208 [(set (match_operand:DI 0 "push_operand" "")
2209 (match_operand:DI 1 "immediate_operand" ""))]
2210 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2211 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2212 [(set (match_dup 0) (match_dup 1))
2213 (set (match_dup 2) (match_dup 3))]
2214 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2215 operands[1] = gen_lowpart (DImode, operands[2]);
2216 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2221 [(set (match_operand:DI 0 "push_operand" "")
2222 (match_operand:DI 1 "immediate_operand" ""))]
2223 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2224 ? epilogue_completed : reload_completed)
2225 && !symbolic_operand (operands[1], DImode)
2226 && !x86_64_immediate_operand (operands[1], DImode)"
2227 [(set (match_dup 0) (match_dup 1))
2228 (set (match_dup 2) (match_dup 3))]
2229 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2230 operands[1] = gen_lowpart (DImode, operands[2]);
2231 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2235 (define_insn "*pushdi2_prologue_rex64"
2236 [(set (match_operand:DI 0 "push_operand" "=<")
2237 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2238 (clobber (mem:BLK (scratch)))]
2241 [(set_attr "type" "push")
2242 (set_attr "mode" "DI")])
2244 (define_insn "*popdi1_epilogue_rex64"
2245 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2246 (mem:DI (reg:DI SP_REG)))
2247 (set (reg:DI SP_REG)
2248 (plus:DI (reg:DI SP_REG) (const_int 8)))
2249 (clobber (mem:BLK (scratch)))]
2252 [(set_attr "type" "pop")
2253 (set_attr "mode" "DI")])
2255 (define_insn "popdi1"
2256 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2257 (mem:DI (reg:DI SP_REG)))
2258 (set (reg:DI SP_REG)
2259 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2262 [(set_attr "type" "pop")
2263 (set_attr "mode" "DI")])
2265 (define_insn "*movdi_xor_rex64"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (match_operand:DI 1 "const0_operand" ""))
2268 (clobber (reg:CC FLAGS_REG))]
2270 && reload_completed"
2272 [(set_attr "type" "alu1")
2273 (set_attr "mode" "SI")
2274 (set_attr "length_immediate" "0")])
2276 (define_insn "*movdi_or_rex64"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (match_operand:DI 1 "const_int_operand" "i"))
2279 (clobber (reg:CC FLAGS_REG))]
2282 && operands[1] == constm1_rtx"
2284 operands[1] = constm1_rtx;
2285 return "or{q}\t{%1, %0|%0, %1}";
2287 [(set_attr "type" "alu1")
2288 (set_attr "mode" "DI")
2289 (set_attr "length_immediate" "1")])
2291 (define_insn "*movdi_2"
2292 [(set (match_operand:DI 0 "nonimmediate_operand"
2293 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2294 (match_operand:DI 1 "general_operand"
2295 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2296 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2301 movq\t{%1, %0|%0, %1}
2302 movq\t{%1, %0|%0, %1}
2304 %vmovq\t{%1, %0|%0, %1}
2305 %vmovdqa\t{%1, %0|%0, %1}
2306 %vmovq\t{%1, %0|%0, %1}
2308 movlps\t{%1, %0|%0, %1}
2309 movaps\t{%1, %0|%0, %1}
2310 movlps\t{%1, %0|%0, %1}"
2311 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2312 (set (attr "prefix")
2313 (if_then_else (eq_attr "alternative" "5,6,7,8")
2314 (const_string "vex")
2315 (const_string "orig")))
2316 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2319 [(set (match_operand:DI 0 "push_operand" "")
2320 (match_operand:DI 1 "general_operand" ""))]
2321 "!TARGET_64BIT && reload_completed
2322 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2324 "ix86_split_long_move (operands); DONE;")
2326 ;; %%% This multiword shite has got to go.
2328 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2329 (match_operand:DI 1 "general_operand" ""))]
2330 "!TARGET_64BIT && reload_completed
2331 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2332 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2334 "ix86_split_long_move (operands); DONE;")
2336 (define_insn "*movdi_1_rex64"
2337 [(set (match_operand:DI 0 "nonimmediate_operand"
2338 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2339 (match_operand:DI 1 "general_operand"
2340 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2341 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2343 switch (get_attr_type (insn))
2346 if (SSE_REG_P (operands[0]))
2347 return "movq2dq\t{%1, %0|%0, %1}";
2349 return "movdq2q\t{%1, %0|%0, %1}";
2354 if (get_attr_mode (insn) == MODE_TI)
2355 return "vmovdqa\t{%1, %0|%0, %1}";
2357 return "vmovq\t{%1, %0|%0, %1}";
2360 if (get_attr_mode (insn) == MODE_TI)
2361 return "movdqa\t{%1, %0|%0, %1}";
2365 /* Moves from and into integer register is done using movd
2366 opcode with REX prefix. */
2367 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2368 return "movd\t{%1, %0|%0, %1}";
2369 return "movq\t{%1, %0|%0, %1}";
2372 return "%vpxor\t%0, %d0";
2375 return "pxor\t%0, %0";
2381 return "lea{q}\t{%a1, %0|%0, %a1}";
2384 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2385 if (get_attr_mode (insn) == MODE_SI)
2386 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387 else if (which_alternative == 2)
2388 return "movabs{q}\t{%1, %0|%0, %1}";
2390 return "mov{q}\t{%1, %0|%0, %1}";
2394 (cond [(eq_attr "alternative" "5")
2395 (const_string "mmx")
2396 (eq_attr "alternative" "6,7,8,9,10")
2397 (const_string "mmxmov")
2398 (eq_attr "alternative" "11")
2399 (const_string "sselog1")
2400 (eq_attr "alternative" "12,13,14,15,16")
2401 (const_string "ssemov")
2402 (eq_attr "alternative" "17,18")
2403 (const_string "ssecvt")
2404 (eq_attr "alternative" "4")
2405 (const_string "multi")
2406 (match_operand:DI 1 "pic_32bit_operand" "")
2407 (const_string "lea")
2409 (const_string "imov")))
2410 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2412 (set (attr "prefix")
2413 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2414 (const_string "maybe_vex")
2415 (const_string "orig")))
2416 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2418 ;; Stores and loads of ax to arbitrary constant address.
2419 ;; We fake an second form of instruction to force reload to load address
2420 ;; into register when rax is not available
2421 (define_insn "*movabsdi_1_rex64"
2422 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2423 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2424 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2426 movabs{q}\t{%1, %P0|%P0, %1}
2427 mov{q}\t{%1, %a0|%a0, %1}"
2428 [(set_attr "type" "imov")
2429 (set_attr "modrm" "0,*")
2430 (set_attr "length_address" "8,0")
2431 (set_attr "length_immediate" "0,*")
2432 (set_attr "memory" "store")
2433 (set_attr "mode" "DI")])
2435 (define_insn "*movabsdi_2_rex64"
2436 [(set (match_operand:DI 0 "register_operand" "=a,r")
2437 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2438 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2440 movabs{q}\t{%P1, %0|%0, %P1}
2441 mov{q}\t{%a1, %0|%0, %a1}"
2442 [(set_attr "type" "imov")
2443 (set_attr "modrm" "0,*")
2444 (set_attr "length_address" "8,0")
2445 (set_attr "length_immediate" "0")
2446 (set_attr "memory" "load")
2447 (set_attr "mode" "DI")])
2449 ;; Convert impossible stores of immediate to existing instructions.
2450 ;; First try to get scratch register and go through it. In case this
2451 ;; fails, move by 32bit parts.
2453 [(match_scratch:DI 2 "r")
2454 (set (match_operand:DI 0 "memory_operand" "")
2455 (match_operand:DI 1 "immediate_operand" ""))]
2456 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2457 && !x86_64_immediate_operand (operands[1], DImode)"
2458 [(set (match_dup 2) (match_dup 1))
2459 (set (match_dup 0) (match_dup 2))]
2462 ;; We need to define this as both peepholer and splitter for case
2463 ;; peephole2 pass is not run.
2464 ;; "&& 1" is needed to keep it from matching the previous pattern.
2466 [(set (match_operand:DI 0 "memory_operand" "")
2467 (match_operand:DI 1 "immediate_operand" ""))]
2468 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2469 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2470 [(set (match_dup 2) (match_dup 3))
2471 (set (match_dup 4) (match_dup 5))]
2472 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2475 [(set (match_operand:DI 0 "memory_operand" "")
2476 (match_operand:DI 1 "immediate_operand" ""))]
2477 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2478 ? epilogue_completed : reload_completed)
2479 && !symbolic_operand (operands[1], DImode)
2480 && !x86_64_immediate_operand (operands[1], DImode)"
2481 [(set (match_dup 2) (match_dup 3))
2482 (set (match_dup 4) (match_dup 5))]
2483 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2485 (define_insn "*swapdi_rex64"
2486 [(set (match_operand:DI 0 "register_operand" "+r")
2487 (match_operand:DI 1 "register_operand" "+r"))
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "DI")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")
2496 (set_attr "amdfam10_decode" "double")])
2498 (define_expand "movoi"
2499 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2500 (match_operand:OI 1 "general_operand" ""))]
2502 "ix86_expand_move (OImode, operands); DONE;")
2504 (define_insn "*movoi_internal"
2505 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2506 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2508 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510 switch (which_alternative)
2513 return "vxorps\t%0, %0, %0";
2516 if (misaligned_operand (operands[0], OImode)
2517 || misaligned_operand (operands[1], OImode))
2518 return "vmovdqu\t{%1, %0|%0, %1}";
2520 return "vmovdqa\t{%1, %0|%0, %1}";
2525 [(set_attr "type" "sselog1,ssemov,ssemov")
2526 (set_attr "prefix" "vex")
2527 (set_attr "mode" "OI")])
2529 (define_expand "movti"
2530 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2531 (match_operand:TI 1 "nonimmediate_operand" ""))]
2532 "TARGET_SSE || TARGET_64BIT"
2535 ix86_expand_move (TImode, operands);
2536 else if (push_operand (operands[0], TImode))
2537 ix86_expand_push (TImode, operands[1]);
2539 ix86_expand_vector_move (TImode, operands);
2543 (define_insn "*movti_internal"
2544 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2545 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2546 "TARGET_SSE && !TARGET_64BIT
2547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2549 switch (which_alternative)
2552 if (get_attr_mode (insn) == MODE_V4SF)
2553 return "%vxorps\t%0, %d0";
2555 return "%vpxor\t%0, %d0";
2558 /* TDmode values are passed as TImode on the stack. Moving them
2559 to stack may result in unaligned memory access. */
2560 if (misaligned_operand (operands[0], TImode)
2561 || misaligned_operand (operands[1], TImode))
2563 if (get_attr_mode (insn) == MODE_V4SF)
2564 return "%vmovups\t{%1, %0|%0, %1}";
2566 return "%vmovdqu\t{%1, %0|%0, %1}";
2570 if (get_attr_mode (insn) == MODE_V4SF)
2571 return "%vmovaps\t{%1, %0|%0, %1}";
2573 return "%vmovdqa\t{%1, %0|%0, %1}";
2579 [(set_attr "type" "sselog1,ssemov,ssemov")
2580 (set_attr "prefix" "maybe_vex")
2582 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2583 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2584 (const_string "V4SF")
2585 (and (eq_attr "alternative" "2")
2586 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2588 (const_string "V4SF")]
2589 (const_string "TI")))])
2591 (define_insn "*movti_rex64"
2592 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2593 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2597 switch (which_alternative)
2603 if (get_attr_mode (insn) == MODE_V4SF)
2604 return "%vxorps\t%0, %d0";
2606 return "%vpxor\t%0, %d0";
2609 /* TDmode values are passed as TImode on the stack. Moving them
2610 to stack may result in unaligned memory access. */
2611 if (misaligned_operand (operands[0], TImode)
2612 || misaligned_operand (operands[1], TImode))
2614 if (get_attr_mode (insn) == MODE_V4SF)
2615 return "%vmovups\t{%1, %0|%0, %1}";
2617 return "%vmovdqu\t{%1, %0|%0, %1}";
2621 if (get_attr_mode (insn) == MODE_V4SF)
2622 return "%vmovaps\t{%1, %0|%0, %1}";
2624 return "%vmovdqa\t{%1, %0|%0, %1}";
2630 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2631 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2633 (cond [(eq_attr "alternative" "2,3")
2635 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2637 (const_string "V4SF")
2638 (const_string "TI"))
2639 (eq_attr "alternative" "4")
2641 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2643 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2645 (const_string "V4SF")
2646 (const_string "TI"))]
2647 (const_string "DI")))])
2650 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2651 (match_operand:TI 1 "general_operand" ""))]
2652 "reload_completed && !SSE_REG_P (operands[0])
2653 && !SSE_REG_P (operands[1])"
2655 "ix86_split_long_move (operands); DONE;")
2657 ;; This expands to what emit_move_complex would generate if we didn't
2658 ;; have a movti pattern. Having this avoids problems with reload on
2659 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2660 ;; to have around all the time.
2661 (define_expand "movcdi"
2662 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2663 (match_operand:CDI 1 "general_operand" ""))]
2666 if (push_operand (operands[0], CDImode))
2667 emit_move_complex_push (CDImode, operands[0], operands[1]);
2669 emit_move_complex_parts (operands[0], operands[1]);
2673 (define_expand "movsf"
2674 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2675 (match_operand:SF 1 "general_operand" ""))]
2677 "ix86_expand_move (SFmode, operands); DONE;")
2679 (define_insn "*pushsf"
2680 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2681 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2684 /* Anything else should be already split before reg-stack. */
2685 gcc_assert (which_alternative == 1);
2686 return "push{l}\t%1";
2688 [(set_attr "type" "multi,push,multi")
2689 (set_attr "unit" "i387,*,*")
2690 (set_attr "mode" "SF,SI,SF")])
2692 (define_insn "*pushsf_rex64"
2693 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2697 /* Anything else should be already split before reg-stack. */
2698 gcc_assert (which_alternative == 1);
2699 return "push{q}\t%q1";
2701 [(set_attr "type" "multi,push,multi")
2702 (set_attr "unit" "i387,*,*")
2703 (set_attr "mode" "SF,DI,SF")])
2706 [(set (match_operand:SF 0 "push_operand" "")
2707 (match_operand:SF 1 "memory_operand" ""))]
2709 && MEM_P (operands[1])
2710 && (operands[2] = find_constant_src (insn))"
2715 ;; %%% Kill this when call knows how to work this out.
2717 [(set (match_operand:SF 0 "push_operand" "")
2718 (match_operand:SF 1 "any_fp_register_operand" ""))]
2720 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2721 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2724 [(set (match_operand:SF 0 "push_operand" "")
2725 (match_operand:SF 1 "any_fp_register_operand" ""))]
2727 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2728 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2730 (define_insn "*movsf_1"
2731 [(set (match_operand:SF 0 "nonimmediate_operand"
2732 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2733 (match_operand:SF 1 "general_operand"
2734 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2735 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2736 && (reload_in_progress || reload_completed
2737 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2738 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2739 && standard_80387_constant_p (operands[1]))
2740 || GET_CODE (operands[1]) != CONST_DOUBLE
2741 || memory_operand (operands[0], SFmode))"
2743 switch (which_alternative)
2747 return output_387_reg_move (insn, operands);
2750 return standard_80387_constant_opcode (operands[1]);
2754 return "mov{l}\t{%1, %0|%0, %1}";
2756 if (get_attr_mode (insn) == MODE_TI)
2757 return "%vpxor\t%0, %d0";
2759 return "%vxorps\t%0, %d0";
2761 if (get_attr_mode (insn) == MODE_V4SF)
2762 return "%vmovaps\t{%1, %0|%0, %1}";
2764 return "%vmovss\t{%1, %d0|%d0, %1}";
2767 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2768 : "vmovss\t{%1, %0|%0, %1}";
2770 return "movss\t{%1, %0|%0, %1}";
2772 return "%vmovss\t{%1, %0|%0, %1}";
2774 case 9: case 10: case 14: case 15:
2775 return "movd\t{%1, %0|%0, %1}";
2777 return "%vmovd\t{%1, %0|%0, %1}";
2780 return "movq\t{%1, %0|%0, %1}";
2786 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2787 (set (attr "prefix")
2788 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2789 (const_string "maybe_vex")
2790 (const_string "orig")))
2792 (cond [(eq_attr "alternative" "3,4,9,10")
2794 (eq_attr "alternative" "5")
2796 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2798 (ne (symbol_ref "TARGET_SSE2")
2800 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2803 (const_string "V4SF"))
2804 /* For architectures resolving dependencies on
2805 whole SSE registers use APS move to break dependency
2806 chains, otherwise use short move to avoid extra work.
2808 Do the same for architectures resolving dependencies on
2809 the parts. While in DF mode it is better to always handle
2810 just register parts, the SF mode is different due to lack
2811 of instructions to load just part of the register. It is
2812 better to maintain the whole registers in single format
2813 to avoid problems on using packed logical operations. */
2814 (eq_attr "alternative" "6")
2816 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2818 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2820 (const_string "V4SF")
2821 (const_string "SF"))
2822 (eq_attr "alternative" "11")
2823 (const_string "DI")]
2824 (const_string "SF")))])
2826 (define_insn "*swapsf"
2827 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2828 (match_operand:SF 1 "fp_register_operand" "+f"))
2831 "reload_completed || TARGET_80387"
2833 if (STACK_TOP_P (operands[0]))
2838 [(set_attr "type" "fxch")
2839 (set_attr "mode" "SF")])
2841 (define_expand "movdf"
2842 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2843 (match_operand:DF 1 "general_operand" ""))]
2845 "ix86_expand_move (DFmode, operands); DONE;")
2847 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2848 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2849 ;; On the average, pushdf using integers can be still shorter. Allow this
2850 ;; pattern for optimize_size too.
2852 (define_insn "*pushdf_nointeger"
2853 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2854 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2855 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2857 /* This insn should be already split before reg-stack. */
2860 [(set_attr "type" "multi")
2861 (set_attr "unit" "i387,*,*,*")
2862 (set_attr "mode" "DF,SI,SI,DF")])
2864 (define_insn "*pushdf_integer"
2865 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2866 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2867 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2869 /* This insn should be already split before reg-stack. */
2872 [(set_attr "type" "multi")
2873 (set_attr "unit" "i387,*,*")
2874 (set_attr "mode" "DF,SI,DF")])
2876 ;; %%% Kill this when call knows how to work this out.
2878 [(set (match_operand:DF 0 "push_operand" "")
2879 (match_operand:DF 1 "any_fp_register_operand" ""))]
2881 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2882 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2886 [(set (match_operand:DF 0 "push_operand" "")
2887 (match_operand:DF 1 "general_operand" ""))]
2890 "ix86_split_long_move (operands); DONE;")
2892 ;; Moving is usually shorter when only FP registers are used. This separate
2893 ;; movdf pattern avoids the use of integer registers for FP operations
2894 ;; when optimizing for size.
2896 (define_insn "*movdf_nointeger"
2897 [(set (match_operand:DF 0 "nonimmediate_operand"
2898 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2899 (match_operand:DF 1 "general_operand"
2900 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2901 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2902 && ((optimize_function_for_size_p (cfun)
2903 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2904 && (reload_in_progress || reload_completed
2905 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2907 && optimize_function_for_size_p (cfun)
2908 && !memory_operand (operands[0], DFmode)
2909 && standard_80387_constant_p (operands[1]))
2910 || GET_CODE (operands[1]) != CONST_DOUBLE
2911 || ((optimize_function_for_size_p (cfun)
2912 || !TARGET_MEMORY_MISMATCH_STALL
2913 || reload_in_progress || reload_completed)
2914 && memory_operand (operands[0], DFmode)))"
2916 switch (which_alternative)
2920 return output_387_reg_move (insn, operands);
2923 return standard_80387_constant_opcode (operands[1]);
2929 switch (get_attr_mode (insn))
2932 return "%vxorps\t%0, %d0";
2934 return "%vxorpd\t%0, %d0";
2936 return "%vpxor\t%0, %d0";
2943 switch (get_attr_mode (insn))
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovapd\t{%1, %0|%0, %1}";
2950 return "%vmovdqa\t{%1, %0|%0, %1}";
2952 return "%vmovq\t{%1, %0|%0, %1}";
2956 if (REG_P (operands[0]) && REG_P (operands[1]))
2957 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2959 return "vmovsd\t{%1, %0|%0, %1}";
2962 return "movsd\t{%1, %0|%0, %1}";
2966 if (REG_P (operands[0]))
2967 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2969 return "vmovlpd\t{%1, %0|%0, %1}";
2972 return "movlpd\t{%1, %0|%0, %1}";
2976 if (REG_P (operands[0]))
2977 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2979 return "vmovlps\t{%1, %0|%0, %1}";
2982 return "movlps\t{%1, %0|%0, %1}";
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2992 (set (attr "prefix")
2993 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2994 (const_string "orig")
2995 (const_string "maybe_vex")))
2997 (cond [(eq_attr "alternative" "0,1,2")
2999 (eq_attr "alternative" "3,4")
3002 /* For SSE1, we have many fewer alternatives. */
3003 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004 (cond [(eq_attr "alternative" "5,6")
3005 (const_string "V4SF")
3007 (const_string "V2SF"))
3009 /* xorps is one byte shorter. */
3010 (eq_attr "alternative" "5")
3011 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3013 (const_string "V4SF")
3014 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3018 (const_string "V2DF"))
3020 /* For architectures resolving dependencies on
3021 whole SSE registers use APD move to break dependency
3022 chains, otherwise use short move to avoid extra work.
3024 movaps encodes one byte shorter. */
3025 (eq_attr "alternative" "6")
3027 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3029 (const_string "V4SF")
3030 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3032 (const_string "V2DF")
3034 (const_string "DF"))
3035 /* For architectures resolving dependencies on register
3036 parts we may avoid extra work to zero out upper part
3038 (eq_attr "alternative" "7")
3040 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3042 (const_string "V1DF")
3043 (const_string "DF"))
3045 (const_string "DF")))])
3047 (define_insn "*movdf_integer_rex64"
3048 [(set (match_operand:DF 0 "nonimmediate_operand"
3049 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3050 (match_operand:DF 1 "general_operand"
3051 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3052 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053 && (reload_in_progress || reload_completed
3054 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3055 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3056 && optimize_function_for_size_p (cfun)
3057 && standard_80387_constant_p (operands[1]))
3058 || GET_CODE (operands[1]) != CONST_DOUBLE
3059 || memory_operand (operands[0], DFmode))"
3061 switch (which_alternative)
3065 return output_387_reg_move (insn, operands);
3068 return standard_80387_constant_opcode (operands[1]);
3075 switch (get_attr_mode (insn))
3078 return "%vxorps\t%0, %d0";
3080 return "%vxorpd\t%0, %d0";
3082 return "%vpxor\t%0, %d0";
3089 switch (get_attr_mode (insn))
3092 return "%vmovaps\t{%1, %0|%0, %1}";
3094 return "%vmovapd\t{%1, %0|%0, %1}";
3096 return "%vmovdqa\t{%1, %0|%0, %1}";
3098 return "%vmovq\t{%1, %0|%0, %1}";
3102 if (REG_P (operands[0]) && REG_P (operands[1]))
3103 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3105 return "vmovsd\t{%1, %0|%0, %1}";
3108 return "movsd\t{%1, %0|%0, %1}";
3110 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3112 return "%vmovlps\t{%1, %d0|%d0, %1}";
3119 return "%vmovd\t{%1, %0|%0, %1}";
3125 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3126 (set (attr "prefix")
3127 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3128 (const_string "orig")
3129 (const_string "maybe_vex")))
3131 (cond [(eq_attr "alternative" "0,1,2")
3133 (eq_attr "alternative" "3,4,9,10")
3136 /* For SSE1, we have many fewer alternatives. */
3137 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138 (cond [(eq_attr "alternative" "5,6")
3139 (const_string "V4SF")
3141 (const_string "V2SF"))
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5")
3145 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3147 (const_string "V4SF")
3148 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3152 (const_string "V2DF"))
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6")
3161 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3163 (const_string "V4SF")
3164 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3166 (const_string "V2DF")
3168 (const_string "DF"))
3169 /* For architectures resolving dependencies on register
3170 parts we may avoid extra work to zero out upper part
3172 (eq_attr "alternative" "7")
3174 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3176 (const_string "V1DF")
3177 (const_string "DF"))
3179 (const_string "DF")))])
3181 (define_insn "*movdf_integer"
3182 [(set (match_operand:DF 0 "nonimmediate_operand"
3183 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3184 (match_operand:DF 1 "general_operand"
3185 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3187 && optimize_function_for_speed_p (cfun)
3188 && TARGET_INTEGER_DFMODE_MOVES
3189 && (reload_in_progress || reload_completed
3190 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3191 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3192 && optimize_function_for_size_p (cfun)
3193 && standard_80387_constant_p (operands[1]))
3194 || GET_CODE (operands[1]) != CONST_DOUBLE
3195 || memory_operand (operands[0], DFmode))"
3197 switch (which_alternative)
3201 return output_387_reg_move (insn, operands);
3204 return standard_80387_constant_opcode (operands[1]);
3211 switch (get_attr_mode (insn))
3214 return "xorps\t%0, %0";
3216 return "xorpd\t%0, %0";
3218 return "pxor\t%0, %0";
3225 switch (get_attr_mode (insn))
3228 return "movaps\t{%1, %0|%0, %1}";
3230 return "movapd\t{%1, %0|%0, %1}";
3232 return "movdqa\t{%1, %0|%0, %1}";
3234 return "movq\t{%1, %0|%0, %1}";
3236 return "movsd\t{%1, %0|%0, %1}";
3238 return "movlpd\t{%1, %0|%0, %1}";
3240 return "movlps\t{%1, %0|%0, %1}";
3249 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3251 (cond [(eq_attr "alternative" "0,1,2")
3253 (eq_attr "alternative" "3,4")
3256 /* For SSE1, we have many fewer alternatives. */
3257 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3258 (cond [(eq_attr "alternative" "5,6")
3259 (const_string "V4SF")
3261 (const_string "V2SF"))
3263 /* xorps is one byte shorter. */
3264 (eq_attr "alternative" "5")
3265 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3267 (const_string "V4SF")
3268 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3272 (const_string "V2DF"))
3274 /* For architectures resolving dependencies on
3275 whole SSE registers use APD move to break dependency
3276 chains, otherwise use short move to avoid extra work.
3278 movaps encodes one byte shorter. */
3279 (eq_attr "alternative" "6")
3281 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3283 (const_string "V4SF")
3284 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3286 (const_string "V2DF")
3288 (const_string "DF"))
3289 /* For architectures resolving dependencies on register
3290 parts we may avoid extra work to zero out upper part
3292 (eq_attr "alternative" "7")
3294 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3296 (const_string "V1DF")
3297 (const_string "DF"))
3299 (const_string "DF")))])
3302 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3303 (match_operand:DF 1 "general_operand" ""))]
3305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3306 && ! (ANY_FP_REG_P (operands[0]) ||
3307 (GET_CODE (operands[0]) == SUBREG
3308 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3309 && ! (ANY_FP_REG_P (operands[1]) ||
3310 (GET_CODE (operands[1]) == SUBREG
3311 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3313 "ix86_split_long_move (operands); DONE;")
3315 (define_insn "*swapdf"
3316 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3317 (match_operand:DF 1 "fp_register_operand" "+f"))
3320 "reload_completed || TARGET_80387"
3322 if (STACK_TOP_P (operands[0]))
3327 [(set_attr "type" "fxch")
3328 (set_attr "mode" "DF")])
3330 (define_expand "movxf"
3331 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3332 (match_operand:XF 1 "general_operand" ""))]
3334 "ix86_expand_move (XFmode, operands); DONE;")
3336 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3337 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3338 ;; Pushing using integer instructions is longer except for constants
3339 ;; and direct memory references.
3340 ;; (assuming that any given constant is pushed only once, but this ought to be
3341 ;; handled elsewhere).
3343 (define_insn "*pushxf_nointeger"
3344 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3345 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3346 "optimize_function_for_size_p (cfun)"
3348 /* This insn should be already split before reg-stack. */
3351 [(set_attr "type" "multi")
3352 (set_attr "unit" "i387,*,*")
3353 (set_attr "mode" "XF,SI,SI")])
3355 (define_insn "*pushxf_integer"
3356 [(set (match_operand:XF 0 "push_operand" "=<,<")
3357 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3358 "optimize_function_for_speed_p (cfun)"
3360 /* This insn should be already split before reg-stack. */
3363 [(set_attr "type" "multi")
3364 (set_attr "unit" "i387,*")
3365 (set_attr "mode" "XF,SI")])
3368 [(set (match_operand 0 "push_operand" "")
3369 (match_operand 1 "general_operand" ""))]
3371 && (GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode)
3373 && !ANY_FP_REG_P (operands[1])"
3375 "ix86_split_long_move (operands); DONE;")
3378 [(set (match_operand:XF 0 "push_operand" "")
3379 (match_operand:XF 1 "any_fp_register_operand" ""))]
3381 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3382 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3383 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3385 ;; Do not use integer registers when optimizing for size
3386 (define_insn "*movxf_nointeger"
3387 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3388 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3389 "optimize_function_for_size_p (cfun)
3390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3391 && (reload_in_progress || reload_completed
3392 || standard_80387_constant_p (operands[1])
3393 || GET_CODE (operands[1]) != CONST_DOUBLE
3394 || memory_operand (operands[0], XFmode))"
3396 switch (which_alternative)
3400 return output_387_reg_move (insn, operands);
3403 return standard_80387_constant_opcode (operands[1]);
3411 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3412 (set_attr "mode" "XF,XF,XF,SI,SI")])
3414 (define_insn "*movxf_integer"
3415 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3416 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3417 "optimize_function_for_speed_p (cfun)
3418 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3419 && (reload_in_progress || reload_completed
3420 || GET_CODE (operands[1]) != CONST_DOUBLE
3421 || memory_operand (operands[0], XFmode))"
3423 switch (which_alternative)
3427 return output_387_reg_move (insn, operands);
3430 return standard_80387_constant_opcode (operands[1]);
3439 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3440 (set_attr "mode" "XF,XF,XF,SI,SI")])
3442 (define_expand "movtf"
3443 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444 (match_operand:TF 1 "nonimmediate_operand" ""))]
3447 ix86_expand_move (TFmode, operands);
3451 (define_insn "*movtf_internal"
3452 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3453 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3457 switch (which_alternative)
3461 if (get_attr_mode (insn) == MODE_V4SF)
3462 return "%vmovaps\t{%1, %0|%0, %1}";
3464 return "%vmovdqa\t{%1, %0|%0, %1}";
3466 if (get_attr_mode (insn) == MODE_V4SF)
3467 return "%vxorps\t%0, %d0";
3469 return "%vpxor\t%0, %d0";
3477 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3478 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3480 (cond [(eq_attr "alternative" "0,2")
3482 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3484 (const_string "V4SF")
3485 (const_string "TI"))
3486 (eq_attr "alternative" "1")
3488 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3490 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3492 (const_string "V4SF")
3493 (const_string "TI"))]
3494 (const_string "DI")))])
3496 (define_insn "*pushtf_sse"
3497 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3498 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3501 /* This insn should be already split before reg-stack. */
3504 [(set_attr "type" "multi")
3505 (set_attr "unit" "sse,*,*")
3506 (set_attr "mode" "TF,SI,SI")])
3509 [(set (match_operand:TF 0 "push_operand" "")
3510 (match_operand:TF 1 "general_operand" ""))]
3511 "TARGET_SSE2 && reload_completed
3512 && !SSE_REG_P (operands[1])"
3514 "ix86_split_long_move (operands); DONE;")
3517 [(set (match_operand:TF 0 "push_operand" "")
3518 (match_operand:TF 1 "any_fp_register_operand" ""))]
3520 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3521 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3525 [(set (match_operand 0 "nonimmediate_operand" "")
3526 (match_operand 1 "general_operand" ""))]
3528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529 && GET_MODE (operands[0]) == XFmode
3530 && ! (ANY_FP_REG_P (operands[0]) ||
3531 (GET_CODE (operands[0]) == SUBREG
3532 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3533 && ! (ANY_FP_REG_P (operands[1]) ||
3534 (GET_CODE (operands[1]) == SUBREG
3535 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3537 "ix86_split_long_move (operands); DONE;")
3540 [(set (match_operand 0 "register_operand" "")
3541 (match_operand 1 "memory_operand" ""))]
3543 && MEM_P (operands[1])
3544 && (GET_MODE (operands[0]) == TFmode
3545 || GET_MODE (operands[0]) == XFmode
3546 || GET_MODE (operands[0]) == SFmode
3547 || GET_MODE (operands[0]) == DFmode)
3548 && (operands[2] = find_constant_src (insn))"
3549 [(set (match_dup 0) (match_dup 2))]
3551 rtx c = operands[2];
3552 rtx r = operands[0];
3554 if (GET_CODE (r) == SUBREG)
3559 if (!standard_sse_constant_p (c))
3562 else if (FP_REG_P (r))
3564 if (!standard_80387_constant_p (c))
3567 else if (MMX_REG_P (r))
3572 [(set (match_operand 0 "register_operand" "")
3573 (float_extend (match_operand 1 "memory_operand" "")))]
3575 && MEM_P (operands[1])
3576 && (GET_MODE (operands[0]) == TFmode
3577 || GET_MODE (operands[0]) == XFmode
3578 || GET_MODE (operands[0]) == SFmode
3579 || GET_MODE (operands[0]) == DFmode)
3580 && (operands[2] = find_constant_src (insn))"
3581 [(set (match_dup 0) (match_dup 2))]
3583 rtx c = operands[2];
3584 rtx r = operands[0];
3586 if (GET_CODE (r) == SUBREG)
3591 if (!standard_sse_constant_p (c))
3594 else if (FP_REG_P (r))
3596 if (!standard_80387_constant_p (c))
3599 else if (MMX_REG_P (r))
3603 (define_insn "swapxf"
3604 [(set (match_operand:XF 0 "register_operand" "+f")
3605 (match_operand:XF 1 "register_operand" "+f"))
3610 if (STACK_TOP_P (operands[0]))
3615 [(set_attr "type" "fxch")
3616 (set_attr "mode" "XF")])
3618 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3620 [(set (match_operand:X87MODEF 0 "register_operand" "")
3621 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3622 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3623 && (standard_80387_constant_p (operands[1]) == 8
3624 || standard_80387_constant_p (operands[1]) == 9)"
3625 [(set (match_dup 0)(match_dup 1))
3627 (neg:X87MODEF (match_dup 0)))]
3631 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3632 if (real_isnegzero (&r))
3633 operands[1] = CONST0_RTX (<MODE>mode);
3635 operands[1] = CONST1_RTX (<MODE>mode);
3639 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3640 (match_operand:TF 1 "general_operand" ""))]
3642 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3644 "ix86_split_long_move (operands); DONE;")
3646 ;; Zero extension instructions
3648 (define_expand "zero_extendhisi2"
3649 [(set (match_operand:SI 0 "register_operand" "")
3650 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3653 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3655 operands[1] = force_reg (HImode, operands[1]);
3656 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3661 (define_insn "zero_extendhisi2_and"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664 (clobber (reg:CC FLAGS_REG))]
3665 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3667 [(set_attr "type" "alu1")
3668 (set_attr "mode" "SI")])
3671 [(set (match_operand:SI 0 "register_operand" "")
3672 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3673 (clobber (reg:CC FLAGS_REG))]
3674 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3675 && optimize_function_for_speed_p (cfun)"
3676 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3677 (clobber (reg:CC FLAGS_REG))])]
3680 (define_insn "*zero_extendhisi2_movzwl"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "!TARGET_ZERO_EXTEND_WITH_AND
3684 || optimize_function_for_size_p (cfun)"
3685 "movz{wl|x}\t{%1, %0|%0, %1}"
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "SI")])
3689 (define_expand "zero_extendqihi2"
3691 [(set (match_operand:HI 0 "register_operand" "")
3692 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3693 (clobber (reg:CC FLAGS_REG))])]
3697 (define_insn "*zero_extendqihi2_and"
3698 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3699 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700 (clobber (reg:CC FLAGS_REG))]
3701 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3703 [(set_attr "type" "alu1")
3704 (set_attr "mode" "HI")])
3706 (define_insn "*zero_extendqihi2_movzbw_and"
3707 [(set (match_operand:HI 0 "register_operand" "=r,r")
3708 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3709 (clobber (reg:CC FLAGS_REG))]
3710 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3712 [(set_attr "type" "imovx,alu1")
3713 (set_attr "mode" "HI")])
3715 ; zero extend to SImode here to avoid partial register stalls
3716 (define_insn "*zero_extendqihi2_movzbl"
3717 [(set (match_operand:HI 0 "register_operand" "=r")
3718 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3719 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3720 && reload_completed"
3721 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")])
3725 ;; For the movzbw case strip only the clobber
3727 [(set (match_operand:HI 0 "register_operand" "")
3728 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))]
3731 && (!TARGET_ZERO_EXTEND_WITH_AND
3732 || optimize_function_for_size_p (cfun))
3733 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734 [(set (match_operand:HI 0 "register_operand" "")
3735 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3737 ;; When source and destination does not overlap, clear destination
3738 ;; first and then do the movb
3740 [(set (match_operand:HI 0 "register_operand" "")
3741 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3742 (clobber (reg:CC FLAGS_REG))]
3744 && ANY_QI_REG_P (operands[0])
3745 && (TARGET_ZERO_EXTEND_WITH_AND
3746 && optimize_function_for_speed_p (cfun))
3747 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3748 [(set (match_dup 0) (const_int 0))
3749 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3750 "operands[2] = gen_lowpart (QImode, operands[0]);")
3752 ;; Rest is handled by single and.
3754 [(set (match_operand:HI 0 "register_operand" "")
3755 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3756 (clobber (reg:CC FLAGS_REG))]
3758 && true_regnum (operands[0]) == true_regnum (operands[1])"
3759 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3760 (clobber (reg:CC FLAGS_REG))])]
3763 (define_expand "zero_extendqisi2"
3765 [(set (match_operand:SI 0 "register_operand" "")
3766 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3767 (clobber (reg:CC FLAGS_REG))])]
3771 (define_insn "*zero_extendqisi2_and"
3772 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3773 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3774 (clobber (reg:CC FLAGS_REG))]
3775 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3777 [(set_attr "type" "alu1")
3778 (set_attr "mode" "SI")])
3780 (define_insn "*zero_extendqisi2_movzbw_and"
3781 [(set (match_operand:SI 0 "register_operand" "=r,r")
3782 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3783 (clobber (reg:CC FLAGS_REG))]
3784 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3786 [(set_attr "type" "imovx,alu1")
3787 (set_attr "mode" "SI")])
3789 (define_insn "*zero_extendqisi2_movzbw"
3790 [(set (match_operand:SI 0 "register_operand" "=r")
3791 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3792 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793 && reload_completed"
3794 "movz{bl|x}\t{%1, %0|%0, %1}"
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "SI")])
3798 ;; For the movzbl case strip only the clobber
3800 [(set (match_operand:SI 0 "register_operand" "")
3801 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3802 (clobber (reg:CC FLAGS_REG))]
3804 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3805 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3807 (zero_extend:SI (match_dup 1)))])
3809 ;; When source and destination does not overlap, clear destination
3810 ;; first and then do the movb
3812 [(set (match_operand:SI 0 "register_operand" "")
3813 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3814 (clobber (reg:CC FLAGS_REG))]
3816 && ANY_QI_REG_P (operands[0])
3817 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3818 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3819 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3820 [(set (match_dup 0) (const_int 0))
3821 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3822 "operands[2] = gen_lowpart (QImode, operands[0]);")
3824 ;; Rest is handled by single and.
3826 [(set (match_operand:SI 0 "register_operand" "")
3827 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3828 (clobber (reg:CC FLAGS_REG))]
3830 && true_regnum (operands[0]) == true_regnum (operands[1])"
3831 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3832 (clobber (reg:CC FLAGS_REG))])]
3835 ;; %%% Kill me once multi-word ops are sane.
3836 (define_expand "zero_extendsidi2"
3837 [(set (match_operand:DI 0 "register_operand" "")
3838 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3843 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3848 (define_insn "zero_extendsidi2_32"
3849 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3851 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3852 (clobber (reg:CC FLAGS_REG))]
3858 movd\t{%1, %0|%0, %1}
3859 movd\t{%1, %0|%0, %1}
3860 %vmovd\t{%1, %0|%0, %1}
3861 %vmovd\t{%1, %0|%0, %1}"
3862 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3863 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3864 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3866 (define_insn "zero_extendsidi2_rex64"
3867 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3869 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3872 mov\t{%k1, %k0|%k0, %k1}
3874 movd\t{%1, %0|%0, %1}
3875 movd\t{%1, %0|%0, %1}
3876 %vmovd\t{%1, %0|%0, %1}
3877 %vmovd\t{%1, %0|%0, %1}"
3878 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3879 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3880 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3883 [(set (match_operand:DI 0 "memory_operand" "")
3884 (zero_extend:DI (match_dup 0)))]
3886 [(set (match_dup 4) (const_int 0))]
3887 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3890 [(set (match_operand:DI 0 "register_operand" "")
3891 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3892 (clobber (reg:CC FLAGS_REG))]
3893 "!TARGET_64BIT && reload_completed
3894 && true_regnum (operands[0]) == true_regnum (operands[1])"
3895 [(set (match_dup 4) (const_int 0))]
3896 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3899 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3900 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3901 (clobber (reg:CC FLAGS_REG))]
3902 "!TARGET_64BIT && reload_completed
3903 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3904 [(set (match_dup 3) (match_dup 1))
3905 (set (match_dup 4) (const_int 0))]
3906 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3908 (define_insn "zero_extendhidi2"
3909 [(set (match_operand:DI 0 "register_operand" "=r")
3910 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3912 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3913 [(set_attr "type" "imovx")
3914 (set_attr "mode" "DI")])
3916 (define_insn "zero_extendqidi2"
3917 [(set (match_operand:DI 0 "register_operand" "=r")
3918 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3920 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3921 [(set_attr "type" "imovx")
3922 (set_attr "mode" "DI")])
3924 ;; Sign extension instructions
3926 (define_expand "extendsidi2"
3927 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3928 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3929 (clobber (reg:CC FLAGS_REG))
3930 (clobber (match_scratch:SI 2 ""))])]
3935 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3940 (define_insn "*extendsidi2_1"
3941 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3942 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3943 (clobber (reg:CC FLAGS_REG))
3944 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3948 (define_insn "extendsidi2_rex64"
3949 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3950 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3954 movs{lq|x}\t{%1,%0|%0, %1}"
3955 [(set_attr "type" "imovx")
3956 (set_attr "mode" "DI")
3957 (set_attr "prefix_0f" "0")
3958 (set_attr "modrm" "0,1")])
3960 (define_insn "extendhidi2"
3961 [(set (match_operand:DI 0 "register_operand" "=r")
3962 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3964 "movs{wq|x}\t{%1,%0|%0, %1}"
3965 [(set_attr "type" "imovx")
3966 (set_attr "mode" "DI")])
3968 (define_insn "extendqidi2"
3969 [(set (match_operand:DI 0 "register_operand" "=r")
3970 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3972 "movs{bq|x}\t{%1,%0|%0, %1}"
3973 [(set_attr "type" "imovx")
3974 (set_attr "mode" "DI")])
3976 ;; Extend to memory case when source register does die.
3978 [(set (match_operand:DI 0 "memory_operand" "")
3979 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3980 (clobber (reg:CC FLAGS_REG))
3981 (clobber (match_operand:SI 2 "register_operand" ""))]
3983 && dead_or_set_p (insn, operands[1])
3984 && !reg_mentioned_p (operands[1], operands[0]))"
3985 [(set (match_dup 3) (match_dup 1))
3986 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3987 (clobber (reg:CC FLAGS_REG))])
3988 (set (match_dup 4) (match_dup 1))]
3989 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3991 ;; Extend to memory case when source register does not die.
3993 [(set (match_operand:DI 0 "memory_operand" "")
3994 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3995 (clobber (reg:CC FLAGS_REG))
3996 (clobber (match_operand:SI 2 "register_operand" ""))]
4000 split_di (&operands[0], 1, &operands[3], &operands[4]);
4002 emit_move_insn (operands[3], operands[1]);
4004 /* Generate a cltd if possible and doing so it profitable. */
4005 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4006 && true_regnum (operands[1]) == AX_REG
4007 && true_regnum (operands[2]) == DX_REG)
4009 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4013 emit_move_insn (operands[2], operands[1]);
4014 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4016 emit_move_insn (operands[4], operands[2]);
4020 ;; Extend to register case. Optimize case where source and destination
4021 ;; registers match and cases where we can use cltd.
4023 [(set (match_operand:DI 0 "register_operand" "")
4024 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))
4026 (clobber (match_scratch:SI 2 ""))]
4030 split_di (&operands[0], 1, &operands[3], &operands[4]);
4032 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4033 emit_move_insn (operands[3], operands[1]);
4035 /* Generate a cltd if possible and doing so it profitable. */
4036 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4037 && true_regnum (operands[3]) == AX_REG)
4039 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4043 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044 emit_move_insn (operands[4], operands[1]);
4046 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4050 (define_insn "extendhisi2"
4051 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4052 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4055 switch (get_attr_prefix_0f (insn))
4058 return "{cwtl|cwde}";
4060 return "movs{wl|x}\t{%1,%0|%0, %1}";
4063 [(set_attr "type" "imovx")
4064 (set_attr "mode" "SI")
4065 (set (attr "prefix_0f")
4066 ;; movsx is short decodable while cwtl is vector decoded.
4067 (if_then_else (and (eq_attr "cpu" "!k6")
4068 (eq_attr "alternative" "0"))
4070 (const_string "1")))
4072 (if_then_else (eq_attr "prefix_0f" "0")
4074 (const_string "1")))])
4076 (define_insn "*extendhisi2_zext"
4077 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4079 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4082 switch (get_attr_prefix_0f (insn))
4085 return "{cwtl|cwde}";
4087 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4090 [(set_attr "type" "imovx")
4091 (set_attr "mode" "SI")
4092 (set (attr "prefix_0f")
4093 ;; movsx is short decodable while cwtl is vector decoded.
4094 (if_then_else (and (eq_attr "cpu" "!k6")
4095 (eq_attr "alternative" "0"))
4097 (const_string "1")))
4099 (if_then_else (eq_attr "prefix_0f" "0")
4101 (const_string "1")))])
4103 (define_insn "extendqihi2"
4104 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4105 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4108 switch (get_attr_prefix_0f (insn))
4111 return "{cbtw|cbw}";
4113 return "movs{bw|x}\t{%1,%0|%0, %1}";
4116 [(set_attr "type" "imovx")
4117 (set_attr "mode" "HI")
4118 (set (attr "prefix_0f")
4119 ;; movsx is short decodable while cwtl is vector decoded.
4120 (if_then_else (and (eq_attr "cpu" "!k6")
4121 (eq_attr "alternative" "0"))
4123 (const_string "1")))
4125 (if_then_else (eq_attr "prefix_0f" "0")
4127 (const_string "1")))])
4129 (define_insn "extendqisi2"
4130 [(set (match_operand:SI 0 "register_operand" "=r")
4131 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4133 "movs{bl|x}\t{%1,%0|%0, %1}"
4134 [(set_attr "type" "imovx")
4135 (set_attr "mode" "SI")])
4137 (define_insn "*extendqisi2_zext"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4140 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4142 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4143 [(set_attr "type" "imovx")
4144 (set_attr "mode" "SI")])
4146 ;; Conversions between float and double.
4148 ;; These are all no-ops in the model used for the 80387. So just
4151 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4152 (define_insn "*dummy_extendsfdf2"
4153 [(set (match_operand:DF 0 "push_operand" "=<")
4154 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4159 [(set (match_operand:DF 0 "push_operand" "")
4160 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4162 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4163 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4165 (define_insn "*dummy_extendsfxf2"
4166 [(set (match_operand:XF 0 "push_operand" "=<")
4167 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4172 [(set (match_operand:XF 0 "push_operand" "")
4173 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4175 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4176 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4177 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4180 [(set (match_operand:XF 0 "push_operand" "")
4181 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4183 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4184 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4185 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4187 (define_expand "extendsfdf2"
4188 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4189 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4190 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4192 /* ??? Needed for compress_float_constant since all fp constants
4193 are LEGITIMATE_CONSTANT_P. */
4194 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4196 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4197 && standard_80387_constant_p (operands[1]) > 0)
4199 operands[1] = simplify_const_unary_operation
4200 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4201 emit_move_insn_1 (operands[0], operands[1]);
4204 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4210 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4212 We do the conversion post reload to avoid producing of 128bit spills
4213 that might lead to ICE on 32bit target. The sequence unlikely combine
4216 [(set (match_operand:DF 0 "register_operand" "")
4218 (match_operand:SF 1 "nonimmediate_operand" "")))]
4219 "TARGET_USE_VECTOR_FP_CONVERTS
4220 && optimize_insn_for_speed_p ()
4221 && reload_completed && SSE_REG_P (operands[0])"
4226 (parallel [(const_int 0) (const_int 1)]))))]
4228 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4229 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4230 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4231 Try to avoid move when unpacking can be done in source. */
4232 if (REG_P (operands[1]))
4234 /* If it is unsafe to overwrite upper half of source, we need
4235 to move to destination and unpack there. */
4236 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4237 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4238 && true_regnum (operands[0]) != true_regnum (operands[1]))
4240 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4241 emit_move_insn (tmp, operands[1]);
4244 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4245 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4248 emit_insn (gen_vec_setv4sf_0 (operands[3],
4249 CONST0_RTX (V4SFmode), operands[1]));
4252 (define_insn "*extendsfdf2_mixed"
4253 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4255 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4256 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4258 switch (which_alternative)
4262 return output_387_reg_move (insn, operands);
4265 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4271 [(set_attr "type" "fmov,fmov,ssecvt")
4272 (set_attr "prefix" "orig,orig,maybe_vex")
4273 (set_attr "mode" "SF,XF,DF")])
4275 (define_insn "*extendsfdf2_sse"
4276 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4277 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4278 "TARGET_SSE2 && TARGET_SSE_MATH"
4279 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4280 [(set_attr "type" "ssecvt")
4281 (set_attr "prefix" "maybe_vex")
4282 (set_attr "mode" "DF")])
4284 (define_insn "*extendsfdf2_i387"
4285 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4286 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4288 "* return output_387_reg_move (insn, operands);"
4289 [(set_attr "type" "fmov")
4290 (set_attr "mode" "SF,XF")])
4292 (define_expand "extend<mode>xf2"
4293 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4294 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4297 /* ??? Needed for compress_float_constant since all fp constants
4298 are LEGITIMATE_CONSTANT_P. */
4299 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4301 if (standard_80387_constant_p (operands[1]) > 0)
4303 operands[1] = simplify_const_unary_operation
4304 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4305 emit_move_insn_1 (operands[0], operands[1]);
4308 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4312 (define_insn "*extend<mode>xf2_i387"
4313 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4315 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4317 "* return output_387_reg_move (insn, operands);"
4318 [(set_attr "type" "fmov")
4319 (set_attr "mode" "<MODE>,XF")])
4321 ;; %%% This seems bad bad news.
4322 ;; This cannot output into an f-reg because there is no way to be sure
4323 ;; of truncating in that case. Otherwise this is just like a simple move
4324 ;; insn. So we pretend we can output to a reg in order to get better
4325 ;; register preferencing, but we really use a stack slot.
4327 ;; Conversion from DFmode to SFmode.
4329 (define_expand "truncdfsf2"
4330 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4332 (match_operand:DF 1 "nonimmediate_operand" "")))]
4333 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4335 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4337 else if (flag_unsafe_math_optimizations)
4341 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4342 rtx temp = assign_386_stack_local (SFmode, slot);
4343 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4348 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4350 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4352 We do the conversion post reload to avoid producing of 128bit spills
4353 that might lead to ICE on 32bit target. The sequence unlikely combine
4356 [(set (match_operand:SF 0 "register_operand" "")
4358 (match_operand:DF 1 "nonimmediate_operand" "")))]
4359 "TARGET_USE_VECTOR_FP_CONVERTS
4360 && optimize_insn_for_speed_p ()
4361 && reload_completed && SSE_REG_P (operands[0])"
4364 (float_truncate:V2SF
4368 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4369 operands[3] = CONST0_RTX (V2SFmode);
4370 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4371 /* Use movsd for loading from memory, unpcklpd for registers.
4372 Try to avoid move when unpacking can be done in source, or SSE3
4373 movddup is available. */
4374 if (REG_P (operands[1]))
4377 && true_regnum (operands[0]) != true_regnum (operands[1])
4378 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4381 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4382 emit_move_insn (tmp, operands[1]);
4385 else if (!TARGET_SSE3)
4386 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4387 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4390 emit_insn (gen_sse2_loadlpd (operands[4],
4391 CONST0_RTX (V2DFmode), operands[1]));
4394 (define_expand "truncdfsf2_with_temp"
4395 [(parallel [(set (match_operand:SF 0 "" "")
4396 (float_truncate:SF (match_operand:DF 1 "" "")))
4397 (clobber (match_operand:SF 2 "" ""))])]
4400 (define_insn "*truncdfsf_fast_mixed"
4401 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4403 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4404 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4406 switch (which_alternative)
4409 return output_387_reg_move (insn, operands);
4411 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4416 [(set_attr "type" "fmov,ssecvt")
4417 (set_attr "prefix" "orig,maybe_vex")
4418 (set_attr "mode" "SF")])
4420 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4421 ;; because nothing we do here is unsafe.
4422 (define_insn "*truncdfsf_fast_sse"
4423 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4425 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4426 "TARGET_SSE2 && TARGET_SSE_MATH"
4427 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4428 [(set_attr "type" "ssecvt")
4429 (set_attr "prefix" "maybe_vex")
4430 (set_attr "mode" "SF")])
4432 (define_insn "*truncdfsf_fast_i387"
4433 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4435 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4436 "TARGET_80387 && flag_unsafe_math_optimizations"
4437 "* return output_387_reg_move (insn, operands);"
4438 [(set_attr "type" "fmov")
4439 (set_attr "mode" "SF")])
4441 (define_insn "*truncdfsf_mixed"
4442 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4444 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4445 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4446 "TARGET_MIX_SSE_I387"
4448 switch (which_alternative)
4451 return output_387_reg_move (insn, operands);
4456 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4461 [(set_attr "type" "fmov,multi,ssecvt")
4462 (set_attr "unit" "*,i387,*")
4463 (set_attr "prefix" "orig,orig,maybe_vex")
4464 (set_attr "mode" "SF")])
4466 (define_insn "*truncdfsf_i387"
4467 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4469 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4470 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4473 switch (which_alternative)
4476 return output_387_reg_move (insn, operands);
4484 [(set_attr "type" "fmov,multi")
4485 (set_attr "unit" "*,i387")
4486 (set_attr "mode" "SF")])
4488 (define_insn "*truncdfsf2_i387_1"
4489 [(set (match_operand:SF 0 "memory_operand" "=m")
4491 (match_operand:DF 1 "register_operand" "f")))]
4493 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4494 && !TARGET_MIX_SSE_I387"
4495 "* return output_387_reg_move (insn, operands);"
4496 [(set_attr "type" "fmov")
4497 (set_attr "mode" "SF")])
4500 [(set (match_operand:SF 0 "register_operand" "")
4502 (match_operand:DF 1 "fp_register_operand" "")))
4503 (clobber (match_operand 2 "" ""))]
4505 [(set (match_dup 2) (match_dup 1))
4506 (set (match_dup 0) (match_dup 2))]
4508 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4511 ;; Conversion from XFmode to {SF,DF}mode
4513 (define_expand "truncxf<mode>2"
4514 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4515 (float_truncate:MODEF
4516 (match_operand:XF 1 "register_operand" "")))
4517 (clobber (match_dup 2))])]
4520 if (flag_unsafe_math_optimizations)
4522 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4523 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4524 if (reg != operands[0])
4525 emit_move_insn (operands[0], reg);
4530 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4531 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4535 (define_insn "*truncxfsf2_mixed"
4536 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4538 (match_operand:XF 1 "register_operand" "f,f")))
4539 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4542 gcc_assert (!which_alternative);
4543 return output_387_reg_move (insn, operands);
4545 [(set_attr "type" "fmov,multi")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "mode" "SF")])
4549 (define_insn "*truncxfdf2_mixed"
4550 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4552 (match_operand:XF 1 "register_operand" "f,f")))
4553 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4556 gcc_assert (!which_alternative);
4557 return output_387_reg_move (insn, operands);
4559 [(set_attr "type" "fmov,multi")
4560 (set_attr "unit" "*,i387")
4561 (set_attr "mode" "DF")])
4563 (define_insn "truncxf<mode>2_i387_noop"
4564 [(set (match_operand:MODEF 0 "register_operand" "=f")
4565 (float_truncate:MODEF
4566 (match_operand:XF 1 "register_operand" "f")))]
4567 "TARGET_80387 && flag_unsafe_math_optimizations"
4568 "* return output_387_reg_move (insn, operands);"
4569 [(set_attr "type" "fmov")
4570 (set_attr "mode" "<MODE>")])
4572 (define_insn "*truncxf<mode>2_i387"
4573 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4574 (float_truncate:MODEF
4575 (match_operand:XF 1 "register_operand" "f")))]
4577 "* return output_387_reg_move (insn, operands);"
4578 [(set_attr "type" "fmov")
4579 (set_attr "mode" "<MODE>")])
4582 [(set (match_operand:MODEF 0 "register_operand" "")
4583 (float_truncate:MODEF
4584 (match_operand:XF 1 "register_operand" "")))
4585 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4586 "TARGET_80387 && reload_completed"
4587 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4588 (set (match_dup 0) (match_dup 2))]
4592 [(set (match_operand:MODEF 0 "memory_operand" "")
4593 (float_truncate:MODEF
4594 (match_operand:XF 1 "register_operand" "")))
4595 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4597 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4600 ;; Signed conversion to DImode.
4602 (define_expand "fix_truncxfdi2"
4603 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4604 (fix:DI (match_operand:XF 1 "register_operand" "")))
4605 (clobber (reg:CC FLAGS_REG))])]
4610 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4615 (define_expand "fix_trunc<mode>di2"
4616 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4617 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4618 (clobber (reg:CC FLAGS_REG))])]
4619 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4622 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4624 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4627 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4629 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4630 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4631 if (out != operands[0])
4632 emit_move_insn (operands[0], out);
4637 ;; Signed conversion to SImode.
4639 (define_expand "fix_truncxfsi2"
4640 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4641 (fix:SI (match_operand:XF 1 "register_operand" "")))
4642 (clobber (reg:CC FLAGS_REG))])]
4647 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4652 (define_expand "fix_trunc<mode>si2"
4653 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4654 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4655 (clobber (reg:CC FLAGS_REG))])]
4656 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4659 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4661 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4664 if (SSE_FLOAT_MODE_P (<MODE>mode))
4666 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4667 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4668 if (out != operands[0])
4669 emit_move_insn (operands[0], out);
4674 ;; Signed conversion to HImode.
4676 (define_expand "fix_trunc<mode>hi2"
4677 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4678 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4679 (clobber (reg:CC FLAGS_REG))])]
4681 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4685 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4690 ;; Unsigned conversion to SImode.
4692 (define_expand "fixuns_trunc<mode>si2"
4694 [(set (match_operand:SI 0 "register_operand" "")
4696 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4698 (clobber (match_scratch:<ssevecmode> 3 ""))
4699 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4700 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4702 enum machine_mode mode = <MODE>mode;
4703 enum machine_mode vecmode = <ssevecmode>mode;
4704 REAL_VALUE_TYPE TWO31r;
4707 if (optimize_insn_for_size_p ())
4710 real_ldexp (&TWO31r, &dconst1, 31);
4711 two31 = const_double_from_real_value (TWO31r, mode);
4712 two31 = ix86_build_const_vector (mode, true, two31);
4713 operands[2] = force_reg (vecmode, two31);
4716 (define_insn_and_split "*fixuns_trunc<mode>_1"
4717 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4719 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4720 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4721 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4722 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4723 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4724 && optimize_function_for_speed_p (cfun)"
4726 "&& reload_completed"
4729 ix86_split_convert_uns_si_sse (operands);
4733 ;; Unsigned conversion to HImode.
4734 ;; Without these patterns, we'll try the unsigned SI conversion which
4735 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4737 (define_expand "fixuns_trunc<mode>hi2"
4739 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4740 (set (match_operand:HI 0 "nonimmediate_operand" "")
4741 (subreg:HI (match_dup 2) 0))]
4742 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4743 "operands[2] = gen_reg_rtx (SImode);")
4745 ;; When SSE is available, it is always faster to use it!
4746 (define_insn "fix_trunc<mode>di_sse"
4747 [(set (match_operand:DI 0 "register_operand" "=r,r")
4748 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4749 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4750 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4751 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4752 [(set_attr "type" "sseicvt")
4753 (set_attr "prefix" "maybe_vex")
4754 (set_attr "mode" "<MODE>")
4755 (set_attr "athlon_decode" "double,vector")
4756 (set_attr "amdfam10_decode" "double,double")])
4758 (define_insn "fix_trunc<mode>si_sse"
4759 [(set (match_operand:SI 0 "register_operand" "=r,r")
4760 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4761 "SSE_FLOAT_MODE_P (<MODE>mode)
4762 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4763 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4764 [(set_attr "type" "sseicvt")
4765 (set_attr "prefix" "maybe_vex")
4766 (set_attr "mode" "<MODE>")
4767 (set_attr "athlon_decode" "double,vector")
4768 (set_attr "amdfam10_decode" "double,double")])
4770 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4772 [(set (match_operand:MODEF 0 "register_operand" "")
4773 (match_operand:MODEF 1 "memory_operand" ""))
4774 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4775 (fix:SSEMODEI24 (match_dup 0)))]
4776 "TARGET_SHORTEN_X87_SSE
4777 && peep2_reg_dead_p (2, operands[0])"
4778 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4781 ;; Avoid vector decoded forms of the instruction.
4783 [(match_scratch:DF 2 "Y2")
4784 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4785 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4786 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4792 [(match_scratch:SF 2 "x")
4793 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4794 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4795 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4796 [(set (match_dup 2) (match_dup 1))
4797 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4800 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4801 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4802 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4803 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4805 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4806 && (TARGET_64BIT || <MODE>mode != DImode))
4808 && !(reload_completed || reload_in_progress)"
4813 if (memory_operand (operands[0], VOIDmode))
4814 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4817 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4818 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4824 [(set_attr "type" "fisttp")
4825 (set_attr "mode" "<MODE>")])
4827 (define_insn "fix_trunc<mode>_i387_fisttp"
4828 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4829 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4830 (clobber (match_scratch:XF 2 "=&1f"))]
4831 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4833 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4834 && (TARGET_64BIT || <MODE>mode != DImode))
4835 && TARGET_SSE_MATH)"
4836 "* return output_fix_trunc (insn, operands, 1);"
4837 [(set_attr "type" "fisttp")
4838 (set_attr "mode" "<MODE>")])
4840 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4841 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4842 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4843 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4844 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4845 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4847 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4848 && (TARGET_64BIT || <MODE>mode != DImode))
4849 && TARGET_SSE_MATH)"
4851 [(set_attr "type" "fisttp")
4852 (set_attr "mode" "<MODE>")])
4855 [(set (match_operand:X87MODEI 0 "register_operand" "")
4856 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4857 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4858 (clobber (match_scratch 3 ""))]
4860 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4861 (clobber (match_dup 3))])
4862 (set (match_dup 0) (match_dup 2))]
4866 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4867 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4868 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4869 (clobber (match_scratch 3 ""))]
4871 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4872 (clobber (match_dup 3))])]
4875 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4876 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4877 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4878 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4879 ;; function in i386.c.
4880 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4881 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4882 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4886 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && (TARGET_64BIT || <MODE>mode != DImode))
4888 && !(reload_completed || reload_in_progress)"
4893 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4895 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4896 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4897 if (memory_operand (operands[0], VOIDmode))
4898 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4899 operands[2], operands[3]));
4902 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4903 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4904 operands[2], operands[3],
4909 [(set_attr "type" "fistp")
4910 (set_attr "i387_cw" "trunc")
4911 (set_attr "mode" "<MODE>")])
4913 (define_insn "fix_truncdi_i387"
4914 [(set (match_operand:DI 0 "memory_operand" "=m")
4915 (fix:DI (match_operand 1 "register_operand" "f")))
4916 (use (match_operand:HI 2 "memory_operand" "m"))
4917 (use (match_operand:HI 3 "memory_operand" "m"))
4918 (clobber (match_scratch:XF 4 "=&1f"))]
4919 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4921 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4922 "* return output_fix_trunc (insn, operands, 0);"
4923 [(set_attr "type" "fistp")
4924 (set_attr "i387_cw" "trunc")
4925 (set_attr "mode" "DI")])
4927 (define_insn "fix_truncdi_i387_with_temp"
4928 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4929 (fix:DI (match_operand 1 "register_operand" "f,f")))
4930 (use (match_operand:HI 2 "memory_operand" "m,m"))
4931 (use (match_operand:HI 3 "memory_operand" "m,m"))
4932 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4933 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4936 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4938 [(set_attr "type" "fistp")
4939 (set_attr "i387_cw" "trunc")
4940 (set_attr "mode" "DI")])
4943 [(set (match_operand:DI 0 "register_operand" "")
4944 (fix:DI (match_operand 1 "register_operand" "")))
4945 (use (match_operand:HI 2 "memory_operand" ""))
4946 (use (match_operand:HI 3 "memory_operand" ""))
4947 (clobber (match_operand:DI 4 "memory_operand" ""))
4948 (clobber (match_scratch 5 ""))]
4950 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4953 (clobber (match_dup 5))])
4954 (set (match_dup 0) (match_dup 4))]
4958 [(set (match_operand:DI 0 "memory_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 0) (fix:DI (match_dup 1)))
4968 (clobber (match_dup 5))])]
4971 (define_insn "fix_trunc<mode>_i387"
4972 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4973 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4974 (use (match_operand:HI 2 "memory_operand" "m"))
4975 (use (match_operand:HI 3 "memory_operand" "m"))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979 "* return output_fix_trunc (insn, operands, 0);"
4980 [(set_attr "type" "fistp")
4981 (set_attr "i387_cw" "trunc")
4982 (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4986 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4987 (use (match_operand:HI 2 "memory_operand" "m,m"))
4988 (use (match_operand:HI 3 "memory_operand" "m,m"))
4989 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4990 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4992 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994 [(set_attr "type" "fistp")
4995 (set_attr "i387_cw" "trunc")
4996 (set_attr "mode" "<MODE>")])
4999 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5000 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5001 (use (match_operand:HI 2 "memory_operand" ""))
5002 (use (match_operand:HI 3 "memory_operand" ""))
5003 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5005 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5007 (use (match_dup 3))])
5008 (set (match_dup 0) (match_dup 4))]
5012 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5013 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5014 (use (match_operand:HI 2 "memory_operand" ""))
5015 (use (match_operand:HI 3 "memory_operand" ""))
5016 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5018 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5020 (use (match_dup 3))])]
5023 (define_insn "x86_fnstcw_1"
5024 [(set (match_operand:HI 0 "memory_operand" "=m")
5025 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5028 [(set_attr "length" "2")
5029 (set_attr "mode" "HI")
5030 (set_attr "unit" "i387")])
5032 (define_insn "x86_fldcw_1"
5033 [(set (reg:HI FPCR_REG)
5034 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5037 [(set_attr "length" "2")
5038 (set_attr "mode" "HI")
5039 (set_attr "unit" "i387")
5040 (set_attr "athlon_decode" "vector")
5041 (set_attr "amdfam10_decode" "vector")])
5043 ;; Conversion between fixed point and floating point.
5045 ;; Even though we only accept memory inputs, the backend _really_
5046 ;; wants to be able to do this between registers.
5048 (define_expand "floathi<mode>2"
5049 [(set (match_operand:X87MODEF 0 "register_operand" "")
5050 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5053 || TARGET_MIX_SSE_I387)"
5056 ;; Pre-reload splitter to add memory clobber to the pattern.
5057 (define_insn_and_split "*floathi<mode>2_1"
5058 [(set (match_operand:X87MODEF 0 "register_operand" "")
5059 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062 || TARGET_MIX_SSE_I387)
5063 && !(reload_completed || reload_in_progress)"
5066 [(parallel [(set (match_dup 0)
5067 (float:X87MODEF (match_dup 1)))
5068 (clobber (match_dup 2))])]
5069 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5071 (define_insn "*floathi<mode>2_i387_with_temp"
5072 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5073 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5074 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077 || TARGET_MIX_SSE_I387)"
5079 [(set_attr "type" "fmov,multi")
5080 (set_attr "mode" "<MODE>")
5081 (set_attr "unit" "*,i387")
5082 (set_attr "fp_int_src" "true")])
5084 (define_insn "*floathi<mode>2_i387"
5085 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5086 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5089 || TARGET_MIX_SSE_I387)"
5091 [(set_attr "type" "fmov")
5092 (set_attr "mode" "<MODE>")
5093 (set_attr "fp_int_src" "true")])
5096 [(set (match_operand:X87MODEF 0 "register_operand" "")
5097 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5098 (clobber (match_operand:HI 2 "memory_operand" ""))]
5100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5101 || TARGET_MIX_SSE_I387)
5102 && reload_completed"
5103 [(set (match_dup 2) (match_dup 1))
5104 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5108 [(set (match_operand:X87MODEF 0 "register_operand" "")
5109 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5110 (clobber (match_operand:HI 2 "memory_operand" ""))]
5112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5113 || TARGET_MIX_SSE_I387)
5114 && reload_completed"
5115 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5118 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5119 [(set (match_operand:X87MODEF 0 "register_operand" "")
5121 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5123 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5127 ;; Pre-reload splitter to add memory clobber to the pattern.
5128 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5129 [(set (match_operand:X87MODEF 0 "register_operand" "")
5130 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5132 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5133 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5134 || TARGET_MIX_SSE_I387))
5135 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5137 && ((<SSEMODEI24:MODE>mode == SImode
5138 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5139 && optimize_function_for_speed_p (cfun)
5140 && flag_trapping_math)
5141 || !(TARGET_INTER_UNIT_CONVERSIONS
5142 || optimize_function_for_size_p (cfun)))))
5143 && !(reload_completed || reload_in_progress)"
5146 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5147 (clobber (match_dup 2))])]
5149 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5151 /* Avoid store forwarding (partial memory) stall penalty
5152 by passing DImode value through XMM registers. */
5153 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5154 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5155 && optimize_function_for_speed_p (cfun))
5157 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5164 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5165 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5167 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5168 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5169 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5170 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5172 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5173 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5174 (set_attr "unit" "*,i387,*,*,*")
5175 (set_attr "athlon_decode" "*,*,double,direct,double")
5176 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5177 (set_attr "fp_int_src" "true")])
5179 (define_insn "*floatsi<mode>2_vector_mixed"
5180 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5181 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5182 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5183 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5187 [(set_attr "type" "fmov,sseicvt")
5188 (set_attr "mode" "<MODE>,<ssevecmode>")
5189 (set_attr "unit" "i387,*")
5190 (set_attr "athlon_decode" "*,direct")
5191 (set_attr "amdfam10_decode" "*,double")
5192 (set_attr "fp_int_src" "true")])
5194 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5195 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5197 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5198 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5199 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5202 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5203 (set_attr "mode" "<MODEF:MODE>")
5204 (set_attr "unit" "*,i387,*,*")
5205 (set_attr "athlon_decode" "*,*,double,direct")
5206 (set_attr "amdfam10_decode" "*,*,vector,double")
5207 (set_attr "fp_int_src" "true")])
5210 [(set (match_operand:MODEF 0 "register_operand" "")
5211 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5212 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5213 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5214 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5215 && TARGET_INTER_UNIT_CONVERSIONS
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (operands[0])))"
5220 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5224 [(set (match_operand:MODEF 0 "register_operand" "")
5225 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5228 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5229 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5234 [(set (match_dup 2) (match_dup 1))
5235 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5238 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5239 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5241 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
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))"
5247 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5248 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249 [(set_attr "type" "fmov,sseicvt,sseicvt")
5250 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5251 (set_attr "mode" "<MODEF:MODE>")
5252 (set_attr "unit" "i387,*,*")
5253 (set_attr "athlon_decode" "*,double,direct")
5254 (set_attr "amdfam10_decode" "*,vector,double")
5255 (set_attr "fp_int_src" "true")])
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5258 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5260 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5261 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5266 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5267 [(set_attr "type" "fmov,sseicvt")
5268 (set_attr "prefix" "orig,maybe_vex")
5269 (set_attr "mode" "<MODEF:MODE>")
5270 (set_attr "athlon_decode" "*,direct")
5271 (set_attr "amdfam10_decode" "*,double")
5272 (set_attr "fp_int_src" "true")])
5274 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5277 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5278 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5279 "TARGET_SSE2 && TARGET_SSE_MATH
5280 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5282 [(set_attr "type" "sseicvt")
5283 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5284 (set_attr "athlon_decode" "double,direct,double")
5285 (set_attr "amdfam10_decode" "vector,double,double")
5286 (set_attr "fp_int_src" "true")])
5288 (define_insn "*floatsi<mode>2_vector_sse"
5289 [(set (match_operand:MODEF 0 "register_operand" "=x")
5290 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5291 "TARGET_SSE2 && TARGET_SSE_MATH
5292 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5294 [(set_attr "type" "sseicvt")
5295 (set_attr "mode" "<MODE>")
5296 (set_attr "athlon_decode" "direct")
5297 (set_attr "amdfam10_decode" "double")
5298 (set_attr "fp_int_src" "true")])
5301 [(set (match_operand:MODEF 0 "register_operand" "")
5302 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5303 (clobber (match_operand:SI 2 "memory_operand" ""))]
5304 "TARGET_SSE2 && TARGET_SSE_MATH
5305 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5307 && (SSE_REG_P (operands[0])
5308 || (GET_CODE (operands[0]) == SUBREG
5309 && SSE_REG_P (operands[0])))"
5312 rtx op1 = operands[1];
5314 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5316 if (GET_CODE (op1) == SUBREG)
5317 op1 = SUBREG_REG (op1);
5319 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5321 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5322 emit_insn (gen_sse2_loadld (operands[4],
5323 CONST0_RTX (V4SImode), operands[1]));
5325 /* We can ignore possible trapping value in the
5326 high part of SSE register for non-trapping math. */
5327 else if (SSE_REG_P (op1) && !flag_trapping_math)
5328 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5331 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5332 emit_move_insn (operands[2], operands[1]);
5333 emit_insn (gen_sse2_loadld (operands[4],
5334 CONST0_RTX (V4SImode), operands[2]));
5337 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5342 [(set (match_operand:MODEF 0 "register_operand" "")
5343 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5344 (clobber (match_operand:SI 2 "memory_operand" ""))]
5345 "TARGET_SSE2 && TARGET_SSE_MATH
5346 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5348 && (SSE_REG_P (operands[0])
5349 || (GET_CODE (operands[0]) == SUBREG
5350 && SSE_REG_P (operands[0])))"
5353 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5355 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5357 emit_insn (gen_sse2_loadld (operands[4],
5358 CONST0_RTX (V4SImode), operands[1]));
5360 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5365 [(set (match_operand:MODEF 0 "register_operand" "")
5366 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5367 "TARGET_SSE2 && TARGET_SSE_MATH
5368 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5375 rtx op1 = operands[1];
5377 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5379 if (GET_CODE (op1) == SUBREG)
5380 op1 = SUBREG_REG (op1);
5382 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5384 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5385 emit_insn (gen_sse2_loadld (operands[4],
5386 CONST0_RTX (V4SImode), operands[1]));
5388 /* We can ignore possible trapping value in the
5389 high part of SSE register for non-trapping math. */
5390 else if (SSE_REG_P (op1) && !flag_trapping_math)
5391 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5395 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5400 [(set (match_operand:MODEF 0 "register_operand" "")
5401 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5402 "TARGET_SSE2 && TARGET_SSE_MATH
5403 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5405 && (SSE_REG_P (operands[0])
5406 || (GET_CODE (operands[0]) == SUBREG
5407 && SSE_REG_P (operands[0])))"
5410 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5412 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5414 emit_insn (gen_sse2_loadld (operands[4],
5415 CONST0_RTX (V4SImode), operands[1]));
5417 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5422 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5424 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5425 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5426 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5427 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5429 [(set_attr "type" "sseicvt")
5430 (set_attr "mode" "<MODEF:MODE>")
5431 (set_attr "athlon_decode" "double,direct")
5432 (set_attr "amdfam10_decode" "vector,double")
5433 (set_attr "fp_int_src" "true")])
5435 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5436 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5438 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5439 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5440 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5441 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5442 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443 [(set_attr "type" "sseicvt")
5444 (set_attr "prefix" "maybe_vex")
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")])
5451 [(set (match_operand:MODEF 0 "register_operand" "")
5452 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5453 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5458 && (SSE_REG_P (operands[0])
5459 || (GET_CODE (operands[0]) == SUBREG
5460 && SSE_REG_P (operands[0])))"
5461 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5464 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5465 [(set (match_operand:MODEF 0 "register_operand" "=x")
5467 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5468 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5469 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5470 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5471 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472 [(set_attr "type" "sseicvt")
5473 (set_attr "prefix" "maybe_vex")
5474 (set_attr "mode" "<MODEF:MODE>")
5475 (set_attr "athlon_decode" "direct")
5476 (set_attr "amdfam10_decode" "double")
5477 (set_attr "fp_int_src" "true")])
5480 [(set (match_operand:MODEF 0 "register_operand" "")
5481 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5487 && (SSE_REG_P (operands[0])
5488 || (GET_CODE (operands[0]) == SUBREG
5489 && SSE_REG_P (operands[0])))"
5490 [(set (match_dup 2) (match_dup 1))
5491 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5495 [(set (match_operand:MODEF 0 "register_operand" "")
5496 (float:MODEF (match_operand:SSEMODEI24 1 "memory_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
5501 && (SSE_REG_P (operands[0])
5502 || (GET_CODE (operands[0]) == SUBREG
5503 && SSE_REG_P (operands[0])))"
5504 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5510 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5516 [(set_attr "type" "fmov,multi")
5517 (set_attr "mode" "<X87MODEF:MODE>")
5518 (set_attr "unit" "*,i387")
5519 (set_attr "fp_int_src" "true")])
5521 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5522 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5524 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5527 [(set_attr "type" "fmov")
5528 (set_attr "mode" "<X87MODEF:MODE>")
5529 (set_attr "fp_int_src" "true")])
5532 [(set (match_operand:X87MODEF 0 "register_operand" "")
5533 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5537 && FP_REG_P (operands[0])"
5538 [(set (match_dup 2) (match_dup 1))
5539 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5543 [(set (match_operand:X87MODEF 0 "register_operand" "")
5544 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5545 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5548 && FP_REG_P (operands[0])"
5549 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers. */
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5558 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559 (clobber (match_scratch:V4SI 3 "=X,x"))
5560 (clobber (match_scratch:V4SI 4 "=X,x"))
5561 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5563 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5565 [(set_attr "type" "multi")
5566 (set_attr "mode" "<X87MODEF:MODE>")
5567 (set_attr "unit" "i387")
5568 (set_attr "fp_int_src" "true")])
5571 [(set (match_operand:X87MODEF 0 "register_operand" "")
5572 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5573 (clobber (match_scratch:V4SI 3 ""))
5574 (clobber (match_scratch:V4SI 4 ""))
5575 (clobber (match_operand:DI 2 "memory_operand" ""))]
5576 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5577 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5579 && FP_REG_P (operands[0])"
5580 [(set (match_dup 2) (match_dup 3))
5581 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5583 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5584 Assemble the 64-bit DImode value in an xmm register. */
5585 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5586 gen_rtx_SUBREG (SImode, operands[1], 0)));
5587 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5588 gen_rtx_SUBREG (SImode, operands[1], 4)));
5589 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5591 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5595 [(set (match_operand:X87MODEF 0 "register_operand" "")
5596 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5597 (clobber (match_scratch:V4SI 3 ""))
5598 (clobber (match_scratch:V4SI 4 ""))
5599 (clobber (match_operand:DI 2 "memory_operand" ""))]
5600 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5601 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5603 && FP_REG_P (operands[0])"
5604 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5610 ;; targets benefit from this optimization. Also note that fild
5611 ;; loads from memory only.
5613 (define_insn "*floatunssi<mode>2_1"
5614 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5615 (unsigned_float:X87MODEF
5616 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5617 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5618 (clobber (match_scratch:SI 3 "=X,x"))]
5620 && TARGET_80387 && TARGET_SSE"
5622 [(set_attr "type" "multi")
5623 (set_attr "mode" "<MODE>")])
5626 [(set (match_operand:X87MODEF 0 "register_operand" "")
5627 (unsigned_float:X87MODEF
5628 (match_operand:SI 1 "register_operand" "")))
5629 (clobber (match_operand:DI 2 "memory_operand" ""))
5630 (clobber (match_scratch:SI 3 ""))]
5632 && TARGET_80387 && TARGET_SSE
5633 && reload_completed"
5634 [(set (match_dup 2) (match_dup 1))
5636 (float:X87MODEF (match_dup 2)))]
5637 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5640 [(set (match_operand:X87MODEF 0 "register_operand" "")
5641 (unsigned_float:X87MODEF
5642 (match_operand:SI 1 "memory_operand" "")))
5643 (clobber (match_operand:DI 2 "memory_operand" ""))
5644 (clobber (match_scratch:SI 3 ""))]
5646 && TARGET_80387 && TARGET_SSE
5647 && reload_completed"
5648 [(set (match_dup 2) (match_dup 3))
5650 (float:X87MODEF (match_dup 2)))]
5652 emit_move_insn (operands[3], operands[1]);
5653 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5656 (define_expand "floatunssi<mode>2"
5658 [(set (match_operand:X87MODEF 0 "register_operand" "")
5659 (unsigned_float:X87MODEF
5660 (match_operand:SI 1 "nonimmediate_operand" "")))
5661 (clobber (match_dup 2))
5662 (clobber (match_scratch:SI 3 ""))])]
5664 && ((TARGET_80387 && TARGET_SSE)
5665 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5667 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5669 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5674 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5675 operands[2] = assign_386_stack_local (DImode, slot);
5679 (define_expand "floatunsdisf2"
5680 [(use (match_operand:SF 0 "register_operand" ""))
5681 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5682 "TARGET_64BIT && TARGET_SSE_MATH"
5683 "x86_emit_floatuns (operands); DONE;")
5685 (define_expand "floatunsdidf2"
5686 [(use (match_operand:DF 0 "register_operand" ""))
5687 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5688 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5689 && TARGET_SSE2 && TARGET_SSE_MATH"
5692 x86_emit_floatuns (operands);
5694 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5700 ;; %%% splits for addditi3
5702 (define_expand "addti3"
5703 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5704 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5705 (match_operand:TI 2 "x86_64_general_operand" "")))]
5707 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5709 (define_insn "*addti3_1"
5710 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5711 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5712 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
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" "")))
5721 (clobber (reg:CC FLAGS_REG))]
5722 "TARGET_64BIT && reload_completed"
5723 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5725 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5726 (parallel [(set (match_dup 3)
5727 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5730 (clobber (reg:CC FLAGS_REG))])]
5731 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5733 ;; %%% splits for addsidi3
5734 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5735 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5736 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5738 (define_expand "adddi3"
5739 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5740 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5741 (match_operand:DI 2 "x86_64_general_operand" "")))]
5743 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5745 (define_insn "*adddi3_1"
5746 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5747 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5748 (match_operand:DI 2 "general_operand" "roiF,riF")))
5749 (clobber (reg:CC FLAGS_REG))]
5750 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5754 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756 (match_operand:DI 2 "general_operand" "")))
5757 (clobber (reg:CC FLAGS_REG))]
5758 "!TARGET_64BIT && reload_completed"
5759 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5761 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5762 (parallel [(set (match_dup 3)
5763 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5766 (clobber (reg:CC FLAGS_REG))])]
5767 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5769 (define_insn "adddi3_carry_rex64"
5770 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5771 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5772 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5773 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776 "adc{q}\t{%2, %0|%0, %2}"
5777 [(set_attr "type" "alu")
5778 (set_attr "pent_pair" "pu")
5779 (set_attr "mode" "DI")])
5781 (define_insn "*adddi3_cc_rex64"
5782 [(set (reg:CC FLAGS_REG)
5783 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5784 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5786 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5787 (plus:DI (match_dup 1) (match_dup 2)))]
5788 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5789 "add{q}\t{%2, %0|%0, %2}"
5790 [(set_attr "type" "alu")
5791 (set_attr "mode" "DI")])
5793 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5794 [(set (reg:CCC FLAGS_REG)
5797 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5798 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5800 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5801 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5802 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5803 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5804 [(set_attr "type" "alu")
5805 (set_attr "mode" "<MODE>")])
5807 (define_insn "*add<mode>3_cconly_overflow"
5808 [(set (reg:CCC FLAGS_REG)
5810 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5811 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5813 (clobber (match_scratch:SWI 0 "=<r>"))]
5814 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5816 [(set_attr "type" "alu")
5817 (set_attr "mode" "<MODE>")])
5819 (define_insn "*sub<mode>3_cconly_overflow"
5820 [(set (reg:CCC FLAGS_REG)
5822 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5823 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5826 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5827 [(set_attr "type" "icmp")
5828 (set_attr "mode" "<MODE>")])
5830 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5831 [(set (reg:CCC FLAGS_REG)
5833 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5834 (match_operand:SI 2 "general_operand" "g"))
5836 (set (match_operand:DI 0 "register_operand" "=r")
5837 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5838 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5839 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5840 [(set_attr "type" "alu")
5841 (set_attr "mode" "SI")])
5843 (define_insn "addqi3_carry"
5844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5845 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5846 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5847 (match_operand:QI 2 "general_operand" "qn,qm")))
5848 (clobber (reg:CC FLAGS_REG))]
5849 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5850 "adc{b}\t{%2, %0|%0, %2}"
5851 [(set_attr "type" "alu")
5852 (set_attr "pent_pair" "pu")
5853 (set_attr "mode" "QI")])
5855 (define_insn "addhi3_carry"
5856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5857 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5858 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5859 (match_operand:HI 2 "general_operand" "rn,rm")))
5860 (clobber (reg:CC FLAGS_REG))]
5861 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5862 "adc{w}\t{%2, %0|%0, %2}"
5863 [(set_attr "type" "alu")
5864 (set_attr "pent_pair" "pu")
5865 (set_attr "mode" "HI")])
5867 (define_insn "addsi3_carry"
5868 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5869 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5870 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5871 (match_operand:SI 2 "general_operand" "ri,rm")))
5872 (clobber (reg:CC FLAGS_REG))]
5873 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5874 "adc{l}\t{%2, %0|%0, %2}"
5875 [(set_attr "type" "alu")
5876 (set_attr "pent_pair" "pu")
5877 (set_attr "mode" "SI")])
5879 (define_insn "*addsi3_carry_zext"
5880 [(set (match_operand:DI 0 "register_operand" "=r")
5882 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5883 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5884 (match_operand:SI 2 "general_operand" "g"))))
5885 (clobber (reg:CC FLAGS_REG))]
5886 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5887 "adc{l}\t{%2, %k0|%k0, %2}"
5888 [(set_attr "type" "alu")
5889 (set_attr "pent_pair" "pu")
5890 (set_attr "mode" "SI")])
5892 (define_insn "*addsi3_cc"
5893 [(set (reg:CC FLAGS_REG)
5894 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5895 (match_operand:SI 2 "general_operand" "ri,rm")]
5897 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5898 (plus:SI (match_dup 1) (match_dup 2)))]
5899 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5900 "add{l}\t{%2, %0|%0, %2}"
5901 [(set_attr "type" "alu")
5902 (set_attr "mode" "SI")])
5904 (define_insn "addqi3_cc"
5905 [(set (reg:CC FLAGS_REG)
5906 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5907 (match_operand:QI 2 "general_operand" "qn,qm")]
5909 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5910 (plus:QI (match_dup 1) (match_dup 2)))]
5911 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5912 "add{b}\t{%2, %0|%0, %2}"
5913 [(set_attr "type" "alu")
5914 (set_attr "mode" "QI")])
5916 (define_expand "addsi3"
5917 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5918 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5919 (match_operand:SI 2 "general_operand" "")))]
5921 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5923 (define_insn "*lea_1"
5924 [(set (match_operand:SI 0 "register_operand" "=r")
5925 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5927 "lea{l}\t{%a1, %0|%0, %a1}"
5928 [(set_attr "type" "lea")
5929 (set_attr "mode" "SI")])
5931 (define_insn "*lea_1_rex64"
5932 [(set (match_operand:SI 0 "register_operand" "=r")
5933 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5935 "lea{l}\t{%a1, %0|%0, %a1}"
5936 [(set_attr "type" "lea")
5937 (set_attr "mode" "SI")])
5939 (define_insn "*lea_1_zext"
5940 [(set (match_operand:DI 0 "register_operand" "=r")
5942 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5944 "lea{l}\t{%a1, %k0|%k0, %a1}"
5945 [(set_attr "type" "lea")
5946 (set_attr "mode" "SI")])
5948 (define_insn "*lea_2_rex64"
5949 [(set (match_operand:DI 0 "register_operand" "=r")
5950 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5952 "lea{q}\t{%a1, %0|%0, %a1}"
5953 [(set_attr "type" "lea")
5954 (set_attr "mode" "DI")])
5956 ;; The lea patterns for non-Pmodes needs to be matched by several
5957 ;; insns converted to real lea by splitters.
5959 (define_insn_and_split "*lea_general_1"
5960 [(set (match_operand 0 "register_operand" "=r")
5961 (plus (plus (match_operand 1 "index_register_operand" "l")
5962 (match_operand 2 "register_operand" "r"))
5963 (match_operand 3 "immediate_operand" "i")))]
5964 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5965 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5966 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5967 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5968 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5969 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5970 || GET_MODE (operands[3]) == VOIDmode)"
5972 "&& reload_completed"
5976 operands[0] = gen_lowpart (SImode, operands[0]);
5977 operands[1] = gen_lowpart (Pmode, operands[1]);
5978 operands[2] = gen_lowpart (Pmode, operands[2]);
5979 operands[3] = gen_lowpart (Pmode, operands[3]);
5980 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5982 if (Pmode != SImode)
5983 pat = gen_rtx_SUBREG (SImode, pat, 0);
5984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5987 [(set_attr "type" "lea")
5988 (set_attr "mode" "SI")])
5990 (define_insn_and_split "*lea_general_1_zext"
5991 [(set (match_operand:DI 0 "register_operand" "=r")
5993 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5994 (match_operand:SI 2 "register_operand" "r"))
5995 (match_operand:SI 3 "immediate_operand" "i"))))]
5998 "&& reload_completed"
6000 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6002 (match_dup 3)) 0)))]
6004 operands[1] = gen_lowpart (Pmode, operands[1]);
6005 operands[2] = gen_lowpart (Pmode, operands[2]);
6006 operands[3] = gen_lowpart (Pmode, operands[3]);
6008 [(set_attr "type" "lea")
6009 (set_attr "mode" "SI")])
6011 (define_insn_and_split "*lea_general_2"
6012 [(set (match_operand 0 "register_operand" "=r")
6013 (plus (mult (match_operand 1 "index_register_operand" "l")
6014 (match_operand 2 "const248_operand" "i"))
6015 (match_operand 3 "nonmemory_operand" "ri")))]
6016 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6017 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021 || GET_MODE (operands[3]) == VOIDmode)"
6023 "&& reload_completed"
6027 operands[0] = gen_lowpart (SImode, operands[0]);
6028 operands[1] = gen_lowpart (Pmode, operands[1]);
6029 operands[3] = gen_lowpart (Pmode, operands[3]);
6030 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6032 if (Pmode != SImode)
6033 pat = gen_rtx_SUBREG (SImode, pat, 0);
6034 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6037 [(set_attr "type" "lea")
6038 (set_attr "mode" "SI")])
6040 (define_insn_and_split "*lea_general_2_zext"
6041 [(set (match_operand:DI 0 "register_operand" "=r")
6043 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6044 (match_operand:SI 2 "const248_operand" "n"))
6045 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6048 "&& reload_completed"
6050 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6052 (match_dup 3)) 0)))]
6054 operands[1] = gen_lowpart (Pmode, operands[1]);
6055 operands[3] = gen_lowpart (Pmode, operands[3]);
6057 [(set_attr "type" "lea")
6058 (set_attr "mode" "SI")])
6060 (define_insn_and_split "*lea_general_3"
6061 [(set (match_operand 0 "register_operand" "=r")
6062 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6063 (match_operand 2 "const248_operand" "i"))
6064 (match_operand 3 "register_operand" "r"))
6065 (match_operand 4 "immediate_operand" "i")))]
6066 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6067 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6068 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6069 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6070 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6072 "&& reload_completed"
6076 operands[0] = gen_lowpart (SImode, operands[0]);
6077 operands[1] = gen_lowpart (Pmode, operands[1]);
6078 operands[3] = gen_lowpart (Pmode, operands[3]);
6079 operands[4] = gen_lowpart (Pmode, operands[4]);
6080 pat = gen_rtx_PLUS (Pmode,
6081 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6085 if (Pmode != SImode)
6086 pat = gen_rtx_SUBREG (SImode, pat, 0);
6087 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6090 [(set_attr "type" "lea")
6091 (set_attr "mode" "SI")])
6093 (define_insn_and_split "*lea_general_3_zext"
6094 [(set (match_operand:DI 0 "register_operand" "=r")
6096 (plus:SI (plus:SI (mult:SI
6097 (match_operand:SI 1 "index_register_operand" "l")
6098 (match_operand:SI 2 "const248_operand" "n"))
6099 (match_operand:SI 3 "register_operand" "r"))
6100 (match_operand:SI 4 "immediate_operand" "i"))))]
6103 "&& reload_completed"
6105 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6108 (match_dup 4)) 0)))]
6110 operands[1] = gen_lowpart (Pmode, operands[1]);
6111 operands[3] = gen_lowpart (Pmode, operands[3]);
6112 operands[4] = gen_lowpart (Pmode, operands[4]);
6114 [(set_attr "type" "lea")
6115 (set_attr "mode" "SI")])
6117 (define_insn "*adddi_1_rex64"
6118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6119 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6120 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6124 switch (get_attr_type (insn))
6127 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128 return "lea{q}\t{%a2, %0|%0, %a2}";
6131 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6132 if (operands[2] == const1_rtx)
6133 return "inc{q}\t%0";
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{q}\t%0";
6141 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6143 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6144 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6145 if (CONST_INT_P (operands[2])
6146 /* Avoid overflows. */
6147 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6148 && (INTVAL (operands[2]) == 128
6149 || (INTVAL (operands[2]) < 0
6150 && INTVAL (operands[2]) != -128)))
6152 operands[2] = GEN_INT (-INTVAL (operands[2]));
6153 return "sub{q}\t{%2, %0|%0, %2}";
6155 return "add{q}\t{%2, %0|%0, %2}";
6159 (cond [(eq_attr "alternative" "2")
6160 (const_string "lea")
6161 ; Current assemblers are broken and do not allow @GOTOFF in
6162 ; ought but a memory context.
6163 (match_operand:DI 2 "pic_symbolic_operand" "")
6164 (const_string "lea")
6165 (match_operand:DI 2 "incdec_operand" "")
6166 (const_string "incdec")
6168 (const_string "alu")))
6169 (set_attr "mode" "DI")])
6171 ;; Convert lea to the lea pattern to avoid flags dependency.
6173 [(set (match_operand:DI 0 "register_operand" "")
6174 (plus:DI (match_operand:DI 1 "register_operand" "")
6175 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "TARGET_64BIT && reload_completed
6178 && true_regnum (operands[0]) != true_regnum (operands[1])"
6180 (plus:DI (match_dup 1)
6184 (define_insn "*adddi_2_rex64"
6185 [(set (reg FLAGS_REG)
6187 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6188 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6190 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6191 (plus:DI (match_dup 1) (match_dup 2)))]
6192 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6193 && ix86_binary_operator_ok (PLUS, DImode, operands)
6194 /* Current assemblers are broken and do not allow @GOTOFF in
6195 ought but a memory context. */
6196 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6198 switch (get_attr_type (insn))
6201 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202 if (operands[2] == const1_rtx)
6203 return "inc{q}\t%0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{q}\t%0";
6211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6212 /* ???? We ought to handle there the 32bit case too
6213 - do we need new constraint? */
6214 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6216 if (CONST_INT_P (operands[2])
6217 /* Avoid overflows. */
6218 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6219 && (INTVAL (operands[2]) == 128
6220 || (INTVAL (operands[2]) < 0
6221 && INTVAL (operands[2]) != -128)))
6223 operands[2] = GEN_INT (-INTVAL (operands[2]));
6224 return "sub{q}\t{%2, %0|%0, %2}";
6226 return "add{q}\t{%2, %0|%0, %2}";
6230 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set_attr "mode" "DI")])
6235 (define_insn "*adddi_3_rex64"
6236 [(set (reg FLAGS_REG)
6237 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6238 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6239 (clobber (match_scratch:DI 0 "=r"))]
6241 && ix86_match_ccmode (insn, CCZmode)
6242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6243 /* Current assemblers are broken and do not allow @GOTOFF in
6244 ought but a memory context. */
6245 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6247 switch (get_attr_type (insn))
6250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6251 if (operands[2] == const1_rtx)
6252 return "inc{q}\t%0";
6255 gcc_assert (operands[2] == constm1_rtx);
6256 return "dec{q}\t%0";
6260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6261 /* ???? We ought to handle there the 32bit case too
6262 - do we need new constraint? */
6263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6265 if (CONST_INT_P (operands[2])
6266 /* Avoid overflows. */
6267 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6268 && (INTVAL (operands[2]) == 128
6269 || (INTVAL (operands[2]) < 0
6270 && INTVAL (operands[2]) != -128)))
6272 operands[2] = GEN_INT (-INTVAL (operands[2]));
6273 return "sub{q}\t{%2, %0|%0, %2}";
6275 return "add{q}\t{%2, %0|%0, %2}";
6279 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu")))
6282 (set_attr "mode" "DI")])
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6286 ; is matched then. We can't accept general immediate, because for
6287 ; case of overflows, the result is messed up.
6288 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6290 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6291 ; only for comparisons not depending on it.
6292 (define_insn "*adddi_4_rex64"
6293 [(set (reg FLAGS_REG)
6294 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6295 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6296 (clobber (match_scratch:DI 0 "=rm"))]
6298 && ix86_match_ccmode (insn, CCGCmode)"
6300 switch (get_attr_type (insn))
6303 if (operands[2] == constm1_rtx)
6304 return "inc{q}\t%0";
6307 gcc_assert (operands[2] == const1_rtx);
6308 return "dec{q}\t%0";
6312 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6313 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6314 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6315 if ((INTVAL (operands[2]) == -128
6316 || (INTVAL (operands[2]) > 0
6317 && INTVAL (operands[2]) != 128))
6318 /* Avoid overflows. */
6319 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6320 return "sub{q}\t{%2, %0|%0, %2}";
6321 operands[2] = GEN_INT (-INTVAL (operands[2]));
6322 return "add{q}\t{%2, %0|%0, %2}";
6326 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6327 (const_string "incdec")
6328 (const_string "alu")))
6329 (set_attr "mode" "DI")])
6331 (define_insn "*adddi_5_rex64"
6332 [(set (reg FLAGS_REG)
6334 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6335 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6337 (clobber (match_scratch:DI 0 "=r"))]
6339 && ix86_match_ccmode (insn, CCGOCmode)
6340 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6341 /* Current assemblers are broken and do not allow @GOTOFF in
6342 ought but a memory context. */
6343 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6345 switch (get_attr_type (insn))
6348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6349 if (operands[2] == const1_rtx)
6350 return "inc{q}\t%0";
6353 gcc_assert (operands[2] == constm1_rtx);
6354 return "dec{q}\t%0";
6358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6359 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6360 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6361 if (CONST_INT_P (operands[2])
6362 /* Avoid overflows. */
6363 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6364 && (INTVAL (operands[2]) == 128
6365 || (INTVAL (operands[2]) < 0
6366 && INTVAL (operands[2]) != -128)))
6368 operands[2] = GEN_INT (-INTVAL (operands[2]));
6369 return "sub{q}\t{%2, %0|%0, %2}";
6371 return "add{q}\t{%2, %0|%0, %2}";
6375 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set_attr "mode" "DI")])
6381 (define_insn "*addsi_1"
6382 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6383 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6384 (match_operand:SI 2 "general_operand" "g,ri,li")))
6385 (clobber (reg:CC FLAGS_REG))]
6386 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6388 switch (get_attr_type (insn))
6391 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6392 return "lea{l}\t{%a2, %0|%0, %a2}";
6395 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6396 if (operands[2] == const1_rtx)
6397 return "inc{l}\t%0";
6400 gcc_assert (operands[2] == constm1_rtx);
6401 return "dec{l}\t%0";
6405 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6407 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6409 if (CONST_INT_P (operands[2])
6410 && (INTVAL (operands[2]) == 128
6411 || (INTVAL (operands[2]) < 0
6412 && INTVAL (operands[2]) != -128)))
6414 operands[2] = GEN_INT (-INTVAL (operands[2]));
6415 return "sub{l}\t{%2, %0|%0, %2}";
6417 return "add{l}\t{%2, %0|%0, %2}";
6421 (cond [(eq_attr "alternative" "2")
6422 (const_string "lea")
6423 ; Current assemblers are broken and do not allow @GOTOFF in
6424 ; ought but a memory context.
6425 (match_operand:SI 2 "pic_symbolic_operand" "")
6426 (const_string "lea")
6427 (match_operand:SI 2 "incdec_operand" "")
6428 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "SI")])
6433 ;; Convert lea to the lea pattern to avoid flags dependency.
6435 [(set (match_operand 0 "register_operand" "")
6436 (plus (match_operand 1 "register_operand" "")
6437 (match_operand 2 "nonmemory_operand" "")))
6438 (clobber (reg:CC FLAGS_REG))]
6440 && true_regnum (operands[0]) != true_regnum (operands[1])"
6444 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6445 may confuse gen_lowpart. */
6446 if (GET_MODE (operands[0]) != Pmode)
6448 operands[1] = gen_lowpart (Pmode, operands[1]);
6449 operands[2] = gen_lowpart (Pmode, operands[2]);
6451 operands[0] = gen_lowpart (SImode, operands[0]);
6452 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6453 if (Pmode != SImode)
6454 pat = gen_rtx_SUBREG (SImode, pat, 0);
6455 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6459 ;; It may seem that nonimmediate operand is proper one for operand 1.
6460 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6461 ;; we take care in ix86_binary_operator_ok to not allow two memory
6462 ;; operands so proper swapping will be done in reload. This allow
6463 ;; patterns constructed from addsi_1 to match.
6464 (define_insn "addsi_1_zext"
6465 [(set (match_operand:DI 0 "register_operand" "=r,r")
6467 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6468 (match_operand:SI 2 "general_operand" "g,li"))))
6469 (clobber (reg:CC FLAGS_REG))]
6470 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6472 switch (get_attr_type (insn))
6475 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6476 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6479 if (operands[2] == const1_rtx)
6480 return "inc{l}\t%k0";
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{l}\t%k0";
6488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{l}\t{%2, %k0|%k0, %2}";
6498 return "add{l}\t{%2, %k0|%k0, %2}";
6502 (cond [(eq_attr "alternative" "1")
6503 (const_string "lea")
6504 ; Current assemblers are broken and do not allow @GOTOFF in
6505 ; ought but a memory context.
6506 (match_operand:SI 2 "pic_symbolic_operand" "")
6507 (const_string "lea")
6508 (match_operand:SI 2 "incdec_operand" "")
6509 (const_string "incdec")
6511 (const_string "alu")))
6512 (set_attr "mode" "SI")])
6514 ;; Convert lea to the lea pattern to avoid flags dependency.
6516 [(set (match_operand:DI 0 "register_operand" "")
6518 (plus:SI (match_operand:SI 1 "register_operand" "")
6519 (match_operand:SI 2 "nonmemory_operand" ""))))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "TARGET_64BIT && reload_completed
6522 && true_regnum (operands[0]) != true_regnum (operands[1])"
6524 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6526 operands[1] = gen_lowpart (Pmode, operands[1]);
6527 operands[2] = gen_lowpart (Pmode, operands[2]);
6530 (define_insn "*addsi_2"
6531 [(set (reg FLAGS_REG)
6533 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6534 (match_operand:SI 2 "general_operand" "g,ri"))
6536 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6537 (plus:SI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCGOCmode)
6539 && ix86_binary_operator_ok (PLUS, SImode, operands)
6540 /* Current assemblers are broken and do not allow @GOTOFF in
6541 ought but a memory context. */
6542 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6544 switch (get_attr_type (insn))
6547 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6548 if (operands[2] == const1_rtx)
6549 return "inc{l}\t%0";
6552 gcc_assert (operands[2] == constm1_rtx);
6553 return "dec{l}\t%0";
6557 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6558 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6559 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6560 if (CONST_INT_P (operands[2])
6561 && (INTVAL (operands[2]) == 128
6562 || (INTVAL (operands[2]) < 0
6563 && INTVAL (operands[2]) != -128)))
6565 operands[2] = GEN_INT (-INTVAL (operands[2]));
6566 return "sub{l}\t{%2, %0|%0, %2}";
6568 return "add{l}\t{%2, %0|%0, %2}";
6572 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6573 (const_string "incdec")
6574 (const_string "alu")))
6575 (set_attr "mode" "SI")])
6577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6578 (define_insn "*addsi_2_zext"
6579 [(set (reg FLAGS_REG)
6581 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6582 (match_operand:SI 2 "general_operand" "g"))
6584 (set (match_operand:DI 0 "register_operand" "=r")
6585 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6587 && ix86_binary_operator_ok (PLUS, SImode, operands)
6588 /* Current assemblers are broken and do not allow @GOTOFF in
6589 ought but a memory context. */
6590 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6592 switch (get_attr_type (insn))
6595 if (operands[2] == const1_rtx)
6596 return "inc{l}\t%k0";
6599 gcc_assert (operands[2] == constm1_rtx);
6600 return "dec{l}\t%k0";
6604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6606 if (CONST_INT_P (operands[2])
6607 && (INTVAL (operands[2]) == 128
6608 || (INTVAL (operands[2]) < 0
6609 && INTVAL (operands[2]) != -128)))
6611 operands[2] = GEN_INT (-INTVAL (operands[2]));
6612 return "sub{l}\t{%2, %k0|%k0, %2}";
6614 return "add{l}\t{%2, %k0|%k0, %2}";
6618 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6619 (const_string "incdec")
6620 (const_string "alu")))
6621 (set_attr "mode" "SI")])
6623 (define_insn "*addsi_3"
6624 [(set (reg FLAGS_REG)
6625 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6626 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6627 (clobber (match_scratch:SI 0 "=r"))]
6628 "ix86_match_ccmode (insn, CCZmode)
6629 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6630 /* Current assemblers are broken and do not allow @GOTOFF in
6631 ought but a memory context. */
6632 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6634 switch (get_attr_type (insn))
6637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638 if (operands[2] == const1_rtx)
6639 return "inc{l}\t%0";
6642 gcc_assert (operands[2] == constm1_rtx);
6643 return "dec{l}\t%0";
6647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6649 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6650 if (CONST_INT_P (operands[2])
6651 && (INTVAL (operands[2]) == 128
6652 || (INTVAL (operands[2]) < 0
6653 && INTVAL (operands[2]) != -128)))
6655 operands[2] = GEN_INT (-INTVAL (operands[2]));
6656 return "sub{l}\t{%2, %0|%0, %2}";
6658 return "add{l}\t{%2, %0|%0, %2}";
6662 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6663 (const_string "incdec")
6664 (const_string "alu")))
6665 (set_attr "mode" "SI")])
6667 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6668 (define_insn "*addsi_3_zext"
6669 [(set (reg FLAGS_REG)
6670 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6671 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6672 (set (match_operand:DI 0 "register_operand" "=r")
6673 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6674 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6675 && ix86_binary_operator_ok (PLUS, SImode, operands)
6676 /* Current assemblers are broken and do not allow @GOTOFF in
6677 ought but a memory context. */
6678 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6680 switch (get_attr_type (insn))
6683 if (operands[2] == const1_rtx)
6684 return "inc{l}\t%k0";
6687 gcc_assert (operands[2] == constm1_rtx);
6688 return "dec{l}\t%k0";
6692 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6693 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6694 if (CONST_INT_P (operands[2])
6695 && (INTVAL (operands[2]) == 128
6696 || (INTVAL (operands[2]) < 0
6697 && INTVAL (operands[2]) != -128)))
6699 operands[2] = GEN_INT (-INTVAL (operands[2]));
6700 return "sub{l}\t{%2, %k0|%k0, %2}";
6702 return "add{l}\t{%2, %k0|%k0, %2}";
6706 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6707 (const_string "incdec")
6708 (const_string "alu")))
6709 (set_attr "mode" "SI")])
6711 ; For comparisons against 1, -1 and 128, we may generate better code
6712 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6713 ; is matched then. We can't accept general immediate, because for
6714 ; case of overflows, the result is messed up.
6715 ; This pattern also don't hold of 0x80000000, since the value overflows
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6719 (define_insn "*addsi_4"
6720 [(set (reg FLAGS_REG)
6721 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6722 (match_operand:SI 2 "const_int_operand" "n")))
6723 (clobber (match_scratch:SI 0 "=rm"))]
6724 "ix86_match_ccmode (insn, CCGCmode)
6725 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6727 switch (get_attr_type (insn))
6730 if (operands[2] == constm1_rtx)
6731 return "inc{l}\t%0";
6734 gcc_assert (operands[2] == const1_rtx);
6735 return "dec{l}\t%0";
6739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6740 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6741 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6742 if ((INTVAL (operands[2]) == -128
6743 || (INTVAL (operands[2]) > 0
6744 && INTVAL (operands[2]) != 128)))
6745 return "sub{l}\t{%2, %0|%0, %2}";
6746 operands[2] = GEN_INT (-INTVAL (operands[2]));
6747 return "add{l}\t{%2, %0|%0, %2}";
6751 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6752 (const_string "incdec")
6753 (const_string "alu")))
6754 (set_attr "mode" "SI")])
6756 (define_insn "*addsi_5"
6757 [(set (reg FLAGS_REG)
6759 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760 (match_operand:SI 2 "general_operand" "g"))
6762 (clobber (match_scratch:SI 0 "=r"))]
6763 "ix86_match_ccmode (insn, CCGOCmode)
6764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6765 /* Current assemblers are broken and do not allow @GOTOFF in
6766 ought but a memory context. */
6767 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6769 switch (get_attr_type (insn))
6772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773 if (operands[2] == const1_rtx)
6774 return "inc{l}\t%0";
6777 gcc_assert (operands[2] == constm1_rtx);
6778 return "dec{l}\t%0";
6782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6785 if (CONST_INT_P (operands[2])
6786 && (INTVAL (operands[2]) == 128
6787 || (INTVAL (operands[2]) < 0
6788 && INTVAL (operands[2]) != -128)))
6790 operands[2] = GEN_INT (-INTVAL (operands[2]));
6791 return "sub{l}\t{%2, %0|%0, %2}";
6793 return "add{l}\t{%2, %0|%0, %2}";
6797 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6798 (const_string "incdec")
6799 (const_string "alu")))
6800 (set_attr "mode" "SI")])
6802 (define_expand "addhi3"
6803 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805 (match_operand:HI 2 "general_operand" "")))]
6806 "TARGET_HIMODE_MATH"
6807 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6809 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6810 ;; type optimizations enabled by define-splits. This is not important
6811 ;; for PII, and in fact harmful because of partial register stalls.
6813 (define_insn "*addhi_1_lea"
6814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6815 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6816 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6817 (clobber (reg:CC FLAGS_REG))]
6818 "!TARGET_PARTIAL_REG_STALL
6819 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6821 switch (get_attr_type (insn))
6826 if (operands[2] == const1_rtx)
6827 return "inc{w}\t%0";
6830 gcc_assert (operands[2] == constm1_rtx);
6831 return "dec{w}\t%0";
6835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6836 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6837 if (CONST_INT_P (operands[2])
6838 && (INTVAL (operands[2]) == 128
6839 || (INTVAL (operands[2]) < 0
6840 && INTVAL (operands[2]) != -128)))
6842 operands[2] = GEN_INT (-INTVAL (operands[2]));
6843 return "sub{w}\t{%2, %0|%0, %2}";
6845 return "add{w}\t{%2, %0|%0, %2}";
6849 (if_then_else (eq_attr "alternative" "2")
6850 (const_string "lea")
6851 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6852 (const_string "incdec")
6853 (const_string "alu"))))
6854 (set_attr "mode" "HI,HI,SI")])
6856 (define_insn "*addhi_1"
6857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6858 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6859 (match_operand:HI 2 "general_operand" "rn,rm")))
6860 (clobber (reg:CC FLAGS_REG))]
6861 "TARGET_PARTIAL_REG_STALL
6862 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6864 switch (get_attr_type (insn))
6867 if (operands[2] == const1_rtx)
6868 return "inc{w}\t%0";
6871 gcc_assert (operands[2] == constm1_rtx);
6872 return "dec{w}\t%0";
6876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6878 if (CONST_INT_P (operands[2])
6879 && (INTVAL (operands[2]) == 128
6880 || (INTVAL (operands[2]) < 0
6881 && INTVAL (operands[2]) != -128)))
6883 operands[2] = GEN_INT (-INTVAL (operands[2]));
6884 return "sub{w}\t{%2, %0|%0, %2}";
6886 return "add{w}\t{%2, %0|%0, %2}";
6890 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6891 (const_string "incdec")
6892 (const_string "alu")))
6893 (set_attr "mode" "HI")])
6895 (define_insn "*addhi_2"
6896 [(set (reg FLAGS_REG)
6898 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6899 (match_operand:HI 2 "general_operand" "rmn,rn"))
6901 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6902 (plus:HI (match_dup 1) (match_dup 2)))]
6903 "ix86_match_ccmode (insn, CCGOCmode)
6904 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6906 switch (get_attr_type (insn))
6909 if (operands[2] == const1_rtx)
6910 return "inc{w}\t%0";
6913 gcc_assert (operands[2] == constm1_rtx);
6914 return "dec{w}\t%0";
6918 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6919 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6920 if (CONST_INT_P (operands[2])
6921 && (INTVAL (operands[2]) == 128
6922 || (INTVAL (operands[2]) < 0
6923 && INTVAL (operands[2]) != -128)))
6925 operands[2] = GEN_INT (-INTVAL (operands[2]));
6926 return "sub{w}\t{%2, %0|%0, %2}";
6928 return "add{w}\t{%2, %0|%0, %2}";
6932 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6933 (const_string "incdec")
6934 (const_string "alu")))
6935 (set_attr "mode" "HI")])
6937 (define_insn "*addhi_3"
6938 [(set (reg FLAGS_REG)
6939 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6940 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6941 (clobber (match_scratch:HI 0 "=r"))]
6942 "ix86_match_ccmode (insn, CCZmode)
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945 switch (get_attr_type (insn))
6948 if (operands[2] == const1_rtx)
6949 return "inc{w}\t%0";
6952 gcc_assert (operands[2] == constm1_rtx);
6953 return "dec{w}\t%0";
6957 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6958 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6959 if (CONST_INT_P (operands[2])
6960 && (INTVAL (operands[2]) == 128
6961 || (INTVAL (operands[2]) < 0
6962 && INTVAL (operands[2]) != -128)))
6964 operands[2] = GEN_INT (-INTVAL (operands[2]));
6965 return "sub{w}\t{%2, %0|%0, %2}";
6967 return "add{w}\t{%2, %0|%0, %2}";
6971 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6972 (const_string "incdec")
6973 (const_string "alu")))
6974 (set_attr "mode" "HI")])
6976 ; See comments above addsi_4 for details.
6977 (define_insn "*addhi_4"
6978 [(set (reg FLAGS_REG)
6979 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6980 (match_operand:HI 2 "const_int_operand" "n")))
6981 (clobber (match_scratch:HI 0 "=rm"))]
6982 "ix86_match_ccmode (insn, CCGCmode)
6983 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6985 switch (get_attr_type (insn))
6988 if (operands[2] == constm1_rtx)
6989 return "inc{w}\t%0";
6992 gcc_assert (operands[2] == const1_rtx);
6993 return "dec{w}\t%0";
6997 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6998 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7000 if ((INTVAL (operands[2]) == -128
7001 || (INTVAL (operands[2]) > 0
7002 && INTVAL (operands[2]) != 128)))
7003 return "sub{w}\t{%2, %0|%0, %2}";
7004 operands[2] = GEN_INT (-INTVAL (operands[2]));
7005 return "add{w}\t{%2, %0|%0, %2}";
7009 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7010 (const_string "incdec")
7011 (const_string "alu")))
7012 (set_attr "mode" "SI")])
7015 (define_insn "*addhi_5"
7016 [(set (reg FLAGS_REG)
7018 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019 (match_operand:HI 2 "general_operand" "rmn"))
7021 (clobber (match_scratch:HI 0 "=r"))]
7022 "ix86_match_ccmode (insn, CCGOCmode)
7023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7025 switch (get_attr_type (insn))
7028 if (operands[2] == const1_rtx)
7029 return "inc{w}\t%0";
7032 gcc_assert (operands[2] == constm1_rtx);
7033 return "dec{w}\t%0";
7037 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7038 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7039 if (CONST_INT_P (operands[2])
7040 && (INTVAL (operands[2]) == 128
7041 || (INTVAL (operands[2]) < 0
7042 && INTVAL (operands[2]) != -128)))
7044 operands[2] = GEN_INT (-INTVAL (operands[2]));
7045 return "sub{w}\t{%2, %0|%0, %2}";
7047 return "add{w}\t{%2, %0|%0, %2}";
7051 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052 (const_string "incdec")
7053 (const_string "alu")))
7054 (set_attr "mode" "HI")])
7056 (define_expand "addqi3"
7057 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7058 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7059 (match_operand:QI 2 "general_operand" "")))]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7063 ;; %%% Potential partial reg stall on alternative 2. What to do?
7064 (define_insn "*addqi_1_lea"
7065 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7066 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7067 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7068 (clobber (reg:CC FLAGS_REG))]
7069 "!TARGET_PARTIAL_REG_STALL
7070 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7072 int widen = (which_alternative == 2);
7073 switch (get_attr_type (insn))
7078 if (operands[2] == const1_rtx)
7079 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7082 gcc_assert (operands[2] == constm1_rtx);
7083 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7087 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7088 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7089 if (CONST_INT_P (operands[2])
7090 && (INTVAL (operands[2]) == 128
7091 || (INTVAL (operands[2]) < 0
7092 && INTVAL (operands[2]) != -128)))
7094 operands[2] = GEN_INT (-INTVAL (operands[2]));
7096 return "sub{l}\t{%2, %k0|%k0, %2}";
7098 return "sub{b}\t{%2, %0|%0, %2}";
7101 return "add{l}\t{%k2, %k0|%k0, %k2}";
7103 return "add{b}\t{%2, %0|%0, %2}";
7107 (if_then_else (eq_attr "alternative" "3")
7108 (const_string "lea")
7109 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7110 (const_string "incdec")
7111 (const_string "alu"))))
7112 (set_attr "mode" "QI,QI,SI,SI")])
7114 (define_insn "*addqi_1"
7115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7116 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7117 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7118 (clobber (reg:CC FLAGS_REG))]
7119 "TARGET_PARTIAL_REG_STALL
7120 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7122 int widen = (which_alternative == 2);
7123 switch (get_attr_type (insn))
7126 if (operands[2] == const1_rtx)
7127 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7130 gcc_assert (operands[2] == constm1_rtx);
7131 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7135 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7136 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7137 if (CONST_INT_P (operands[2])
7138 && (INTVAL (operands[2]) == 128
7139 || (INTVAL (operands[2]) < 0
7140 && INTVAL (operands[2]) != -128)))
7142 operands[2] = GEN_INT (-INTVAL (operands[2]));
7144 return "sub{l}\t{%2, %k0|%k0, %2}";
7146 return "sub{b}\t{%2, %0|%0, %2}";
7149 return "add{l}\t{%k2, %k0|%k0, %k2}";
7151 return "add{b}\t{%2, %0|%0, %2}";
7155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156 (const_string "incdec")
7157 (const_string "alu")))
7158 (set_attr "mode" "QI,QI,SI")])
7160 (define_insn "*addqi_1_slp"
7161 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7162 (plus:QI (match_dup 0)
7163 (match_operand:QI 1 "general_operand" "qn,qnm")))
7164 (clobber (reg:CC FLAGS_REG))]
7165 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7168 switch (get_attr_type (insn))
7171 if (operands[1] == const1_rtx)
7172 return "inc{b}\t%0";
7175 gcc_assert (operands[1] == constm1_rtx);
7176 return "dec{b}\t%0";
7180 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7181 if (CONST_INT_P (operands[1])
7182 && INTVAL (operands[1]) < 0)
7184 operands[1] = GEN_INT (-INTVAL (operands[1]));
7185 return "sub{b}\t{%1, %0|%0, %1}";
7187 return "add{b}\t{%1, %0|%0, %1}";
7191 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7192 (const_string "incdec")
7193 (const_string "alu1")))
7194 (set (attr "memory")
7195 (if_then_else (match_operand 1 "memory_operand" "")
7196 (const_string "load")
7197 (const_string "none")))
7198 (set_attr "mode" "QI")])
7200 (define_insn "*addqi_2"
7201 [(set (reg FLAGS_REG)
7203 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7204 (match_operand:QI 2 "general_operand" "qmn,qn"))
7206 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7207 (plus:QI (match_dup 1) (match_dup 2)))]
7208 "ix86_match_ccmode (insn, CCGOCmode)
7209 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7211 switch (get_attr_type (insn))
7214 if (operands[2] == const1_rtx)
7215 return "inc{b}\t%0";
7218 gcc_assert (operands[2] == constm1_rtx
7219 || (CONST_INT_P (operands[2])
7220 && INTVAL (operands[2]) == 255));
7221 return "dec{b}\t%0";
7225 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7226 if (CONST_INT_P (operands[2])
7227 && INTVAL (operands[2]) < 0)
7229 operands[2] = GEN_INT (-INTVAL (operands[2]));
7230 return "sub{b}\t{%2, %0|%0, %2}";
7232 return "add{b}\t{%2, %0|%0, %2}";
7236 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7237 (const_string "incdec")
7238 (const_string "alu")))
7239 (set_attr "mode" "QI")])
7241 (define_insn "*addqi_3"
7242 [(set (reg FLAGS_REG)
7243 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7244 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7245 (clobber (match_scratch:QI 0 "=q"))]
7246 "ix86_match_ccmode (insn, CCZmode)
7247 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7249 switch (get_attr_type (insn))
7252 if (operands[2] == const1_rtx)
7253 return "inc{b}\t%0";
7256 gcc_assert (operands[2] == constm1_rtx
7257 || (CONST_INT_P (operands[2])
7258 && INTVAL (operands[2]) == 255));
7259 return "dec{b}\t%0";
7263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7264 if (CONST_INT_P (operands[2])
7265 && INTVAL (operands[2]) < 0)
7267 operands[2] = GEN_INT (-INTVAL (operands[2]));
7268 return "sub{b}\t{%2, %0|%0, %2}";
7270 return "add{b}\t{%2, %0|%0, %2}";
7274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7275 (const_string "incdec")
7276 (const_string "alu")))
7277 (set_attr "mode" "QI")])
7279 ; See comments above addsi_4 for details.
7280 (define_insn "*addqi_4"
7281 [(set (reg FLAGS_REG)
7282 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7283 (match_operand:QI 2 "const_int_operand" "n")))
7284 (clobber (match_scratch:QI 0 "=qm"))]
7285 "ix86_match_ccmode (insn, CCGCmode)
7286 && (INTVAL (operands[2]) & 0xff) != 0x80"
7288 switch (get_attr_type (insn))
7291 if (operands[2] == constm1_rtx
7292 || (CONST_INT_P (operands[2])
7293 && INTVAL (operands[2]) == 255))
7294 return "inc{b}\t%0";
7297 gcc_assert (operands[2] == const1_rtx);
7298 return "dec{b}\t%0";
7302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7303 if (INTVAL (operands[2]) < 0)
7305 operands[2] = GEN_INT (-INTVAL (operands[2]));
7306 return "add{b}\t{%2, %0|%0, %2}";
7308 return "sub{b}\t{%2, %0|%0, %2}";
7312 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7313 (const_string "incdec")
7314 (const_string "alu")))
7315 (set_attr "mode" "QI")])
7318 (define_insn "*addqi_5"
7319 [(set (reg FLAGS_REG)
7321 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7322 (match_operand:QI 2 "general_operand" "qmn"))
7324 (clobber (match_scratch:QI 0 "=q"))]
7325 "ix86_match_ccmode (insn, CCGOCmode)
7326 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7328 switch (get_attr_type (insn))
7331 if (operands[2] == const1_rtx)
7332 return "inc{b}\t%0";
7335 gcc_assert (operands[2] == constm1_rtx
7336 || (CONST_INT_P (operands[2])
7337 && INTVAL (operands[2]) == 255));
7338 return "dec{b}\t%0";
7342 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7343 if (CONST_INT_P (operands[2])
7344 && INTVAL (operands[2]) < 0)
7346 operands[2] = GEN_INT (-INTVAL (operands[2]));
7347 return "sub{b}\t{%2, %0|%0, %2}";
7349 return "add{b}\t{%2, %0|%0, %2}";
7353 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7354 (const_string "incdec")
7355 (const_string "alu")))
7356 (set_attr "mode" "QI")])
7359 (define_insn "addqi_ext_1"
7360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7365 (match_operand 1 "ext_register_operand" "0")
7368 (match_operand:QI 2 "general_operand" "Qmn")))
7369 (clobber (reg:CC FLAGS_REG))]
7372 switch (get_attr_type (insn))
7375 if (operands[2] == const1_rtx)
7376 return "inc{b}\t%h0";
7379 gcc_assert (operands[2] == constm1_rtx
7380 || (CONST_INT_P (operands[2])
7381 && INTVAL (operands[2]) == 255));
7382 return "dec{b}\t%h0";
7386 return "add{b}\t{%2, %h0|%h0, %2}";
7390 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7391 (const_string "incdec")
7392 (const_string "alu")))
7393 (set_attr "mode" "QI")])
7395 (define_insn "*addqi_ext_1_rex64"
7396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7401 (match_operand 1 "ext_register_operand" "0")
7404 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7405 (clobber (reg:CC FLAGS_REG))]
7408 switch (get_attr_type (insn))
7411 if (operands[2] == const1_rtx)
7412 return "inc{b}\t%h0";
7415 gcc_assert (operands[2] == constm1_rtx
7416 || (CONST_INT_P (operands[2])
7417 && INTVAL (operands[2]) == 255));
7418 return "dec{b}\t%h0";
7422 return "add{b}\t{%2, %h0|%h0, %2}";
7426 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7427 (const_string "incdec")
7428 (const_string "alu")))
7429 (set_attr "mode" "QI")])
7431 (define_insn "*addqi_ext_2"
7432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7437 (match_operand 1 "ext_register_operand" "%0")
7441 (match_operand 2 "ext_register_operand" "Q")
7444 (clobber (reg:CC FLAGS_REG))]
7446 "add{b}\t{%h2, %h0|%h0, %h2}"
7447 [(set_attr "type" "alu")
7448 (set_attr "mode" "QI")])
7450 ;; The patterns that match these are at the end of this file.
7452 (define_expand "addxf3"
7453 [(set (match_operand:XF 0 "register_operand" "")
7454 (plus:XF (match_operand:XF 1 "register_operand" "")
7455 (match_operand:XF 2 "register_operand" "")))]
7459 (define_expand "add<mode>3"
7460 [(set (match_operand:MODEF 0 "register_operand" "")
7461 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7462 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7466 ;; Subtract instructions
7468 ;; %%% splits for subditi3
7470 (define_expand "subti3"
7471 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7472 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7473 (match_operand:TI 2 "x86_64_general_operand" "")))]
7475 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7477 (define_insn "*subti3_1"
7478 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7479 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7480 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
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" "")))
7489 (clobber (reg:CC FLAGS_REG))]
7490 "TARGET_64BIT && reload_completed"
7491 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7492 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7493 (parallel [(set (match_dup 3)
7494 (minus:DI (match_dup 4)
7495 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7497 (clobber (reg:CC FLAGS_REG))])]
7498 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7500 ;; %%% splits for subsidi3
7502 (define_expand "subdi3"
7503 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7504 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7505 (match_operand:DI 2 "x86_64_general_operand" "")))]
7507 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7509 (define_insn "*subdi3_1"
7510 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7511 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7512 (match_operand:DI 2 "general_operand" "roiF,riF")))
7513 (clobber (reg:CC FLAGS_REG))]
7514 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7518 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520 (match_operand:DI 2 "general_operand" "")))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "!TARGET_64BIT && reload_completed"
7523 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7525 (parallel [(set (match_dup 3)
7526 (minus:SI (match_dup 4)
7527 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7529 (clobber (reg:CC FLAGS_REG))])]
7530 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7532 (define_insn "subdi3_carry_rex64"
7533 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7535 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7536 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7539 "sbb{q}\t{%2, %0|%0, %2}"
7540 [(set_attr "type" "alu")
7541 (set_attr "pent_pair" "pu")
7542 (set_attr "mode" "DI")])
7544 (define_insn "*subdi_1_rex64"
7545 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7546 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7547 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7548 (clobber (reg:CC FLAGS_REG))]
7549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7550 "sub{q}\t{%2, %0|%0, %2}"
7551 [(set_attr "type" "alu")
7552 (set_attr "mode" "DI")])
7554 (define_insn "*subdi_2_rex64"
7555 [(set (reg FLAGS_REG)
7557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7558 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7560 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561 (minus:DI (match_dup 1) (match_dup 2)))]
7562 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7563 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7564 "sub{q}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "DI")])
7568 (define_insn "*subdi_3_rex63"
7569 [(set (reg FLAGS_REG)
7570 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7571 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7572 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7573 (minus:DI (match_dup 1) (match_dup 2)))]
7574 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7575 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7576 "sub{q}\t{%2, %0|%0, %2}"
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "DI")])
7580 (define_insn "subqi3_carry"
7581 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7582 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7583 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7584 (match_operand:QI 2 "general_operand" "qn,qm"))))
7585 (clobber (reg:CC FLAGS_REG))]
7586 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7587 "sbb{b}\t{%2, %0|%0, %2}"
7588 [(set_attr "type" "alu")
7589 (set_attr "pent_pair" "pu")
7590 (set_attr "mode" "QI")])
7592 (define_insn "subhi3_carry"
7593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7594 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7595 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7596 (match_operand:HI 2 "general_operand" "rn,rm"))))
7597 (clobber (reg:CC FLAGS_REG))]
7598 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7599 "sbb{w}\t{%2, %0|%0, %2}"
7600 [(set_attr "type" "alu")
7601 (set_attr "pent_pair" "pu")
7602 (set_attr "mode" "HI")])
7604 (define_insn "subsi3_carry"
7605 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7606 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7607 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7608 (match_operand:SI 2 "general_operand" "ri,rm"))))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7611 "sbb{l}\t{%2, %0|%0, %2}"
7612 [(set_attr "type" "alu")
7613 (set_attr "pent_pair" "pu")
7614 (set_attr "mode" "SI")])
7616 (define_insn "subsi3_carry_zext"
7617 [(set (match_operand:DI 0 "register_operand" "=r")
7619 (minus:SI (match_operand:SI 1 "register_operand" "0")
7620 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7621 (match_operand:SI 2 "general_operand" "g")))))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7624 "sbb{l}\t{%2, %k0|%k0, %2}"
7625 [(set_attr "type" "alu")
7626 (set_attr "pent_pair" "pu")
7627 (set_attr "mode" "SI")])
7629 (define_expand "subsi3"
7630 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7631 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7632 (match_operand:SI 2 "general_operand" "")))]
7634 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7636 (define_insn "*subsi_1"
7637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639 (match_operand:SI 2 "general_operand" "ri,rm")))
7640 (clobber (reg:CC FLAGS_REG))]
7641 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7642 "sub{l}\t{%2, %0|%0, %2}"
7643 [(set_attr "type" "alu")
7644 (set_attr "mode" "SI")])
7646 (define_insn "*subsi_1_zext"
7647 [(set (match_operand:DI 0 "register_operand" "=r")
7649 (minus:SI (match_operand:SI 1 "register_operand" "0")
7650 (match_operand:SI 2 "general_operand" "g"))))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7653 "sub{l}\t{%2, %k0|%k0, %2}"
7654 [(set_attr "type" "alu")
7655 (set_attr "mode" "SI")])
7657 (define_insn "*subsi_2"
7658 [(set (reg FLAGS_REG)
7660 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7661 (match_operand:SI 2 "general_operand" "ri,rm"))
7663 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7664 (minus:SI (match_dup 1) (match_dup 2)))]
7665 "ix86_match_ccmode (insn, CCGOCmode)
7666 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7667 "sub{l}\t{%2, %0|%0, %2}"
7668 [(set_attr "type" "alu")
7669 (set_attr "mode" "SI")])
7671 (define_insn "*subsi_2_zext"
7672 [(set (reg FLAGS_REG)
7674 (minus:SI (match_operand:SI 1 "register_operand" "0")
7675 (match_operand:SI 2 "general_operand" "g"))
7677 (set (match_operand:DI 0 "register_operand" "=r")
7679 (minus:SI (match_dup 1)
7681 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7682 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7683 "sub{l}\t{%2, %k0|%k0, %2}"
7684 [(set_attr "type" "alu")
7685 (set_attr "mode" "SI")])
7687 (define_insn "*subsi_3"
7688 [(set (reg FLAGS_REG)
7689 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7690 (match_operand:SI 2 "general_operand" "ri,rm")))
7691 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7692 (minus:SI (match_dup 1) (match_dup 2)))]
7693 "ix86_match_ccmode (insn, CCmode)
7694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695 "sub{l}\t{%2, %0|%0, %2}"
7696 [(set_attr "type" "alu")
7697 (set_attr "mode" "SI")])
7699 (define_insn "*subsi_3_zext"
7700 [(set (reg FLAGS_REG)
7701 (compare (match_operand:SI 1 "register_operand" "0")
7702 (match_operand:SI 2 "general_operand" "g")))
7703 (set (match_operand:DI 0 "register_operand" "=r")
7705 (minus:SI (match_dup 1)
7707 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7708 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709 "sub{l}\t{%2, %1|%1, %2}"
7710 [(set_attr "type" "alu")
7711 (set_attr "mode" "DI")])
7713 (define_expand "subhi3"
7714 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7715 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7716 (match_operand:HI 2 "general_operand" "")))]
7717 "TARGET_HIMODE_MATH"
7718 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7720 (define_insn "*subhi_1"
7721 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7722 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7723 (match_operand:HI 2 "general_operand" "rn,rm")))
7724 (clobber (reg:CC FLAGS_REG))]
7725 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7726 "sub{w}\t{%2, %0|%0, %2}"
7727 [(set_attr "type" "alu")
7728 (set_attr "mode" "HI")])
7730 (define_insn "*subhi_2"
7731 [(set (reg FLAGS_REG)
7733 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7734 (match_operand:HI 2 "general_operand" "rn,rm"))
7736 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737 (minus:HI (match_dup 1) (match_dup 2)))]
7738 "ix86_match_ccmode (insn, CCGOCmode)
7739 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7740 "sub{w}\t{%2, %0|%0, %2}"
7741 [(set_attr "type" "alu")
7742 (set_attr "mode" "HI")])
7744 (define_insn "*subhi_3"
7745 [(set (reg FLAGS_REG)
7746 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7747 (match_operand:HI 2 "general_operand" "rn,rm")))
7748 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7749 (minus:HI (match_dup 1) (match_dup 2)))]
7750 "ix86_match_ccmode (insn, CCmode)
7751 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7752 "sub{w}\t{%2, %0|%0, %2}"
7753 [(set_attr "type" "alu")
7754 (set_attr "mode" "HI")])
7756 (define_expand "subqi3"
7757 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7758 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759 (match_operand:QI 2 "general_operand" "")))]
7760 "TARGET_QIMODE_MATH"
7761 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7763 (define_insn "*subqi_1"
7764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7765 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:QI 2 "general_operand" "qn,qm")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7769 "sub{b}\t{%2, %0|%0, %2}"
7770 [(set_attr "type" "alu")
7771 (set_attr "mode" "QI")])
7773 (define_insn "*subqi_1_slp"
7774 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7775 (minus:QI (match_dup 0)
7776 (match_operand:QI 1 "general_operand" "qn,qm")))
7777 (clobber (reg:CC FLAGS_REG))]
7778 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7780 "sub{b}\t{%1, %0|%0, %1}"
7781 [(set_attr "type" "alu1")
7782 (set_attr "mode" "QI")])
7784 (define_insn "*subqi_2"
7785 [(set (reg FLAGS_REG)
7787 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7788 (match_operand:QI 2 "general_operand" "qn,qm"))
7790 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7791 (minus:QI (match_dup 1) (match_dup 2)))]
7792 "ix86_match_ccmode (insn, CCGOCmode)
7793 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7794 "sub{b}\t{%2, %0|%0, %2}"
7795 [(set_attr "type" "alu")
7796 (set_attr "mode" "QI")])
7798 (define_insn "*subqi_3"
7799 [(set (reg FLAGS_REG)
7800 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7801 (match_operand:QI 2 "general_operand" "qn,qm")))
7802 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7803 (minus:QI (match_dup 1) (match_dup 2)))]
7804 "ix86_match_ccmode (insn, CCmode)
7805 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7806 "sub{b}\t{%2, %0|%0, %2}"
7807 [(set_attr "type" "alu")
7808 (set_attr "mode" "QI")])
7810 ;; The patterns that match these are at the end of this file.
7812 (define_expand "subxf3"
7813 [(set (match_operand:XF 0 "register_operand" "")
7814 (minus:XF (match_operand:XF 1 "register_operand" "")
7815 (match_operand:XF 2 "register_operand" "")))]
7819 (define_expand "sub<mode>3"
7820 [(set (match_operand:MODEF 0 "register_operand" "")
7821 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7822 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7826 ;; Multiply instructions
7828 (define_expand "muldi3"
7829 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7830 (mult:DI (match_operand:DI 1 "register_operand" "")
7831 (match_operand:DI 2 "x86_64_general_operand" "")))
7832 (clobber (reg:CC FLAGS_REG))])]
7837 ;; IMUL reg64, reg64, imm8 Direct
7838 ;; IMUL reg64, mem64, imm8 VectorPath
7839 ;; IMUL reg64, reg64, imm32 Direct
7840 ;; IMUL reg64, mem64, imm32 VectorPath
7841 ;; IMUL reg64, reg64 Direct
7842 ;; IMUL reg64, mem64 Direct
7844 (define_insn "*muldi3_1_rex64"
7845 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7846 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7847 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7848 (clobber (reg:CC FLAGS_REG))]
7850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7852 imul{q}\t{%2, %1, %0|%0, %1, %2}
7853 imul{q}\t{%2, %1, %0|%0, %1, %2}
7854 imul{q}\t{%2, %0|%0, %2}"
7855 [(set_attr "type" "imul")
7856 (set_attr "prefix_0f" "0,0,1")
7857 (set (attr "athlon_decode")
7858 (cond [(eq_attr "cpu" "athlon")
7859 (const_string "vector")
7860 (eq_attr "alternative" "1")
7861 (const_string "vector")
7862 (and (eq_attr "alternative" "2")
7863 (match_operand 1 "memory_operand" ""))
7864 (const_string "vector")]
7865 (const_string "direct")))
7866 (set (attr "amdfam10_decode")
7867 (cond [(and (eq_attr "alternative" "0,1")
7868 (match_operand 1 "memory_operand" ""))
7869 (const_string "vector")]
7870 (const_string "direct")))
7871 (set_attr "mode" "DI")])
7873 (define_expand "mulsi3"
7874 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875 (mult:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "general_operand" "")))
7877 (clobber (reg:CC FLAGS_REG))])]
7882 ;; IMUL reg32, reg32, imm8 Direct
7883 ;; IMUL reg32, mem32, imm8 VectorPath
7884 ;; IMUL reg32, reg32, imm32 Direct
7885 ;; IMUL reg32, mem32, imm32 VectorPath
7886 ;; IMUL reg32, reg32 Direct
7887 ;; IMUL reg32, mem32 Direct
7889 (define_insn "*mulsi3_1"
7890 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7892 (match_operand:SI 2 "general_operand" "K,i,mr")))
7893 (clobber (reg:CC FLAGS_REG))]
7894 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7896 imul{l}\t{%2, %1, %0|%0, %1, %2}
7897 imul{l}\t{%2, %1, %0|%0, %1, %2}
7898 imul{l}\t{%2, %0|%0, %2}"
7899 [(set_attr "type" "imul")
7900 (set_attr "prefix_0f" "0,0,1")
7901 (set (attr "athlon_decode")
7902 (cond [(eq_attr "cpu" "athlon")
7903 (const_string "vector")
7904 (eq_attr "alternative" "1")
7905 (const_string "vector")
7906 (and (eq_attr "alternative" "2")
7907 (match_operand 1 "memory_operand" ""))
7908 (const_string "vector")]
7909 (const_string "direct")))
7910 (set (attr "amdfam10_decode")
7911 (cond [(and (eq_attr "alternative" "0,1")
7912 (match_operand 1 "memory_operand" ""))
7913 (const_string "vector")]
7914 (const_string "direct")))
7915 (set_attr "mode" "SI")])
7917 (define_insn "*mulsi3_1_zext"
7918 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7920 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7921 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7922 (clobber (reg:CC FLAGS_REG))]
7924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928 imul{l}\t{%2, %k0|%k0, %2}"
7929 [(set_attr "type" "imul")
7930 (set_attr "prefix_0f" "0,0,1")
7931 (set (attr "athlon_decode")
7932 (cond [(eq_attr "cpu" "athlon")
7933 (const_string "vector")
7934 (eq_attr "alternative" "1")
7935 (const_string "vector")
7936 (and (eq_attr "alternative" "2")
7937 (match_operand 1 "memory_operand" ""))
7938 (const_string "vector")]
7939 (const_string "direct")))
7940 (set (attr "amdfam10_decode")
7941 (cond [(and (eq_attr "alternative" "0,1")
7942 (match_operand 1 "memory_operand" ""))
7943 (const_string "vector")]
7944 (const_string "direct")))
7945 (set_attr "mode" "SI")])
7947 (define_expand "mulhi3"
7948 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7949 (mult:HI (match_operand:HI 1 "register_operand" "")
7950 (match_operand:HI 2 "general_operand" "")))
7951 (clobber (reg:CC FLAGS_REG))])]
7952 "TARGET_HIMODE_MATH"
7956 ;; IMUL reg16, reg16, imm8 VectorPath
7957 ;; IMUL reg16, mem16, imm8 VectorPath
7958 ;; IMUL reg16, reg16, imm16 VectorPath
7959 ;; IMUL reg16, mem16, imm16 VectorPath
7960 ;; IMUL reg16, reg16 Direct
7961 ;; IMUL reg16, mem16 Direct
7962 (define_insn "*mulhi3_1"
7963 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7964 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7965 (match_operand:HI 2 "general_operand" "K,n,mr")))
7966 (clobber (reg:CC FLAGS_REG))]
7967 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969 imul{w}\t{%2, %1, %0|%0, %1, %2}
7970 imul{w}\t{%2, %1, %0|%0, %1, %2}
7971 imul{w}\t{%2, %0|%0, %2}"
7972 [(set_attr "type" "imul")
7973 (set_attr "prefix_0f" "0,0,1")
7974 (set (attr "athlon_decode")
7975 (cond [(eq_attr "cpu" "athlon")
7976 (const_string "vector")
7977 (eq_attr "alternative" "1,2")
7978 (const_string "vector")]
7979 (const_string "direct")))
7980 (set (attr "amdfam10_decode")
7981 (cond [(eq_attr "alternative" "0,1")
7982 (const_string "vector")]
7983 (const_string "direct")))
7984 (set_attr "mode" "HI")])
7986 (define_expand "mulqi3"
7987 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7988 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7989 (match_operand:QI 2 "register_operand" "")))
7990 (clobber (reg:CC FLAGS_REG))])]
7991 "TARGET_QIMODE_MATH"
7998 (define_insn "*mulqi3_1"
7999 [(set (match_operand:QI 0 "register_operand" "=a")
8000 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8001 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8002 (clobber (reg:CC FLAGS_REG))]
8004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8006 [(set_attr "type" "imul")
8007 (set_attr "length_immediate" "0")
8008 (set (attr "athlon_decode")
8009 (if_then_else (eq_attr "cpu" "athlon")
8010 (const_string "vector")
8011 (const_string "direct")))
8012 (set_attr "amdfam10_decode" "direct")
8013 (set_attr "mode" "QI")])
8015 (define_expand "umulqihi3"
8016 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8017 (mult:HI (zero_extend:HI
8018 (match_operand:QI 1 "nonimmediate_operand" ""))
8020 (match_operand:QI 2 "register_operand" ""))))
8021 (clobber (reg:CC FLAGS_REG))])]
8022 "TARGET_QIMODE_MATH"
8025 (define_insn "*umulqihi3_1"
8026 [(set (match_operand:HI 0 "register_operand" "=a")
8027 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8028 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8029 (clobber (reg:CC FLAGS_REG))]
8031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8033 [(set_attr "type" "imul")
8034 (set_attr "length_immediate" "0")
8035 (set (attr "athlon_decode")
8036 (if_then_else (eq_attr "cpu" "athlon")
8037 (const_string "vector")
8038 (const_string "direct")))
8039 (set_attr "amdfam10_decode" "direct")
8040 (set_attr "mode" "QI")])
8042 (define_expand "mulqihi3"
8043 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8044 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8045 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8046 (clobber (reg:CC FLAGS_REG))])]
8047 "TARGET_QIMODE_MATH"
8050 (define_insn "*mulqihi3_insn"
8051 [(set (match_operand:HI 0 "register_operand" "=a")
8052 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8053 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8054 (clobber (reg:CC FLAGS_REG))]
8056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8058 [(set_attr "type" "imul")
8059 (set_attr "length_immediate" "0")
8060 (set (attr "athlon_decode")
8061 (if_then_else (eq_attr "cpu" "athlon")
8062 (const_string "vector")
8063 (const_string "direct")))
8064 (set_attr "amdfam10_decode" "direct")
8065 (set_attr "mode" "QI")])
8067 (define_expand "umulditi3"
8068 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8069 (mult:TI (zero_extend:TI
8070 (match_operand:DI 1 "nonimmediate_operand" ""))
8072 (match_operand:DI 2 "register_operand" ""))))
8073 (clobber (reg:CC FLAGS_REG))])]
8077 (define_insn "*umulditi3_insn"
8078 [(set (match_operand:TI 0 "register_operand" "=A")
8079 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8080 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8081 (clobber (reg:CC FLAGS_REG))]
8083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8085 [(set_attr "type" "imul")
8086 (set_attr "length_immediate" "0")
8087 (set (attr "athlon_decode")
8088 (if_then_else (eq_attr "cpu" "athlon")
8089 (const_string "vector")
8090 (const_string "double")))
8091 (set_attr "amdfam10_decode" "double")
8092 (set_attr "mode" "DI")])
8094 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8095 (define_expand "umulsidi3"
8096 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8097 (mult:DI (zero_extend:DI
8098 (match_operand:SI 1 "nonimmediate_operand" ""))
8100 (match_operand:SI 2 "register_operand" ""))))
8101 (clobber (reg:CC FLAGS_REG))])]
8105 (define_insn "*umulsidi3_insn"
8106 [(set (match_operand:DI 0 "register_operand" "=A")
8107 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8108 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8109 (clobber (reg:CC FLAGS_REG))]
8111 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8113 [(set_attr "type" "imul")
8114 (set_attr "length_immediate" "0")
8115 (set (attr "athlon_decode")
8116 (if_then_else (eq_attr "cpu" "athlon")
8117 (const_string "vector")
8118 (const_string "double")))
8119 (set_attr "amdfam10_decode" "double")
8120 (set_attr "mode" "SI")])
8122 (define_expand "mulditi3"
8123 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8124 (mult:TI (sign_extend:TI
8125 (match_operand:DI 1 "nonimmediate_operand" ""))
8127 (match_operand:DI 2 "register_operand" ""))))
8128 (clobber (reg:CC FLAGS_REG))])]
8132 (define_insn "*mulditi3_insn"
8133 [(set (match_operand:TI 0 "register_operand" "=A")
8134 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8135 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8136 (clobber (reg:CC FLAGS_REG))]
8138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8140 [(set_attr "type" "imul")
8141 (set_attr "length_immediate" "0")
8142 (set (attr "athlon_decode")
8143 (if_then_else (eq_attr "cpu" "athlon")
8144 (const_string "vector")
8145 (const_string "double")))
8146 (set_attr "amdfam10_decode" "double")
8147 (set_attr "mode" "DI")])
8149 (define_expand "mulsidi3"
8150 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8151 (mult:DI (sign_extend:DI
8152 (match_operand:SI 1 "nonimmediate_operand" ""))
8154 (match_operand:SI 2 "register_operand" ""))))
8155 (clobber (reg:CC FLAGS_REG))])]
8159 (define_insn "*mulsidi3_insn"
8160 [(set (match_operand:DI 0 "register_operand" "=A")
8161 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8162 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8163 (clobber (reg:CC FLAGS_REG))]
8165 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8167 [(set_attr "type" "imul")
8168 (set_attr "length_immediate" "0")
8169 (set (attr "athlon_decode")
8170 (if_then_else (eq_attr "cpu" "athlon")
8171 (const_string "vector")
8172 (const_string "double")))
8173 (set_attr "amdfam10_decode" "double")
8174 (set_attr "mode" "SI")])
8176 (define_expand "umuldi3_highpart"
8177 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8180 (mult:TI (zero_extend:TI
8181 (match_operand:DI 1 "nonimmediate_operand" ""))
8183 (match_operand:DI 2 "register_operand" "")))
8185 (clobber (match_scratch:DI 3 ""))
8186 (clobber (reg:CC FLAGS_REG))])]
8190 (define_insn "*umuldi3_highpart_rex64"
8191 [(set (match_operand:DI 0 "register_operand" "=d")
8194 (mult:TI (zero_extend:TI
8195 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8197 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8199 (clobber (match_scratch:DI 3 "=1"))
8200 (clobber (reg:CC FLAGS_REG))]
8202 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8204 [(set_attr "type" "imul")
8205 (set_attr "length_immediate" "0")
8206 (set (attr "athlon_decode")
8207 (if_then_else (eq_attr "cpu" "athlon")
8208 (const_string "vector")
8209 (const_string "double")))
8210 (set_attr "amdfam10_decode" "double")
8211 (set_attr "mode" "DI")])
8213 (define_expand "umulsi3_highpart"
8214 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8217 (mult:DI (zero_extend:DI
8218 (match_operand:SI 1 "nonimmediate_operand" ""))
8220 (match_operand:SI 2 "register_operand" "")))
8222 (clobber (match_scratch:SI 3 ""))
8223 (clobber (reg:CC FLAGS_REG))])]
8227 (define_insn "*umulsi3_highpart_insn"
8228 [(set (match_operand:SI 0 "register_operand" "=d")
8231 (mult:DI (zero_extend:DI
8232 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8234 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8236 (clobber (match_scratch:SI 3 "=1"))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8240 [(set_attr "type" "imul")
8241 (set_attr "length_immediate" "0")
8242 (set (attr "athlon_decode")
8243 (if_then_else (eq_attr "cpu" "athlon")
8244 (const_string "vector")
8245 (const_string "double")))
8246 (set_attr "amdfam10_decode" "double")
8247 (set_attr "mode" "SI")])
8249 (define_insn "*umulsi3_highpart_zext"
8250 [(set (match_operand:DI 0 "register_operand" "=d")
8251 (zero_extend:DI (truncate:SI
8253 (mult:DI (zero_extend:DI
8254 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8256 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8258 (clobber (match_scratch:SI 3 "=1"))
8259 (clobber (reg:CC FLAGS_REG))]
8261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8263 [(set_attr "type" "imul")
8264 (set_attr "length_immediate" "0")
8265 (set (attr "athlon_decode")
8266 (if_then_else (eq_attr "cpu" "athlon")
8267 (const_string "vector")
8268 (const_string "double")))
8269 (set_attr "amdfam10_decode" "double")
8270 (set_attr "mode" "SI")])
8272 (define_expand "smuldi3_highpart"
8273 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8276 (mult:TI (sign_extend:TI
8277 (match_operand:DI 1 "nonimmediate_operand" ""))
8279 (match_operand:DI 2 "register_operand" "")))
8281 (clobber (match_scratch:DI 3 ""))
8282 (clobber (reg:CC FLAGS_REG))])]
8286 (define_insn "*smuldi3_highpart_rex64"
8287 [(set (match_operand:DI 0 "register_operand" "=d")
8290 (mult:TI (sign_extend:TI
8291 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8293 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8295 (clobber (match_scratch:DI 3 "=1"))
8296 (clobber (reg:CC FLAGS_REG))]
8298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8300 [(set_attr "type" "imul")
8301 (set (attr "athlon_decode")
8302 (if_then_else (eq_attr "cpu" "athlon")
8303 (const_string "vector")
8304 (const_string "double")))
8305 (set_attr "amdfam10_decode" "double")
8306 (set_attr "mode" "DI")])
8308 (define_expand "smulsi3_highpart"
8309 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8312 (mult:DI (sign_extend:DI
8313 (match_operand:SI 1 "nonimmediate_operand" ""))
8315 (match_operand:SI 2 "register_operand" "")))
8317 (clobber (match_scratch:SI 3 ""))
8318 (clobber (reg:CC FLAGS_REG))])]
8322 (define_insn "*smulsi3_highpart_insn"
8323 [(set (match_operand:SI 0 "register_operand" "=d")
8326 (mult:DI (sign_extend:DI
8327 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8329 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8331 (clobber (match_scratch:SI 3 "=1"))
8332 (clobber (reg:CC FLAGS_REG))]
8333 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8335 [(set_attr "type" "imul")
8336 (set (attr "athlon_decode")
8337 (if_then_else (eq_attr "cpu" "athlon")
8338 (const_string "vector")
8339 (const_string "double")))
8340 (set_attr "amdfam10_decode" "double")
8341 (set_attr "mode" "SI")])
8343 (define_insn "*smulsi3_highpart_zext"
8344 [(set (match_operand:DI 0 "register_operand" "=d")
8345 (zero_extend:DI (truncate:SI
8347 (mult:DI (sign_extend:DI
8348 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8350 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8352 (clobber (match_scratch:SI 3 "=1"))
8353 (clobber (reg:CC FLAGS_REG))]
8355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8357 [(set_attr "type" "imul")
8358 (set (attr "athlon_decode")
8359 (if_then_else (eq_attr "cpu" "athlon")
8360 (const_string "vector")
8361 (const_string "double")))
8362 (set_attr "amdfam10_decode" "double")
8363 (set_attr "mode" "SI")])
8365 ;; The patterns that match these are at the end of this file.
8367 (define_expand "mulxf3"
8368 [(set (match_operand:XF 0 "register_operand" "")
8369 (mult:XF (match_operand:XF 1 "register_operand" "")
8370 (match_operand:XF 2 "register_operand" "")))]
8374 (define_expand "mul<mode>3"
8375 [(set (match_operand:MODEF 0 "register_operand" "")
8376 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8377 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8378 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8381 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8384 ;; Divide instructions
8386 (define_insn "divqi3"
8387 [(set (match_operand:QI 0 "register_operand" "=a")
8388 (div:QI (match_operand:HI 1 "register_operand" "0")
8389 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "TARGET_QIMODE_MATH"
8393 [(set_attr "type" "idiv")
8394 (set_attr "mode" "QI")])
8396 (define_insn "udivqi3"
8397 [(set (match_operand:QI 0 "register_operand" "=a")
8398 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400 (clobber (reg:CC FLAGS_REG))]
8401 "TARGET_QIMODE_MATH"
8403 [(set_attr "type" "idiv")
8404 (set_attr "mode" "QI")])
8406 ;; The patterns that match these are at the end of this file.
8408 (define_expand "divxf3"
8409 [(set (match_operand:XF 0 "register_operand" "")
8410 (div:XF (match_operand:XF 1 "register_operand" "")
8411 (match_operand:XF 2 "register_operand" "")))]
8415 (define_expand "divdf3"
8416 [(set (match_operand:DF 0 "register_operand" "")
8417 (div:DF (match_operand:DF 1 "register_operand" "")
8418 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8422 (define_expand "divsf3"
8423 [(set (match_operand:SF 0 "register_operand" "")
8424 (div:SF (match_operand:SF 1 "register_operand" "")
8425 (match_operand:SF 2 "nonimmediate_operand" "")))]
8426 "TARGET_80387 || TARGET_SSE_MATH"
8428 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8429 && flag_finite_math_only && !flag_trapping_math
8430 && flag_unsafe_math_optimizations)
8432 ix86_emit_swdivsf (operands[0], operands[1],
8433 operands[2], SFmode);
8438 ;; Remainder instructions.
8440 (define_expand "divmoddi4"
8441 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8442 (div:DI (match_operand:DI 1 "register_operand" "")
8443 (match_operand:DI 2 "nonimmediate_operand" "")))
8444 (set (match_operand:DI 3 "register_operand" "")
8445 (mod:DI (match_dup 1) (match_dup 2)))
8446 (clobber (reg:CC FLAGS_REG))])]
8450 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8451 ;; Penalize eax case slightly because it results in worse scheduling
8453 (define_insn "*divmoddi4_nocltd_rex64"
8454 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8455 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8456 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8457 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8458 (mod:DI (match_dup 2) (match_dup 3)))
8459 (clobber (reg:CC FLAGS_REG))]
8460 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8462 [(set_attr "type" "multi")])
8464 (define_insn "*divmoddi4_cltd_rex64"
8465 [(set (match_operand:DI 0 "register_operand" "=a")
8466 (div:DI (match_operand:DI 2 "register_operand" "a")
8467 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8468 (set (match_operand:DI 1 "register_operand" "=&d")
8469 (mod:DI (match_dup 2) (match_dup 3)))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8473 [(set_attr "type" "multi")])
8475 (define_insn "*divmoddi_noext_rex64"
8476 [(set (match_operand:DI 0 "register_operand" "=a")
8477 (div:DI (match_operand:DI 1 "register_operand" "0")
8478 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8479 (set (match_operand:DI 3 "register_operand" "=d")
8480 (mod:DI (match_dup 1) (match_dup 2)))
8481 (use (match_operand:DI 4 "register_operand" "3"))
8482 (clobber (reg:CC FLAGS_REG))]
8485 [(set_attr "type" "idiv")
8486 (set_attr "mode" "DI")])
8489 [(set (match_operand:DI 0 "register_operand" "")
8490 (div:DI (match_operand:DI 1 "register_operand" "")
8491 (match_operand:DI 2 "nonimmediate_operand" "")))
8492 (set (match_operand:DI 3 "register_operand" "")
8493 (mod:DI (match_dup 1) (match_dup 2)))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "TARGET_64BIT && reload_completed"
8496 [(parallel [(set (match_dup 3)
8497 (ashiftrt:DI (match_dup 4) (const_int 63)))
8498 (clobber (reg:CC FLAGS_REG))])
8499 (parallel [(set (match_dup 0)
8500 (div:DI (reg:DI 0) (match_dup 2)))
8502 (mod:DI (reg:DI 0) (match_dup 2)))
8504 (clobber (reg:CC FLAGS_REG))])]
8506 /* Avoid use of cltd in favor of a mov+shift. */
8507 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8509 if (true_regnum (operands[1]))
8510 emit_move_insn (operands[0], operands[1]);
8512 emit_move_insn (operands[3], operands[1]);
8513 operands[4] = operands[3];
8517 gcc_assert (!true_regnum (operands[1]));
8518 operands[4] = operands[1];
8523 (define_expand "divmodsi4"
8524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8525 (div:SI (match_operand:SI 1 "register_operand" "")
8526 (match_operand:SI 2 "nonimmediate_operand" "")))
8527 (set (match_operand:SI 3 "register_operand" "")
8528 (mod:SI (match_dup 1) (match_dup 2)))
8529 (clobber (reg:CC FLAGS_REG))])]
8533 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8534 ;; Penalize eax case slightly because it results in worse scheduling
8536 (define_insn "*divmodsi4_nocltd"
8537 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8538 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8539 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8540 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8541 (mod:SI (match_dup 2) (match_dup 3)))
8542 (clobber (reg:CC FLAGS_REG))]
8543 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8545 [(set_attr "type" "multi")])
8547 (define_insn "*divmodsi4_cltd"
8548 [(set (match_operand:SI 0 "register_operand" "=a")
8549 (div:SI (match_operand:SI 2 "register_operand" "a")
8550 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8551 (set (match_operand:SI 1 "register_operand" "=&d")
8552 (mod:SI (match_dup 2) (match_dup 3)))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8556 [(set_attr "type" "multi")])
8558 (define_insn "*divmodsi_noext"
8559 [(set (match_operand:SI 0 "register_operand" "=a")
8560 (div:SI (match_operand:SI 1 "register_operand" "0")
8561 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8562 (set (match_operand:SI 3 "register_operand" "=d")
8563 (mod:SI (match_dup 1) (match_dup 2)))
8564 (use (match_operand:SI 4 "register_operand" "3"))
8565 (clobber (reg:CC FLAGS_REG))]
8568 [(set_attr "type" "idiv")
8569 (set_attr "mode" "SI")])
8572 [(set (match_operand:SI 0 "register_operand" "")
8573 (div:SI (match_operand:SI 1 "register_operand" "")
8574 (match_operand:SI 2 "nonimmediate_operand" "")))
8575 (set (match_operand:SI 3 "register_operand" "")
8576 (mod:SI (match_dup 1) (match_dup 2)))
8577 (clobber (reg:CC FLAGS_REG))]
8579 [(parallel [(set (match_dup 3)
8580 (ashiftrt:SI (match_dup 4) (const_int 31)))
8581 (clobber (reg:CC FLAGS_REG))])
8582 (parallel [(set (match_dup 0)
8583 (div:SI (reg:SI 0) (match_dup 2)))
8585 (mod:SI (reg:SI 0) (match_dup 2)))
8587 (clobber (reg:CC FLAGS_REG))])]
8589 /* Avoid use of cltd in favor of a mov+shift. */
8590 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8592 if (true_regnum (operands[1]))
8593 emit_move_insn (operands[0], operands[1]);
8595 emit_move_insn (operands[3], operands[1]);
8596 operands[4] = operands[3];
8600 gcc_assert (!true_regnum (operands[1]));
8601 operands[4] = operands[1];
8605 (define_insn "divmodhi4"
8606 [(set (match_operand:HI 0 "register_operand" "=a")
8607 (div:HI (match_operand:HI 1 "register_operand" "0")
8608 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8609 (set (match_operand:HI 3 "register_operand" "=&d")
8610 (mod:HI (match_dup 1) (match_dup 2)))
8611 (clobber (reg:CC FLAGS_REG))]
8612 "TARGET_HIMODE_MATH"
8614 [(set_attr "type" "multi")
8615 (set_attr "length_immediate" "0")
8616 (set_attr "mode" "SI")])
8618 (define_insn "udivmoddi4"
8619 [(set (match_operand:DI 0 "register_operand" "=a")
8620 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8621 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8622 (set (match_operand:DI 3 "register_operand" "=&d")
8623 (umod:DI (match_dup 1) (match_dup 2)))
8624 (clobber (reg:CC FLAGS_REG))]
8626 "xor{q}\t%3, %3\;div{q}\t%2"
8627 [(set_attr "type" "multi")
8628 (set_attr "length_immediate" "0")
8629 (set_attr "mode" "DI")])
8631 (define_insn "*udivmoddi4_noext"
8632 [(set (match_operand:DI 0 "register_operand" "=a")
8633 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8634 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8635 (set (match_operand:DI 3 "register_operand" "=d")
8636 (umod:DI (match_dup 1) (match_dup 2)))
8638 (clobber (reg:CC FLAGS_REG))]
8641 [(set_attr "type" "idiv")
8642 (set_attr "mode" "DI")])
8645 [(set (match_operand:DI 0 "register_operand" "")
8646 (udiv:DI (match_operand:DI 1 "register_operand" "")
8647 (match_operand:DI 2 "nonimmediate_operand" "")))
8648 (set (match_operand:DI 3 "register_operand" "")
8649 (umod:DI (match_dup 1) (match_dup 2)))
8650 (clobber (reg:CC FLAGS_REG))]
8651 "TARGET_64BIT && reload_completed"
8652 [(set (match_dup 3) (const_int 0))
8653 (parallel [(set (match_dup 0)
8654 (udiv:DI (match_dup 1) (match_dup 2)))
8656 (umod:DI (match_dup 1) (match_dup 2)))
8658 (clobber (reg:CC FLAGS_REG))])]
8661 (define_insn "udivmodsi4"
8662 [(set (match_operand:SI 0 "register_operand" "=a")
8663 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8664 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8665 (set (match_operand:SI 3 "register_operand" "=&d")
8666 (umod:SI (match_dup 1) (match_dup 2)))
8667 (clobber (reg:CC FLAGS_REG))]
8669 "xor{l}\t%3, %3\;div{l}\t%2"
8670 [(set_attr "type" "multi")
8671 (set_attr "length_immediate" "0")
8672 (set_attr "mode" "SI")])
8674 (define_insn "*udivmodsi4_noext"
8675 [(set (match_operand:SI 0 "register_operand" "=a")
8676 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8677 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8678 (set (match_operand:SI 3 "register_operand" "=d")
8679 (umod:SI (match_dup 1) (match_dup 2)))
8681 (clobber (reg:CC FLAGS_REG))]
8684 [(set_attr "type" "idiv")
8685 (set_attr "mode" "SI")])
8688 [(set (match_operand:SI 0 "register_operand" "")
8689 (udiv:SI (match_operand:SI 1 "register_operand" "")
8690 (match_operand:SI 2 "nonimmediate_operand" "")))
8691 (set (match_operand:SI 3 "register_operand" "")
8692 (umod:SI (match_dup 1) (match_dup 2)))
8693 (clobber (reg:CC FLAGS_REG))]
8695 [(set (match_dup 3) (const_int 0))
8696 (parallel [(set (match_dup 0)
8697 (udiv:SI (match_dup 1) (match_dup 2)))
8699 (umod:SI (match_dup 1) (match_dup 2)))
8701 (clobber (reg:CC FLAGS_REG))])]
8704 (define_expand "udivmodhi4"
8705 [(set (match_dup 4) (const_int 0))
8706 (parallel [(set (match_operand:HI 0 "register_operand" "")
8707 (udiv:HI (match_operand:HI 1 "register_operand" "")
8708 (match_operand:HI 2 "nonimmediate_operand" "")))
8709 (set (match_operand:HI 3 "register_operand" "")
8710 (umod:HI (match_dup 1) (match_dup 2)))
8712 (clobber (reg:CC FLAGS_REG))])]
8713 "TARGET_HIMODE_MATH"
8714 "operands[4] = gen_reg_rtx (HImode);")
8716 (define_insn "*udivmodhi_noext"
8717 [(set (match_operand:HI 0 "register_operand" "=a")
8718 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8719 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8720 (set (match_operand:HI 3 "register_operand" "=d")
8721 (umod:HI (match_dup 1) (match_dup 2)))
8722 (use (match_operand:HI 4 "register_operand" "3"))
8723 (clobber (reg:CC FLAGS_REG))]
8726 [(set_attr "type" "idiv")
8727 (set_attr "mode" "HI")])
8729 ;; We cannot use div/idiv for double division, because it causes
8730 ;; "division by zero" on the overflow and that's not what we expect
8731 ;; from truncate. Because true (non truncating) double division is
8732 ;; never generated, we can't create this insn anyway.
8735 ; [(set (match_operand:SI 0 "register_operand" "=a")
8737 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8739 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8740 ; (set (match_operand:SI 3 "register_operand" "=d")
8742 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8743 ; (clobber (reg:CC FLAGS_REG))]
8745 ; "div{l}\t{%2, %0|%0, %2}"
8746 ; [(set_attr "type" "idiv")])
8748 ;;- Logical AND instructions
8750 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8751 ;; Note that this excludes ah.
8753 (define_insn "*testdi_1_rex64"
8754 [(set (reg FLAGS_REG)
8756 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8757 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8759 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8762 test{l}\t{%k1, %k0|%k0, %k1}
8763 test{l}\t{%k1, %k0|%k0, %k1}
8764 test{q}\t{%1, %0|%0, %1}
8765 test{q}\t{%1, %0|%0, %1}
8766 test{q}\t{%1, %0|%0, %1}"
8767 [(set_attr "type" "test")
8768 (set_attr "modrm" "0,1,0,1,1")
8769 (set_attr "mode" "SI,SI,DI,DI,DI")
8770 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8772 (define_insn "testsi_1"
8773 [(set (reg FLAGS_REG)
8775 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8776 (match_operand:SI 1 "general_operand" "i,i,ri"))
8778 "ix86_match_ccmode (insn, CCNOmode)
8779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8780 "test{l}\t{%1, %0|%0, %1}"
8781 [(set_attr "type" "test")
8782 (set_attr "modrm" "0,1,1")
8783 (set_attr "mode" "SI")
8784 (set_attr "pent_pair" "uv,np,uv")])
8786 (define_expand "testsi_ccno_1"
8787 [(set (reg:CCNO FLAGS_REG)
8789 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8790 (match_operand:SI 1 "nonmemory_operand" ""))
8795 (define_insn "*testhi_1"
8796 [(set (reg FLAGS_REG)
8797 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8798 (match_operand:HI 1 "general_operand" "n,n,rn"))
8800 "ix86_match_ccmode (insn, CCNOmode)
8801 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8802 "test{w}\t{%1, %0|%0, %1}"
8803 [(set_attr "type" "test")
8804 (set_attr "modrm" "0,1,1")
8805 (set_attr "mode" "HI")
8806 (set_attr "pent_pair" "uv,np,uv")])
8808 (define_expand "testqi_ccz_1"
8809 [(set (reg:CCZ FLAGS_REG)
8810 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8811 (match_operand:QI 1 "nonmemory_operand" ""))
8816 (define_insn "*testqi_1_maybe_si"
8817 [(set (reg FLAGS_REG)
8820 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8821 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8824 && ix86_match_ccmode (insn,
8825 CONST_INT_P (operands[1])
8826 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8828 if (which_alternative == 3)
8830 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8831 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8832 return "test{l}\t{%1, %k0|%k0, %1}";
8834 return "test{b}\t{%1, %0|%0, %1}";
8836 [(set_attr "type" "test")
8837 (set_attr "modrm" "0,1,1,1")
8838 (set_attr "mode" "QI,QI,QI,SI")
8839 (set_attr "pent_pair" "uv,np,uv,np")])
8841 (define_insn "*testqi_1"
8842 [(set (reg FLAGS_REG)
8845 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8846 (match_operand:QI 1 "general_operand" "n,n,qn"))
8848 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8849 && ix86_match_ccmode (insn, CCNOmode)"
8850 "test{b}\t{%1, %0|%0, %1}"
8851 [(set_attr "type" "test")
8852 (set_attr "modrm" "0,1,1")
8853 (set_attr "mode" "QI")
8854 (set_attr "pent_pair" "uv,np,uv")])
8856 (define_expand "testqi_ext_ccno_0"
8857 [(set (reg:CCNO FLAGS_REG)
8861 (match_operand 0 "ext_register_operand" "")
8864 (match_operand 1 "const_int_operand" ""))
8869 (define_insn "*testqi_ext_0"
8870 [(set (reg FLAGS_REG)
8874 (match_operand 0 "ext_register_operand" "Q")
8877 (match_operand 1 "const_int_operand" "n"))
8879 "ix86_match_ccmode (insn, CCNOmode)"
8880 "test{b}\t{%1, %h0|%h0, %1}"
8881 [(set_attr "type" "test")
8882 (set_attr "mode" "QI")
8883 (set_attr "length_immediate" "1")
8884 (set_attr "pent_pair" "np")])
8886 (define_insn "*testqi_ext_1"
8887 [(set (reg FLAGS_REG)
8891 (match_operand 0 "ext_register_operand" "Q")
8895 (match_operand:QI 1 "general_operand" "Qm")))
8897 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8899 "test{b}\t{%1, %h0|%h0, %1}"
8900 [(set_attr "type" "test")
8901 (set_attr "mode" "QI")])
8903 (define_insn "*testqi_ext_1_rex64"
8904 [(set (reg FLAGS_REG)
8908 (match_operand 0 "ext_register_operand" "Q")
8912 (match_operand:QI 1 "register_operand" "Q")))
8914 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8915 "test{b}\t{%1, %h0|%h0, %1}"
8916 [(set_attr "type" "test")
8917 (set_attr "mode" "QI")])
8919 (define_insn "*testqi_ext_2"
8920 [(set (reg FLAGS_REG)
8924 (match_operand 0 "ext_register_operand" "Q")
8928 (match_operand 1 "ext_register_operand" "Q")
8932 "ix86_match_ccmode (insn, CCNOmode)"
8933 "test{b}\t{%h1, %h0|%h0, %h1}"
8934 [(set_attr "type" "test")
8935 (set_attr "mode" "QI")])
8937 ;; Combine likes to form bit extractions for some tests. Humor it.
8938 (define_insn "*testqi_ext_3"
8939 [(set (reg FLAGS_REG)
8940 (compare (zero_extract:SI
8941 (match_operand 0 "nonimmediate_operand" "rm")
8942 (match_operand:SI 1 "const_int_operand" "")
8943 (match_operand:SI 2 "const_int_operand" ""))
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && INTVAL (operands[1]) > 0
8947 && INTVAL (operands[2]) >= 0
8948 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8949 && (GET_MODE (operands[0]) == SImode
8950 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8951 || GET_MODE (operands[0]) == HImode
8952 || GET_MODE (operands[0]) == QImode)"
8955 (define_insn "*testqi_ext_3_rex64"
8956 [(set (reg FLAGS_REG)
8957 (compare (zero_extract:DI
8958 (match_operand 0 "nonimmediate_operand" "rm")
8959 (match_operand:DI 1 "const_int_operand" "")
8960 (match_operand:DI 2 "const_int_operand" ""))
8963 && ix86_match_ccmode (insn, CCNOmode)
8964 && INTVAL (operands[1]) > 0
8965 && INTVAL (operands[2]) >= 0
8966 /* Ensure that resulting mask is zero or sign extended operand. */
8967 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8969 && INTVAL (operands[1]) > 32))
8970 && (GET_MODE (operands[0]) == SImode
8971 || GET_MODE (operands[0]) == DImode
8972 || GET_MODE (operands[0]) == HImode
8973 || GET_MODE (operands[0]) == QImode)"
8977 [(set (match_operand 0 "flags_reg_operand" "")
8978 (match_operator 1 "compare_operator"
8980 (match_operand 2 "nonimmediate_operand" "")
8981 (match_operand 3 "const_int_operand" "")
8982 (match_operand 4 "const_int_operand" ""))
8984 "ix86_match_ccmode (insn, CCNOmode)"
8985 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8987 rtx val = operands[2];
8988 HOST_WIDE_INT len = INTVAL (operands[3]);
8989 HOST_WIDE_INT pos = INTVAL (operands[4]);
8991 enum machine_mode mode, submode;
8993 mode = GET_MODE (val);
8996 /* ??? Combine likes to put non-volatile mem extractions in QImode
8997 no matter the size of the test. So find a mode that works. */
8998 if (! MEM_VOLATILE_P (val))
9000 mode = smallest_mode_for_size (pos + len, MODE_INT);
9001 val = adjust_address (val, mode, 0);
9004 else if (GET_CODE (val) == SUBREG
9005 && (submode = GET_MODE (SUBREG_REG (val)),
9006 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9007 && pos + len <= GET_MODE_BITSIZE (submode))
9009 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9011 val = SUBREG_REG (val);
9013 else if (mode == HImode && pos + len <= 8)
9015 /* Small HImode tests can be converted to QImode. */
9017 val = gen_lowpart (QImode, val);
9020 if (len == HOST_BITS_PER_WIDE_INT)
9023 mask = ((HOST_WIDE_INT)1 << len) - 1;
9026 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9029 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9030 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9031 ;; this is relatively important trick.
9032 ;; Do the conversion only post-reload to avoid limiting of the register class
9035 [(set (match_operand 0 "flags_reg_operand" "")
9036 (match_operator 1 "compare_operator"
9037 [(and (match_operand 2 "register_operand" "")
9038 (match_operand 3 "const_int_operand" ""))
9041 && QI_REG_P (operands[2])
9042 && GET_MODE (operands[2]) != QImode
9043 && ((ix86_match_ccmode (insn, CCZmode)
9044 && !(INTVAL (operands[3]) & ~(255 << 8)))
9045 || (ix86_match_ccmode (insn, CCNOmode)
9046 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9049 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9052 "operands[2] = gen_lowpart (SImode, operands[2]);
9053 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9056 [(set (match_operand 0 "flags_reg_operand" "")
9057 (match_operator 1 "compare_operator"
9058 [(and (match_operand 2 "nonimmediate_operand" "")
9059 (match_operand 3 "const_int_operand" ""))
9062 && GET_MODE (operands[2]) != QImode
9063 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9064 && ((ix86_match_ccmode (insn, CCZmode)
9065 && !(INTVAL (operands[3]) & ~255))
9066 || (ix86_match_ccmode (insn, CCNOmode)
9067 && !(INTVAL (operands[3]) & ~127)))"
9069 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9071 "operands[2] = gen_lowpart (QImode, operands[2]);
9072 operands[3] = gen_lowpart (QImode, operands[3]);")
9075 ;; %%% This used to optimize known byte-wide and operations to memory,
9076 ;; and sometimes to QImode registers. If this is considered useful,
9077 ;; it should be done with splitters.
9079 (define_expand "anddi3"
9080 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9081 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9082 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9084 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9086 (define_insn "*anddi_1_rex64"
9087 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9088 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9089 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9093 switch (get_attr_type (insn))
9097 enum machine_mode mode;
9099 gcc_assert (CONST_INT_P (operands[2]));
9100 if (INTVAL (operands[2]) == 0xff)
9104 gcc_assert (INTVAL (operands[2]) == 0xffff);
9108 operands[1] = gen_lowpart (mode, operands[1]);
9110 return "movz{bq|x}\t{%1,%0|%0, %1}";
9112 return "movz{wq|x}\t{%1,%0|%0, %1}";
9116 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9117 if (get_attr_mode (insn) == MODE_SI)
9118 return "and{l}\t{%k2, %k0|%k0, %k2}";
9120 return "and{q}\t{%2, %0|%0, %2}";
9123 [(set_attr "type" "alu,alu,alu,imovx")
9124 (set_attr "length_immediate" "*,*,*,0")
9125 (set_attr "mode" "SI,DI,DI,DI")])
9127 (define_insn "*anddi_2"
9128 [(set (reg FLAGS_REG)
9129 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9130 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9132 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9133 (and:DI (match_dup 1) (match_dup 2)))]
9134 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9135 && ix86_binary_operator_ok (AND, DImode, operands)"
9137 and{l}\t{%k2, %k0|%k0, %k2}
9138 and{q}\t{%2, %0|%0, %2}
9139 and{q}\t{%2, %0|%0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "mode" "SI,DI,DI")])
9143 (define_expand "andsi3"
9144 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9145 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9146 (match_operand:SI 2 "general_operand" "")))]
9148 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9150 (define_insn "*andsi_1"
9151 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9152 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9153 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "ix86_binary_operator_ok (AND, SImode, operands)"
9157 switch (get_attr_type (insn))
9161 enum machine_mode mode;
9163 gcc_assert (CONST_INT_P (operands[2]));
9164 if (INTVAL (operands[2]) == 0xff)
9168 gcc_assert (INTVAL (operands[2]) == 0xffff);
9172 operands[1] = gen_lowpart (mode, operands[1]);
9174 return "movz{bl|x}\t{%1,%0|%0, %1}";
9176 return "movz{wl|x}\t{%1,%0|%0, %1}";
9180 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9181 return "and{l}\t{%2, %0|%0, %2}";
9184 [(set_attr "type" "alu,alu,imovx")
9185 (set_attr "length_immediate" "*,*,0")
9186 (set_attr "mode" "SI")])
9189 [(set (match_operand 0 "register_operand" "")
9191 (const_int -65536)))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9194 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9195 "operands[1] = gen_lowpart (HImode, operands[0]);")
9198 [(set (match_operand 0 "ext_register_operand" "")
9201 (clobber (reg:CC FLAGS_REG))]
9202 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9203 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9204 "operands[1] = gen_lowpart (QImode, operands[0]);")
9207 [(set (match_operand 0 "ext_register_operand" "")
9209 (const_int -65281)))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9212 [(parallel [(set (zero_extract:SI (match_dup 0)
9216 (zero_extract:SI (match_dup 0)
9219 (zero_extract:SI (match_dup 0)
9222 (clobber (reg:CC FLAGS_REG))])]
9223 "operands[0] = gen_lowpart (SImode, operands[0]);")
9225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9226 (define_insn "*andsi_1_zext"
9227 [(set (match_operand:DI 0 "register_operand" "=r")
9229 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9230 (match_operand:SI 2 "general_operand" "g"))))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9233 "and{l}\t{%2, %k0|%k0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "mode" "SI")])
9237 (define_insn "*andsi_2"
9238 [(set (reg FLAGS_REG)
9239 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9240 (match_operand:SI 2 "general_operand" "g,ri"))
9242 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9243 (and:SI (match_dup 1) (match_dup 2)))]
9244 "ix86_match_ccmode (insn, CCNOmode)
9245 && ix86_binary_operator_ok (AND, SImode, operands)"
9246 "and{l}\t{%2, %0|%0, %2}"
9247 [(set_attr "type" "alu")
9248 (set_attr "mode" "SI")])
9250 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9251 (define_insn "*andsi_2_zext"
9252 [(set (reg FLAGS_REG)
9253 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9254 (match_operand:SI 2 "general_operand" "g"))
9256 (set (match_operand:DI 0 "register_operand" "=r")
9257 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9258 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9259 && ix86_binary_operator_ok (AND, SImode, operands)"
9260 "and{l}\t{%2, %k0|%k0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "SI")])
9264 (define_expand "andhi3"
9265 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9266 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9267 (match_operand:HI 2 "general_operand" "")))]
9268 "TARGET_HIMODE_MATH"
9269 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9271 (define_insn "*andhi_1"
9272 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9273 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9274 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9275 (clobber (reg:CC FLAGS_REG))]
9276 "ix86_binary_operator_ok (AND, HImode, operands)"
9278 switch (get_attr_type (insn))
9281 gcc_assert (CONST_INT_P (operands[2]));
9282 gcc_assert (INTVAL (operands[2]) == 0xff);
9283 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9288 return "and{w}\t{%2, %0|%0, %2}";
9291 [(set_attr "type" "alu,alu,imovx")
9292 (set_attr "length_immediate" "*,*,0")
9293 (set_attr "mode" "HI,HI,SI")])
9295 (define_insn "*andhi_2"
9296 [(set (reg FLAGS_REG)
9297 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9298 (match_operand:HI 2 "general_operand" "rmn,rn"))
9300 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9301 (and:HI (match_dup 1) (match_dup 2)))]
9302 "ix86_match_ccmode (insn, CCNOmode)
9303 && ix86_binary_operator_ok (AND, HImode, operands)"
9304 "and{w}\t{%2, %0|%0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "HI")])
9308 (define_expand "andqi3"
9309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9310 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9311 (match_operand:QI 2 "general_operand" "")))]
9312 "TARGET_QIMODE_MATH"
9313 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9315 ;; %%% Potential partial reg stall on alternative 2. What to do?
9316 (define_insn "*andqi_1"
9317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9318 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9319 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9320 (clobber (reg:CC FLAGS_REG))]
9321 "ix86_binary_operator_ok (AND, QImode, operands)"
9323 and{b}\t{%2, %0|%0, %2}
9324 and{b}\t{%2, %0|%0, %2}
9325 and{l}\t{%k2, %k0|%k0, %k2}"
9326 [(set_attr "type" "alu")
9327 (set_attr "mode" "QI,QI,SI")])
9329 (define_insn "*andqi_1_slp"
9330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9331 (and:QI (match_dup 0)
9332 (match_operand:QI 1 "general_operand" "qn,qmn")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9335 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9336 "and{b}\t{%1, %0|%0, %1}"
9337 [(set_attr "type" "alu1")
9338 (set_attr "mode" "QI")])
9340 (define_insn "*andqi_2_maybe_si"
9341 [(set (reg FLAGS_REG)
9343 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9344 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9346 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9347 (and:QI (match_dup 1) (match_dup 2)))]
9348 "ix86_binary_operator_ok (AND, QImode, operands)
9349 && ix86_match_ccmode (insn,
9350 CONST_INT_P (operands[2])
9351 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9353 if (which_alternative == 2)
9355 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9356 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9357 return "and{l}\t{%2, %k0|%k0, %2}";
9359 return "and{b}\t{%2, %0|%0, %2}";
9361 [(set_attr "type" "alu")
9362 (set_attr "mode" "QI,QI,SI")])
9364 (define_insn "*andqi_2"
9365 [(set (reg FLAGS_REG)
9367 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9368 (match_operand:QI 2 "general_operand" "qmn,qn"))
9370 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9371 (and:QI (match_dup 1) (match_dup 2)))]
9372 "ix86_match_ccmode (insn, CCNOmode)
9373 && ix86_binary_operator_ok (AND, QImode, operands)"
9374 "and{b}\t{%2, %0|%0, %2}"
9375 [(set_attr "type" "alu")
9376 (set_attr "mode" "QI")])
9378 (define_insn "*andqi_2_slp"
9379 [(set (reg FLAGS_REG)
9381 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9382 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9384 (set (strict_low_part (match_dup 0))
9385 (and:QI (match_dup 0) (match_dup 1)))]
9386 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9387 && ix86_match_ccmode (insn, CCNOmode)
9388 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9389 "and{b}\t{%1, %0|%0, %1}"
9390 [(set_attr "type" "alu1")
9391 (set_attr "mode" "QI")])
9393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9394 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9395 ;; for a QImode operand, which of course failed.
9397 (define_insn "andqi_ext_0"
9398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9403 (match_operand 1 "ext_register_operand" "0")
9406 (match_operand 2 "const_int_operand" "n")))
9407 (clobber (reg:CC FLAGS_REG))]
9409 "and{b}\t{%2, %h0|%h0, %2}"
9410 [(set_attr "type" "alu")
9411 (set_attr "length_immediate" "1")
9412 (set_attr "mode" "QI")])
9414 ;; Generated by peephole translating test to and. This shows up
9415 ;; often in fp comparisons.
9417 (define_insn "*andqi_ext_0_cc"
9418 [(set (reg FLAGS_REG)
9422 (match_operand 1 "ext_register_operand" "0")
9425 (match_operand 2 "const_int_operand" "n"))
9427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9436 "ix86_match_ccmode (insn, CCNOmode)"
9437 "and{b}\t{%2, %h0|%h0, %2}"
9438 [(set_attr "type" "alu")
9439 (set_attr "length_immediate" "1")
9440 (set_attr "mode" "QI")])
9442 (define_insn "*andqi_ext_1"
9443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9448 (match_operand 1 "ext_register_operand" "0")
9452 (match_operand:QI 2 "general_operand" "Qm"))))
9453 (clobber (reg:CC FLAGS_REG))]
9455 "and{b}\t{%2, %h0|%h0, %2}"
9456 [(set_attr "type" "alu")
9457 (set_attr "length_immediate" "0")
9458 (set_attr "mode" "QI")])
9460 (define_insn "*andqi_ext_1_rex64"
9461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (match_operand 1 "ext_register_operand" "0")
9470 (match_operand 2 "ext_register_operand" "Q"))))
9471 (clobber (reg:CC FLAGS_REG))]
9473 "and{b}\t{%2, %h0|%h0, %2}"
9474 [(set_attr "type" "alu")
9475 (set_attr "length_immediate" "0")
9476 (set_attr "mode" "QI")])
9478 (define_insn "*andqi_ext_2"
9479 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9484 (match_operand 1 "ext_register_operand" "%0")
9488 (match_operand 2 "ext_register_operand" "Q")
9491 (clobber (reg:CC FLAGS_REG))]
9493 "and{b}\t{%h2, %h0|%h0, %h2}"
9494 [(set_attr "type" "alu")
9495 (set_attr "length_immediate" "0")
9496 (set_attr "mode" "QI")])
9498 ;; Convert wide AND instructions with immediate operand to shorter QImode
9499 ;; equivalents when possible.
9500 ;; Don't do the splitting with memory operands, since it introduces risk
9501 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9502 ;; for size, but that can (should?) be handled by generic code instead.
9504 [(set (match_operand 0 "register_operand" "")
9505 (and (match_operand 1 "register_operand" "")
9506 (match_operand 2 "const_int_operand" "")))
9507 (clobber (reg:CC FLAGS_REG))]
9509 && QI_REG_P (operands[0])
9510 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9511 && !(~INTVAL (operands[2]) & ~(255 << 8))
9512 && GET_MODE (operands[0]) != QImode"
9513 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514 (and:SI (zero_extract:SI (match_dup 1)
9515 (const_int 8) (const_int 8))
9517 (clobber (reg:CC FLAGS_REG))])]
9518 "operands[0] = gen_lowpart (SImode, operands[0]);
9519 operands[1] = gen_lowpart (SImode, operands[1]);
9520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9522 ;; Since AND can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is not set.
9525 [(set (match_operand 0 "register_operand" "")
9526 (and (match_operand 1 "general_operand" "")
9527 (match_operand 2 "const_int_operand" "")))
9528 (clobber (reg:CC FLAGS_REG))]
9530 && ANY_QI_REG_P (operands[0])
9531 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9532 && !(~INTVAL (operands[2]) & ~255)
9533 && !(INTVAL (operands[2]) & 128)
9534 && GET_MODE (operands[0]) != QImode"
9535 [(parallel [(set (strict_low_part (match_dup 0))
9536 (and:QI (match_dup 1)
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "operands[0] = gen_lowpart (QImode, operands[0]);
9540 operands[1] = gen_lowpart (QImode, operands[1]);
9541 operands[2] = gen_lowpart (QImode, operands[2]);")
9543 ;; Logical inclusive OR instructions
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9548 (define_expand "iordi3"
9549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551 (match_operand:DI 2 "x86_64_general_operand" "")))]
9553 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9555 (define_insn "*iordi_1_rex64"
9556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9557 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9558 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9559 (clobber (reg:CC FLAGS_REG))]
9561 && ix86_binary_operator_ok (IOR, DImode, operands)"
9562 "or{q}\t{%2, %0|%0, %2}"
9563 [(set_attr "type" "alu")
9564 (set_attr "mode" "DI")])
9566 (define_insn "*iordi_2_rex64"
9567 [(set (reg FLAGS_REG)
9568 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9569 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9571 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9572 (ior:DI (match_dup 1) (match_dup 2)))]
9574 && ix86_match_ccmode (insn, CCNOmode)
9575 && ix86_binary_operator_ok (IOR, DImode, operands)"
9576 "or{q}\t{%2, %0|%0, %2}"
9577 [(set_attr "type" "alu")
9578 (set_attr "mode" "DI")])
9580 (define_insn "*iordi_3_rex64"
9581 [(set (reg FLAGS_REG)
9582 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9583 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9585 (clobber (match_scratch:DI 0 "=r"))]
9587 && ix86_match_ccmode (insn, CCNOmode)
9588 && ix86_binary_operator_ok (IOR, DImode, operands)"
9589 "or{q}\t{%2, %0|%0, %2}"
9590 [(set_attr "type" "alu")
9591 (set_attr "mode" "DI")])
9594 (define_expand "iorsi3"
9595 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9596 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9597 (match_operand:SI 2 "general_operand" "")))]
9599 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9601 (define_insn "*iorsi_1"
9602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9603 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9604 (match_operand:SI 2 "general_operand" "ri,g")))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "ix86_binary_operator_ok (IOR, SImode, operands)"
9607 "or{l}\t{%2, %0|%0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "SI")])
9611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9612 (define_insn "*iorsi_1_zext"
9613 [(set (match_operand:DI 0 "register_operand" "=r")
9615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9616 (match_operand:SI 2 "general_operand" "g"))))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9619 "or{l}\t{%2, %k0|%k0, %2}"
9620 [(set_attr "type" "alu")
9621 (set_attr "mode" "SI")])
9623 (define_insn "*iorsi_1_zext_imm"
9624 [(set (match_operand:DI 0 "register_operand" "=r")
9625 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9626 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9627 (clobber (reg:CC FLAGS_REG))]
9629 "or{l}\t{%2, %k0|%k0, %2}"
9630 [(set_attr "type" "alu")
9631 (set_attr "mode" "SI")])
9633 (define_insn "*iorsi_2"
9634 [(set (reg FLAGS_REG)
9635 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9636 (match_operand:SI 2 "general_operand" "g,ri"))
9638 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9639 (ior:SI (match_dup 1) (match_dup 2)))]
9640 "ix86_match_ccmode (insn, CCNOmode)
9641 && ix86_binary_operator_ok (IOR, SImode, operands)"
9642 "or{l}\t{%2, %0|%0, %2}"
9643 [(set_attr "type" "alu")
9644 (set_attr "mode" "SI")])
9646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9647 ;; ??? Special case for immediate operand is missing - it is tricky.
9648 (define_insn "*iorsi_2_zext"
9649 [(set (reg FLAGS_REG)
9650 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9651 (match_operand:SI 2 "general_operand" "g"))
9653 (set (match_operand:DI 0 "register_operand" "=r")
9654 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9656 && ix86_binary_operator_ok (IOR, SImode, operands)"
9657 "or{l}\t{%2, %k0|%k0, %2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "mode" "SI")])
9661 (define_insn "*iorsi_2_zext_imm"
9662 [(set (reg FLAGS_REG)
9663 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9664 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9666 (set (match_operand:DI 0 "register_operand" "=r")
9667 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9668 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9669 && ix86_binary_operator_ok (IOR, SImode, operands)"
9670 "or{l}\t{%2, %k0|%k0, %2}"
9671 [(set_attr "type" "alu")
9672 (set_attr "mode" "SI")])
9674 (define_insn "*iorsi_3"
9675 [(set (reg FLAGS_REG)
9676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9677 (match_operand:SI 2 "general_operand" "g"))
9679 (clobber (match_scratch:SI 0 "=r"))]
9680 "ix86_match_ccmode (insn, CCNOmode)
9681 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682 "or{l}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "alu")
9684 (set_attr "mode" "SI")])
9686 (define_expand "iorhi3"
9687 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9688 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9689 (match_operand:HI 2 "general_operand" "")))]
9690 "TARGET_HIMODE_MATH"
9691 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9693 (define_insn "*iorhi_1"
9694 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9695 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9696 (match_operand:HI 2 "general_operand" "rmn,rn")))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "ix86_binary_operator_ok (IOR, HImode, operands)"
9699 "or{w}\t{%2, %0|%0, %2}"
9700 [(set_attr "type" "alu")
9701 (set_attr "mode" "HI")])
9703 (define_insn "*iorhi_2"
9704 [(set (reg FLAGS_REG)
9705 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9706 (match_operand:HI 2 "general_operand" "rmn,rn"))
9708 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9709 (ior:HI (match_dup 1) (match_dup 2)))]
9710 "ix86_match_ccmode (insn, CCNOmode)
9711 && ix86_binary_operator_ok (IOR, HImode, operands)"
9712 "or{w}\t{%2, %0|%0, %2}"
9713 [(set_attr "type" "alu")
9714 (set_attr "mode" "HI")])
9716 (define_insn "*iorhi_3"
9717 [(set (reg FLAGS_REG)
9718 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9719 (match_operand:HI 2 "general_operand" "rmn"))
9721 (clobber (match_scratch:HI 0 "=r"))]
9722 "ix86_match_ccmode (insn, CCNOmode)
9723 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9724 "or{w}\t{%2, %0|%0, %2}"
9725 [(set_attr "type" "alu")
9726 (set_attr "mode" "HI")])
9728 (define_expand "iorqi3"
9729 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9730 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9731 (match_operand:QI 2 "general_operand" "")))]
9732 "TARGET_QIMODE_MATH"
9733 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9735 ;; %%% Potential partial reg stall on alternative 2. What to do?
9736 (define_insn "*iorqi_1"
9737 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9738 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9739 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9740 (clobber (reg:CC FLAGS_REG))]
9741 "ix86_binary_operator_ok (IOR, QImode, operands)"
9743 or{b}\t{%2, %0|%0, %2}
9744 or{b}\t{%2, %0|%0, %2}
9745 or{l}\t{%k2, %k0|%k0, %k2}"
9746 [(set_attr "type" "alu")
9747 (set_attr "mode" "QI,QI,SI")])
9749 (define_insn "*iorqi_1_slp"
9750 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9751 (ior:QI (match_dup 0)
9752 (match_operand:QI 1 "general_operand" "qmn,qn")))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9755 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9756 "or{b}\t{%1, %0|%0, %1}"
9757 [(set_attr "type" "alu1")
9758 (set_attr "mode" "QI")])
9760 (define_insn "*iorqi_2"
9761 [(set (reg FLAGS_REG)
9762 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9763 (match_operand:QI 2 "general_operand" "qmn,qn"))
9765 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9766 (ior:QI (match_dup 1) (match_dup 2)))]
9767 "ix86_match_ccmode (insn, CCNOmode)
9768 && ix86_binary_operator_ok (IOR, QImode, operands)"
9769 "or{b}\t{%2, %0|%0, %2}"
9770 [(set_attr "type" "alu")
9771 (set_attr "mode" "QI")])
9773 (define_insn "*iorqi_2_slp"
9774 [(set (reg FLAGS_REG)
9775 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9776 (match_operand:QI 1 "general_operand" "qmn,qn"))
9778 (set (strict_low_part (match_dup 0))
9779 (ior:QI (match_dup 0) (match_dup 1)))]
9780 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9781 && ix86_match_ccmode (insn, CCNOmode)
9782 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9783 "or{b}\t{%1, %0|%0, %1}"
9784 [(set_attr "type" "alu1")
9785 (set_attr "mode" "QI")])
9787 (define_insn "*iorqi_3"
9788 [(set (reg FLAGS_REG)
9789 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9790 (match_operand:QI 2 "general_operand" "qmn"))
9792 (clobber (match_scratch:QI 0 "=q"))]
9793 "ix86_match_ccmode (insn, CCNOmode)
9794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9795 "or{b}\t{%2, %0|%0, %2}"
9796 [(set_attr "type" "alu")
9797 (set_attr "mode" "QI")])
9799 (define_insn "*iorqi_ext_0"
9800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9805 (match_operand 1 "ext_register_operand" "0")
9808 (match_operand 2 "const_int_operand" "n")))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9811 "or{b}\t{%2, %h0|%h0, %2}"
9812 [(set_attr "type" "alu")
9813 (set_attr "length_immediate" "1")
9814 (set_attr "mode" "QI")])
9816 (define_insn "*iorqi_ext_1"
9817 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9822 (match_operand 1 "ext_register_operand" "0")
9826 (match_operand:QI 2 "general_operand" "Qm"))))
9827 (clobber (reg:CC FLAGS_REG))]
9829 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830 "or{b}\t{%2, %h0|%h0, %2}"
9831 [(set_attr "type" "alu")
9832 (set_attr "length_immediate" "0")
9833 (set_attr "mode" "QI")])
9835 (define_insn "*iorqi_ext_1_rex64"
9836 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9841 (match_operand 1 "ext_register_operand" "0")
9845 (match_operand 2 "ext_register_operand" "Q"))))
9846 (clobber (reg:CC FLAGS_REG))]
9848 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849 "or{b}\t{%2, %h0|%h0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "length_immediate" "0")
9852 (set_attr "mode" "QI")])
9854 (define_insn "*iorqi_ext_2"
9855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9859 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9862 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9865 (clobber (reg:CC FLAGS_REG))]
9866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9867 "ior{b}\t{%h2, %h0|%h0, %h2}"
9868 [(set_attr "type" "alu")
9869 (set_attr "length_immediate" "0")
9870 (set_attr "mode" "QI")])
9873 [(set (match_operand 0 "register_operand" "")
9874 (ior (match_operand 1 "register_operand" "")
9875 (match_operand 2 "const_int_operand" "")))
9876 (clobber (reg:CC FLAGS_REG))]
9878 && QI_REG_P (operands[0])
9879 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9880 && !(INTVAL (operands[2]) & ~(255 << 8))
9881 && GET_MODE (operands[0]) != QImode"
9882 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9883 (ior:SI (zero_extract:SI (match_dup 1)
9884 (const_int 8) (const_int 8))
9886 (clobber (reg:CC FLAGS_REG))])]
9887 "operands[0] = gen_lowpart (SImode, operands[0]);
9888 operands[1] = gen_lowpart (SImode, operands[1]);
9889 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9891 ;; Since OR can be encoded with sign extended immediate, this is only
9892 ;; profitable when 7th bit is set.
9894 [(set (match_operand 0 "register_operand" "")
9895 (ior (match_operand 1 "general_operand" "")
9896 (match_operand 2 "const_int_operand" "")))
9897 (clobber (reg:CC FLAGS_REG))]
9899 && ANY_QI_REG_P (operands[0])
9900 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9901 && !(INTVAL (operands[2]) & ~255)
9902 && (INTVAL (operands[2]) & 128)
9903 && GET_MODE (operands[0]) != QImode"
9904 [(parallel [(set (strict_low_part (match_dup 0))
9905 (ior:QI (match_dup 1)
9907 (clobber (reg:CC FLAGS_REG))])]
9908 "operands[0] = gen_lowpart (QImode, operands[0]);
9909 operands[1] = gen_lowpart (QImode, operands[1]);
9910 operands[2] = gen_lowpart (QImode, operands[2]);")
9912 ;; Logical XOR instructions
9914 ;; %%% This used to optimize known byte-wide and operations to memory.
9915 ;; If this is considered useful, it should be done with splitters.
9917 (define_expand "xordi3"
9918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9920 (match_operand:DI 2 "x86_64_general_operand" "")))]
9922 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9924 (define_insn "*xordi_1_rex64"
9925 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9926 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9927 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9928 (clobber (reg:CC FLAGS_REG))]
9930 && ix86_binary_operator_ok (XOR, DImode, operands)"
9931 "xor{q}\t{%2, %0|%0, %2}"
9932 [(set_attr "type" "alu")
9933 (set_attr "mode" "DI")])
9935 (define_insn "*xordi_2_rex64"
9936 [(set (reg FLAGS_REG)
9937 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9938 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9940 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9941 (xor:DI (match_dup 1) (match_dup 2)))]
9943 && ix86_match_ccmode (insn, CCNOmode)
9944 && ix86_binary_operator_ok (XOR, DImode, operands)"
9945 "xor{q}\t{%2, %0|%0, %2}"
9946 [(set_attr "type" "alu")
9947 (set_attr "mode" "DI")])
9949 (define_insn "*xordi_3_rex64"
9950 [(set (reg FLAGS_REG)
9951 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9952 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9954 (clobber (match_scratch:DI 0 "=r"))]
9956 && ix86_match_ccmode (insn, CCNOmode)
9957 && ix86_binary_operator_ok (XOR, DImode, operands)"
9958 "xor{q}\t{%2, %0|%0, %2}"
9959 [(set_attr "type" "alu")
9960 (set_attr "mode" "DI")])
9962 (define_expand "xorsi3"
9963 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9964 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9965 (match_operand:SI 2 "general_operand" "")))]
9967 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9969 (define_insn "*xorsi_1"
9970 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9971 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9972 (match_operand:SI 2 "general_operand" "ri,rm")))
9973 (clobber (reg:CC FLAGS_REG))]
9974 "ix86_binary_operator_ok (XOR, SImode, operands)"
9975 "xor{l}\t{%2, %0|%0, %2}"
9976 [(set_attr "type" "alu")
9977 (set_attr "mode" "SI")])
9979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9980 ;; Add speccase for immediates
9981 (define_insn "*xorsi_1_zext"
9982 [(set (match_operand:DI 0 "register_operand" "=r")
9984 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9985 (match_operand:SI 2 "general_operand" "g"))))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9988 "xor{l}\t{%2, %k0|%k0, %2}"
9989 [(set_attr "type" "alu")
9990 (set_attr "mode" "SI")])
9992 (define_insn "*xorsi_1_zext_imm"
9993 [(set (match_operand:DI 0 "register_operand" "=r")
9994 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9995 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9996 (clobber (reg:CC FLAGS_REG))]
9997 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9998 "xor{l}\t{%2, %k0|%k0, %2}"
9999 [(set_attr "type" "alu")
10000 (set_attr "mode" "SI")])
10002 (define_insn "*xorsi_2"
10003 [(set (reg FLAGS_REG)
10004 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005 (match_operand:SI 2 "general_operand" "g,ri"))
10007 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10008 (xor:SI (match_dup 1) (match_dup 2)))]
10009 "ix86_match_ccmode (insn, CCNOmode)
10010 && ix86_binary_operator_ok (XOR, SImode, operands)"
10011 "xor{l}\t{%2, %0|%0, %2}"
10012 [(set_attr "type" "alu")
10013 (set_attr "mode" "SI")])
10015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10016 ;; ??? Special case for immediate operand is missing - it is tricky.
10017 (define_insn "*xorsi_2_zext"
10018 [(set (reg FLAGS_REG)
10019 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10020 (match_operand:SI 2 "general_operand" "g"))
10022 (set (match_operand:DI 0 "register_operand" "=r")
10023 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10024 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10025 && ix86_binary_operator_ok (XOR, SImode, operands)"
10026 "xor{l}\t{%2, %k0|%k0, %2}"
10027 [(set_attr "type" "alu")
10028 (set_attr "mode" "SI")])
10030 (define_insn "*xorsi_2_zext_imm"
10031 [(set (reg FLAGS_REG)
10032 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10033 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10035 (set (match_operand:DI 0 "register_operand" "=r")
10036 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10037 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10038 && ix86_binary_operator_ok (XOR, SImode, operands)"
10039 "xor{l}\t{%2, %k0|%k0, %2}"
10040 [(set_attr "type" "alu")
10041 (set_attr "mode" "SI")])
10043 (define_insn "*xorsi_3"
10044 [(set (reg FLAGS_REG)
10045 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10046 (match_operand:SI 2 "general_operand" "g"))
10048 (clobber (match_scratch:SI 0 "=r"))]
10049 "ix86_match_ccmode (insn, CCNOmode)
10050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051 "xor{l}\t{%2, %0|%0, %2}"
10052 [(set_attr "type" "alu")
10053 (set_attr "mode" "SI")])
10055 (define_expand "xorhi3"
10056 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10057 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10058 (match_operand:HI 2 "general_operand" "")))]
10059 "TARGET_HIMODE_MATH"
10060 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10062 (define_insn "*xorhi_1"
10063 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10064 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10065 (match_operand:HI 2 "general_operand" "rmn,rn")))
10066 (clobber (reg:CC FLAGS_REG))]
10067 "ix86_binary_operator_ok (XOR, HImode, operands)"
10068 "xor{w}\t{%2, %0|%0, %2}"
10069 [(set_attr "type" "alu")
10070 (set_attr "mode" "HI")])
10072 (define_insn "*xorhi_2"
10073 [(set (reg FLAGS_REG)
10074 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10075 (match_operand:HI 2 "general_operand" "rmn,rn"))
10077 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10078 (xor:HI (match_dup 1) (match_dup 2)))]
10079 "ix86_match_ccmode (insn, CCNOmode)
10080 && ix86_binary_operator_ok (XOR, HImode, operands)"
10081 "xor{w}\t{%2, %0|%0, %2}"
10082 [(set_attr "type" "alu")
10083 (set_attr "mode" "HI")])
10085 (define_insn "*xorhi_3"
10086 [(set (reg FLAGS_REG)
10087 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10088 (match_operand:HI 2 "general_operand" "rmn"))
10090 (clobber (match_scratch:HI 0 "=r"))]
10091 "ix86_match_ccmode (insn, CCNOmode)
10092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10093 "xor{w}\t{%2, %0|%0, %2}"
10094 [(set_attr "type" "alu")
10095 (set_attr "mode" "HI")])
10097 (define_expand "xorqi3"
10098 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10099 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10100 (match_operand:QI 2 "general_operand" "")))]
10101 "TARGET_QIMODE_MATH"
10102 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10104 ;; %%% Potential partial reg stall on alternative 2. What to do?
10105 (define_insn "*xorqi_1"
10106 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10107 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10108 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "ix86_binary_operator_ok (XOR, QImode, operands)"
10112 xor{b}\t{%2, %0|%0, %2}
10113 xor{b}\t{%2, %0|%0, %2}
10114 xor{l}\t{%k2, %k0|%k0, %k2}"
10115 [(set_attr "type" "alu")
10116 (set_attr "mode" "QI,QI,SI")])
10118 (define_insn "*xorqi_1_slp"
10119 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10120 (xor:QI (match_dup 0)
10121 (match_operand:QI 1 "general_operand" "qn,qmn")))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10124 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10125 "xor{b}\t{%1, %0|%0, %1}"
10126 [(set_attr "type" "alu1")
10127 (set_attr "mode" "QI")])
10129 (define_insn "*xorqi_ext_0"
10130 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10135 (match_operand 1 "ext_register_operand" "0")
10138 (match_operand 2 "const_int_operand" "n")))
10139 (clobber (reg:CC FLAGS_REG))]
10140 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10141 "xor{b}\t{%2, %h0|%h0, %2}"
10142 [(set_attr "type" "alu")
10143 (set_attr "length_immediate" "1")
10144 (set_attr "mode" "QI")])
10146 (define_insn "*xorqi_ext_1"
10147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10152 (match_operand 1 "ext_register_operand" "0")
10156 (match_operand:QI 2 "general_operand" "Qm"))))
10157 (clobber (reg:CC FLAGS_REG))]
10159 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160 "xor{b}\t{%2, %h0|%h0, %2}"
10161 [(set_attr "type" "alu")
10162 (set_attr "length_immediate" "0")
10163 (set_attr "mode" "QI")])
10165 (define_insn "*xorqi_ext_1_rex64"
10166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10171 (match_operand 1 "ext_register_operand" "0")
10175 (match_operand 2 "ext_register_operand" "Q"))))
10176 (clobber (reg:CC FLAGS_REG))]
10178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179 "xor{b}\t{%2, %h0|%h0, %2}"
10180 [(set_attr "type" "alu")
10181 (set_attr "length_immediate" "0")
10182 (set_attr "mode" "QI")])
10184 (define_insn "*xorqi_ext_2"
10185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10189 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10192 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10195 (clobber (reg:CC FLAGS_REG))]
10196 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10197 "xor{b}\t{%h2, %h0|%h0, %h2}"
10198 [(set_attr "type" "alu")
10199 (set_attr "length_immediate" "0")
10200 (set_attr "mode" "QI")])
10202 (define_insn "*xorqi_cc_1"
10203 [(set (reg FLAGS_REG)
10205 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10206 (match_operand:QI 2 "general_operand" "qmn,qn"))
10208 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10209 (xor:QI (match_dup 1) (match_dup 2)))]
10210 "ix86_match_ccmode (insn, CCNOmode)
10211 && ix86_binary_operator_ok (XOR, QImode, operands)"
10212 "xor{b}\t{%2, %0|%0, %2}"
10213 [(set_attr "type" "alu")
10214 (set_attr "mode" "QI")])
10216 (define_insn "*xorqi_2_slp"
10217 [(set (reg FLAGS_REG)
10218 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10219 (match_operand:QI 1 "general_operand" "qmn,qn"))
10221 (set (strict_low_part (match_dup 0))
10222 (xor:QI (match_dup 0) (match_dup 1)))]
10223 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10224 && ix86_match_ccmode (insn, CCNOmode)
10225 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10226 "xor{b}\t{%1, %0|%0, %1}"
10227 [(set_attr "type" "alu1")
10228 (set_attr "mode" "QI")])
10230 (define_insn "*xorqi_cc_2"
10231 [(set (reg FLAGS_REG)
10233 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10234 (match_operand:QI 2 "general_operand" "qmn"))
10236 (clobber (match_scratch:QI 0 "=q"))]
10237 "ix86_match_ccmode (insn, CCNOmode)
10238 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10239 "xor{b}\t{%2, %0|%0, %2}"
10240 [(set_attr "type" "alu")
10241 (set_attr "mode" "QI")])
10243 (define_insn "*xorqi_cc_ext_1"
10244 [(set (reg FLAGS_REG)
10248 (match_operand 1 "ext_register_operand" "0")
10251 (match_operand:QI 2 "general_operand" "qmn"))
10253 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10257 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10259 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10260 "xor{b}\t{%2, %h0|%h0, %2}"
10261 [(set_attr "type" "alu")
10262 (set_attr "mode" "QI")])
10264 (define_insn "*xorqi_cc_ext_1_rex64"
10265 [(set (reg FLAGS_REG)
10269 (match_operand 1 "ext_register_operand" "0")
10272 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10274 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10278 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10280 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10281 "xor{b}\t{%2, %h0|%h0, %2}"
10282 [(set_attr "type" "alu")
10283 (set_attr "mode" "QI")])
10285 (define_expand "xorqi_cc_ext_1"
10287 (set (reg:CCNO FLAGS_REG)
10291 (match_operand 1 "ext_register_operand" "")
10294 (match_operand:QI 2 "general_operand" ""))
10296 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10300 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10306 [(set (match_operand 0 "register_operand" "")
10307 (xor (match_operand 1 "register_operand" "")
10308 (match_operand 2 "const_int_operand" "")))
10309 (clobber (reg:CC FLAGS_REG))]
10311 && QI_REG_P (operands[0])
10312 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10313 && !(INTVAL (operands[2]) & ~(255 << 8))
10314 && GET_MODE (operands[0]) != QImode"
10315 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10316 (xor:SI (zero_extract:SI (match_dup 1)
10317 (const_int 8) (const_int 8))
10319 (clobber (reg:CC FLAGS_REG))])]
10320 "operands[0] = gen_lowpart (SImode, operands[0]);
10321 operands[1] = gen_lowpart (SImode, operands[1]);
10322 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10324 ;; Since XOR can be encoded with sign extended immediate, this is only
10325 ;; profitable when 7th bit is set.
10327 [(set (match_operand 0 "register_operand" "")
10328 (xor (match_operand 1 "general_operand" "")
10329 (match_operand 2 "const_int_operand" "")))
10330 (clobber (reg:CC FLAGS_REG))]
10332 && ANY_QI_REG_P (operands[0])
10333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10334 && !(INTVAL (operands[2]) & ~255)
10335 && (INTVAL (operands[2]) & 128)
10336 && GET_MODE (operands[0]) != QImode"
10337 [(parallel [(set (strict_low_part (match_dup 0))
10338 (xor:QI (match_dup 1)
10340 (clobber (reg:CC FLAGS_REG))])]
10341 "operands[0] = gen_lowpart (QImode, operands[0]);
10342 operands[1] = gen_lowpart (QImode, operands[1]);
10343 operands[2] = gen_lowpart (QImode, operands[2]);")
10345 ;; Negation instructions
10347 (define_expand "negti2"
10348 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10349 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10351 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10353 (define_insn "*negti2_1"
10354 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10355 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10356 (clobber (reg:CC FLAGS_REG))]
10358 && ix86_unary_operator_ok (NEG, TImode, operands)"
10362 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10363 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "TARGET_64BIT && reload_completed"
10367 [(set (reg:CCZ FLAGS_REG)
10368 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10369 (set (match_dup 0) (neg:DI (match_dup 1)))])
10371 [(set (match_dup 2)
10372 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10375 (clobber (reg:CC FLAGS_REG))])
10377 [(set (match_dup 2)
10378 (neg:DI (match_dup 2)))
10379 (clobber (reg:CC FLAGS_REG))])]
10380 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10382 (define_expand "negdi2"
10383 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10384 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10386 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10388 (define_insn "*negdi2_1"
10389 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10390 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10391 (clobber (reg:CC FLAGS_REG))]
10393 && ix86_unary_operator_ok (NEG, DImode, operands)"
10397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10398 (neg:DI (match_operand:DI 1 "general_operand" "")))
10399 (clobber (reg:CC FLAGS_REG))]
10400 "!TARGET_64BIT && reload_completed"
10402 [(set (reg:CCZ FLAGS_REG)
10403 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10404 (set (match_dup 0) (neg:SI (match_dup 1)))])
10406 [(set (match_dup 2)
10407 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10410 (clobber (reg:CC FLAGS_REG))])
10412 [(set (match_dup 2)
10413 (neg:SI (match_dup 2)))
10414 (clobber (reg:CC FLAGS_REG))])]
10415 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10417 (define_insn "*negdi2_1_rex64"
10418 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10419 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10423 [(set_attr "type" "negnot")
10424 (set_attr "mode" "DI")])
10426 ;; The problem with neg is that it does not perform (compare x 0),
10427 ;; it really performs (compare 0 x), which leaves us with the zero
10428 ;; flag being the only useful item.
10430 (define_insn "*negdi2_cmpz_rex64"
10431 [(set (reg:CCZ FLAGS_REG)
10432 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10434 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10435 (neg:DI (match_dup 1)))]
10436 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10438 [(set_attr "type" "negnot")
10439 (set_attr "mode" "DI")])
10442 (define_expand "negsi2"
10443 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10446 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10448 (define_insn "*negsi2_1"
10449 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10451 (clobber (reg:CC FLAGS_REG))]
10452 "ix86_unary_operator_ok (NEG, SImode, operands)"
10454 [(set_attr "type" "negnot")
10455 (set_attr "mode" "SI")])
10457 ;; Combine is quite creative about this pattern.
10458 (define_insn "*negsi2_1_zext"
10459 [(set (match_operand:DI 0 "register_operand" "=r")
10460 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10463 (clobber (reg:CC FLAGS_REG))]
10464 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10466 [(set_attr "type" "negnot")
10467 (set_attr "mode" "SI")])
10469 ;; The problem with neg is that it does not perform (compare x 0),
10470 ;; it really performs (compare 0 x), which leaves us with the zero
10471 ;; flag being the only useful item.
10473 (define_insn "*negsi2_cmpz"
10474 [(set (reg:CCZ FLAGS_REG)
10475 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10477 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10478 (neg:SI (match_dup 1)))]
10479 "ix86_unary_operator_ok (NEG, SImode, operands)"
10481 [(set_attr "type" "negnot")
10482 (set_attr "mode" "SI")])
10484 (define_insn "*negsi2_cmpz_zext"
10485 [(set (reg:CCZ FLAGS_REG)
10486 (compare:CCZ (lshiftrt:DI
10488 (match_operand:DI 1 "register_operand" "0")
10492 (set (match_operand:DI 0 "register_operand" "=r")
10493 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10496 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10498 [(set_attr "type" "negnot")
10499 (set_attr "mode" "SI")])
10501 (define_expand "neghi2"
10502 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504 "TARGET_HIMODE_MATH"
10505 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10507 (define_insn "*neghi2_1"
10508 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "ix86_unary_operator_ok (NEG, HImode, operands)"
10513 [(set_attr "type" "negnot")
10514 (set_attr "mode" "HI")])
10516 (define_insn "*neghi2_cmpz"
10517 [(set (reg:CCZ FLAGS_REG)
10518 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10520 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10521 (neg:HI (match_dup 1)))]
10522 "ix86_unary_operator_ok (NEG, HImode, operands)"
10524 [(set_attr "type" "negnot")
10525 (set_attr "mode" "HI")])
10527 (define_expand "negqi2"
10528 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10529 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10530 "TARGET_QIMODE_MATH"
10531 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10533 (define_insn "*negqi2_1"
10534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10536 (clobber (reg:CC FLAGS_REG))]
10537 "ix86_unary_operator_ok (NEG, QImode, operands)"
10539 [(set_attr "type" "negnot")
10540 (set_attr "mode" "QI")])
10542 (define_insn "*negqi2_cmpz"
10543 [(set (reg:CCZ FLAGS_REG)
10544 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10546 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10547 (neg:QI (match_dup 1)))]
10548 "ix86_unary_operator_ok (NEG, QImode, operands)"
10550 [(set_attr "type" "negnot")
10551 (set_attr "mode" "QI")])
10553 ;; Changing of sign for FP values is doable using integer unit too.
10555 (define_expand "<code><mode>2"
10556 [(set (match_operand:X87MODEF 0 "register_operand" "")
10557 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10558 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10559 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10561 (define_insn "*absneg<mode>2_mixed"
10562 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10563 (match_operator:MODEF 3 "absneg_operator"
10564 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10565 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10566 (clobber (reg:CC FLAGS_REG))]
10567 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10570 (define_insn "*absneg<mode>2_sse"
10571 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10572 (match_operator:MODEF 3 "absneg_operator"
10573 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10574 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10579 (define_insn "*absneg<mode>2_i387"
10580 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10581 (match_operator:X87MODEF 3 "absneg_operator"
10582 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10583 (use (match_operand 2 "" ""))
10584 (clobber (reg:CC FLAGS_REG))]
10585 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10588 (define_expand "<code>tf2"
10589 [(set (match_operand:TF 0 "register_operand" "")
10590 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10592 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10594 (define_insn "*absnegtf2_sse"
10595 [(set (match_operand:TF 0 "register_operand" "=x,x")
10596 (match_operator:TF 3 "absneg_operator"
10597 [(match_operand:TF 1 "register_operand" "0,x")]))
10598 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10599 (clobber (reg:CC FLAGS_REG))]
10603 ;; Splitters for fp abs and neg.
10606 [(set (match_operand 0 "fp_register_operand" "")
10607 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10608 (use (match_operand 2 "" ""))
10609 (clobber (reg:CC FLAGS_REG))]
10611 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10614 [(set (match_operand 0 "register_operand" "")
10615 (match_operator 3 "absneg_operator"
10616 [(match_operand 1 "register_operand" "")]))
10617 (use (match_operand 2 "nonimmediate_operand" ""))
10618 (clobber (reg:CC FLAGS_REG))]
10619 "reload_completed && SSE_REG_P (operands[0])"
10620 [(set (match_dup 0) (match_dup 3))]
10622 enum machine_mode mode = GET_MODE (operands[0]);
10623 enum machine_mode vmode = GET_MODE (operands[2]);
10626 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10627 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10628 if (operands_match_p (operands[0], operands[2]))
10631 operands[1] = operands[2];
10634 if (GET_CODE (operands[3]) == ABS)
10635 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10637 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10642 [(set (match_operand:SF 0 "register_operand" "")
10643 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10644 (use (match_operand:V4SF 2 "" ""))
10645 (clobber (reg:CC FLAGS_REG))]
10647 [(parallel [(set (match_dup 0) (match_dup 1))
10648 (clobber (reg:CC FLAGS_REG))])]
10651 operands[0] = gen_lowpart (SImode, operands[0]);
10652 if (GET_CODE (operands[1]) == ABS)
10654 tmp = gen_int_mode (0x7fffffff, SImode);
10655 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10659 tmp = gen_int_mode (0x80000000, SImode);
10660 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10666 [(set (match_operand:DF 0 "register_operand" "")
10667 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10668 (use (match_operand 2 "" ""))
10669 (clobber (reg:CC FLAGS_REG))]
10671 [(parallel [(set (match_dup 0) (match_dup 1))
10672 (clobber (reg:CC FLAGS_REG))])]
10677 tmp = gen_lowpart (DImode, operands[0]);
10678 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10681 if (GET_CODE (operands[1]) == ABS)
10684 tmp = gen_rtx_NOT (DImode, tmp);
10688 operands[0] = gen_highpart (SImode, operands[0]);
10689 if (GET_CODE (operands[1]) == ABS)
10691 tmp = gen_int_mode (0x7fffffff, SImode);
10692 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10696 tmp = gen_int_mode (0x80000000, SImode);
10697 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10704 [(set (match_operand:XF 0 "register_operand" "")
10705 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10706 (use (match_operand 2 "" ""))
10707 (clobber (reg:CC FLAGS_REG))]
10709 [(parallel [(set (match_dup 0) (match_dup 1))
10710 (clobber (reg:CC FLAGS_REG))])]
10713 operands[0] = gen_rtx_REG (SImode,
10714 true_regnum (operands[0])
10715 + (TARGET_64BIT ? 1 : 2));
10716 if (GET_CODE (operands[1]) == ABS)
10718 tmp = GEN_INT (0x7fff);
10719 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10723 tmp = GEN_INT (0x8000);
10724 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10729 ;; Conditionalize these after reload. If they match before reload, we
10730 ;; lose the clobber and ability to use integer instructions.
10732 (define_insn "*<code><mode>2_1"
10733 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10734 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10736 && (reload_completed
10737 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10739 [(set_attr "type" "fsgn")
10740 (set_attr "mode" "<MODE>")])
10742 (define_insn "*<code>extendsfdf2"
10743 [(set (match_operand:DF 0 "register_operand" "=f")
10744 (absneg:DF (float_extend:DF
10745 (match_operand:SF 1 "register_operand" "0"))))]
10746 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10748 [(set_attr "type" "fsgn")
10749 (set_attr "mode" "DF")])
10751 (define_insn "*<code>extendsfxf2"
10752 [(set (match_operand:XF 0 "register_operand" "=f")
10753 (absneg:XF (float_extend:XF
10754 (match_operand:SF 1 "register_operand" "0"))))]
10757 [(set_attr "type" "fsgn")
10758 (set_attr "mode" "XF")])
10760 (define_insn "*<code>extenddfxf2"
10761 [(set (match_operand:XF 0 "register_operand" "=f")
10762 (absneg:XF (float_extend:XF
10763 (match_operand:DF 1 "register_operand" "0"))))]
10766 [(set_attr "type" "fsgn")
10767 (set_attr "mode" "XF")])
10769 ;; Copysign instructions
10771 (define_mode_iterator CSGNMODE [SF DF TF])
10772 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10774 (define_expand "copysign<mode>3"
10775 [(match_operand:CSGNMODE 0 "register_operand" "")
10776 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10777 (match_operand:CSGNMODE 2 "register_operand" "")]
10778 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10779 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10781 ix86_expand_copysign (operands);
10785 (define_insn_and_split "copysign<mode>3_const"
10786 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10788 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10789 (match_operand:CSGNMODE 2 "register_operand" "0")
10790 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10792 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10793 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10795 "&& reload_completed"
10798 ix86_split_copysign_const (operands);
10802 (define_insn "copysign<mode>3_var"
10803 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10805 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10806 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10807 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10808 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10810 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10811 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10816 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10818 [(match_operand:CSGNMODE 2 "register_operand" "")
10819 (match_operand:CSGNMODE 3 "register_operand" "")
10820 (match_operand:<CSGNVMODE> 4 "" "")
10821 (match_operand:<CSGNVMODE> 5 "" "")]
10823 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10824 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10826 && reload_completed"
10829 ix86_split_copysign_var (operands);
10833 ;; One complement instructions
10835 (define_expand "one_cmpldi2"
10836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10837 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10839 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10841 (define_insn "*one_cmpldi2_1_rex64"
10842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10843 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10844 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10846 [(set_attr "type" "negnot")
10847 (set_attr "mode" "DI")])
10849 (define_insn "*one_cmpldi2_2_rex64"
10850 [(set (reg FLAGS_REG)
10851 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10853 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10854 (not:DI (match_dup 1)))]
10855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10856 && ix86_unary_operator_ok (NOT, DImode, operands)"
10858 [(set_attr "type" "alu1")
10859 (set_attr "mode" "DI")])
10862 [(set (match_operand 0 "flags_reg_operand" "")
10863 (match_operator 2 "compare_operator"
10864 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10866 (set (match_operand:DI 1 "nonimmediate_operand" "")
10867 (not:DI (match_dup 3)))]
10868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10869 [(parallel [(set (match_dup 0)
10871 [(xor:DI (match_dup 3) (const_int -1))
10874 (xor:DI (match_dup 3) (const_int -1)))])]
10877 (define_expand "one_cmplsi2"
10878 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10879 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10881 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10883 (define_insn "*one_cmplsi2_1"
10884 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10885 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10886 "ix86_unary_operator_ok (NOT, SImode, operands)"
10888 [(set_attr "type" "negnot")
10889 (set_attr "mode" "SI")])
10891 ;; ??? Currently never generated - xor is used instead.
10892 (define_insn "*one_cmplsi2_1_zext"
10893 [(set (match_operand:DI 0 "register_operand" "=r")
10894 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10895 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10897 [(set_attr "type" "negnot")
10898 (set_attr "mode" "SI")])
10900 (define_insn "*one_cmplsi2_2"
10901 [(set (reg FLAGS_REG)
10902 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10904 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10905 (not:SI (match_dup 1)))]
10906 "ix86_match_ccmode (insn, CCNOmode)
10907 && ix86_unary_operator_ok (NOT, SImode, operands)"
10909 [(set_attr "type" "alu1")
10910 (set_attr "mode" "SI")])
10913 [(set (match_operand 0 "flags_reg_operand" "")
10914 (match_operator 2 "compare_operator"
10915 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10917 (set (match_operand:SI 1 "nonimmediate_operand" "")
10918 (not:SI (match_dup 3)))]
10919 "ix86_match_ccmode (insn, CCNOmode)"
10920 [(parallel [(set (match_dup 0)
10921 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10924 (xor:SI (match_dup 3) (const_int -1)))])]
10927 ;; ??? Currently never generated - xor is used instead.
10928 (define_insn "*one_cmplsi2_2_zext"
10929 [(set (reg FLAGS_REG)
10930 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10932 (set (match_operand:DI 0 "register_operand" "=r")
10933 (zero_extend:DI (not:SI (match_dup 1))))]
10934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10935 && ix86_unary_operator_ok (NOT, SImode, operands)"
10937 [(set_attr "type" "alu1")
10938 (set_attr "mode" "SI")])
10941 [(set (match_operand 0 "flags_reg_operand" "")
10942 (match_operator 2 "compare_operator"
10943 [(not:SI (match_operand:SI 3 "register_operand" ""))
10945 (set (match_operand:DI 1 "register_operand" "")
10946 (zero_extend:DI (not:SI (match_dup 3))))]
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 [(parallel [(set (match_dup 0)
10949 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10952 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10955 (define_expand "one_cmplhi2"
10956 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10957 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10958 "TARGET_HIMODE_MATH"
10959 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10961 (define_insn "*one_cmplhi2_1"
10962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10963 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10964 "ix86_unary_operator_ok (NOT, HImode, operands)"
10966 [(set_attr "type" "negnot")
10967 (set_attr "mode" "HI")])
10969 (define_insn "*one_cmplhi2_2"
10970 [(set (reg FLAGS_REG)
10971 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10973 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10974 (not:HI (match_dup 1)))]
10975 "ix86_match_ccmode (insn, CCNOmode)
10976 && ix86_unary_operator_ok (NEG, HImode, operands)"
10978 [(set_attr "type" "alu1")
10979 (set_attr "mode" "HI")])
10982 [(set (match_operand 0 "flags_reg_operand" "")
10983 (match_operator 2 "compare_operator"
10984 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10986 (set (match_operand:HI 1 "nonimmediate_operand" "")
10987 (not:HI (match_dup 3)))]
10988 "ix86_match_ccmode (insn, CCNOmode)"
10989 [(parallel [(set (match_dup 0)
10990 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10993 (xor:HI (match_dup 3) (const_int -1)))])]
10996 ;; %%% Potential partial reg stall on alternative 1. What to do?
10997 (define_expand "one_cmplqi2"
10998 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10999 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11000 "TARGET_QIMODE_MATH"
11001 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11003 (define_insn "*one_cmplqi2_1"
11004 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11005 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11006 "ix86_unary_operator_ok (NOT, QImode, operands)"
11010 [(set_attr "type" "negnot")
11011 (set_attr "mode" "QI,SI")])
11013 (define_insn "*one_cmplqi2_2"
11014 [(set (reg FLAGS_REG)
11015 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11017 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11018 (not:QI (match_dup 1)))]
11019 "ix86_match_ccmode (insn, CCNOmode)
11020 && ix86_unary_operator_ok (NOT, QImode, operands)"
11022 [(set_attr "type" "alu1")
11023 (set_attr "mode" "QI")])
11026 [(set (match_operand 0 "flags_reg_operand" "")
11027 (match_operator 2 "compare_operator"
11028 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11030 (set (match_operand:QI 1 "nonimmediate_operand" "")
11031 (not:QI (match_dup 3)))]
11032 "ix86_match_ccmode (insn, CCNOmode)"
11033 [(parallel [(set (match_dup 0)
11034 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11037 (xor:QI (match_dup 3) (const_int -1)))])]
11040 ;; Arithmetic shift instructions
11042 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11043 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11044 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11045 ;; from the assembler input.
11047 ;; This instruction shifts the target reg/mem as usual, but instead of
11048 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11049 ;; is a left shift double, bits are taken from the high order bits of
11050 ;; reg, else if the insn is a shift right double, bits are taken from the
11051 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11052 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11054 ;; Since sh[lr]d does not change the `reg' operand, that is done
11055 ;; separately, making all shifts emit pairs of shift double and normal
11056 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11057 ;; support a 63 bit shift, each shift where the count is in a reg expands
11058 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11060 ;; If the shift count is a constant, we need never emit more than one
11061 ;; shift pair, instead using moves and sign extension for counts greater
11064 (define_expand "ashlti3"
11065 [(set (match_operand:TI 0 "register_operand" "")
11066 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11067 (match_operand:QI 2 "nonmemory_operand" "")))]
11069 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11071 ;; This pattern must be defined before *ashlti3_1 to prevent
11072 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11074 (define_insn "*avx_ashlti3"
11075 [(set (match_operand:TI 0 "register_operand" "=x")
11076 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11077 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11080 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11081 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11083 [(set_attr "type" "sseishft")
11084 (set_attr "prefix" "vex")
11085 (set_attr "mode" "TI")])
11087 (define_insn "sse2_ashlti3"
11088 [(set (match_operand:TI 0 "register_operand" "=x")
11089 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11090 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11093 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11094 return "pslldq\t{%2, %0|%0, %2}";
11096 [(set_attr "type" "sseishft")
11097 (set_attr "prefix_data16" "1")
11098 (set_attr "mode" "TI")])
11100 (define_insn "*ashlti3_1"
11101 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11102 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11103 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11104 (clobber (reg:CC FLAGS_REG))]
11107 [(set_attr "type" "multi")])
11110 [(match_scratch:DI 3 "r")
11111 (parallel [(set (match_operand:TI 0 "register_operand" "")
11112 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11113 (match_operand:QI 2 "nonmemory_operand" "")))
11114 (clobber (reg:CC FLAGS_REG))])
11118 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11121 [(set (match_operand:TI 0 "register_operand" "")
11122 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11123 (match_operand:QI 2 "nonmemory_operand" "")))
11124 (clobber (reg:CC FLAGS_REG))]
11125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11126 ? epilogue_completed : reload_completed)"
11128 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11130 (define_insn "x86_64_shld"
11131 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11132 (ior:DI (ashift:DI (match_dup 0)
11133 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11135 (minus:QI (const_int 64) (match_dup 2)))))
11136 (clobber (reg:CC FLAGS_REG))]
11138 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11139 [(set_attr "type" "ishift")
11140 (set_attr "prefix_0f" "1")
11141 (set_attr "mode" "DI")
11142 (set_attr "athlon_decode" "vector")
11143 (set_attr "amdfam10_decode" "vector")])
11145 (define_expand "x86_64_shift_adj_1"
11146 [(set (reg:CCZ FLAGS_REG)
11147 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11150 (set (match_operand:DI 0 "register_operand" "")
11151 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11152 (match_operand:DI 1 "register_operand" "")
11155 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11156 (match_operand:DI 3 "register_operand" "r")
11161 (define_expand "x86_64_shift_adj_2"
11162 [(use (match_operand:DI 0 "register_operand" ""))
11163 (use (match_operand:DI 1 "register_operand" ""))
11164 (use (match_operand:QI 2 "register_operand" ""))]
11167 rtx label = gen_label_rtx ();
11170 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11172 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11173 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11174 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11175 gen_rtx_LABEL_REF (VOIDmode, label),
11177 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11178 JUMP_LABEL (tmp) = label;
11180 emit_move_insn (operands[0], operands[1]);
11181 ix86_expand_clear (operands[1]);
11183 emit_label (label);
11184 LABEL_NUSES (label) = 1;
11189 (define_expand "ashldi3"
11190 [(set (match_operand:DI 0 "shiftdi_operand" "")
11191 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11192 (match_operand:QI 2 "nonmemory_operand" "")))]
11194 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11196 (define_insn "*ashldi3_1_rex64"
11197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11203 switch (get_attr_type (insn))
11206 gcc_assert (operands[2] == const1_rtx);
11207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11208 return "add{q}\t%0, %0";
11211 gcc_assert (CONST_INT_P (operands[2]));
11212 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11213 operands[1] = gen_rtx_MULT (DImode, operands[1],
11214 GEN_INT (1 << INTVAL (operands[2])));
11215 return "lea{q}\t{%a1, %0|%0, %a1}";
11218 if (REG_P (operands[2]))
11219 return "sal{q}\t{%b2, %0|%0, %b2}";
11220 else if (operands[2] == const1_rtx
11221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11222 return "sal{q}\t%0";
11224 return "sal{q}\t{%2, %0|%0, %2}";
11227 [(set (attr "type")
11228 (cond [(eq_attr "alternative" "1")
11229 (const_string "lea")
11230 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11232 (match_operand 0 "register_operand" ""))
11233 (match_operand 2 "const1_operand" ""))
11234 (const_string "alu")
11236 (const_string "ishift")))
11237 (set_attr "mode" "DI")])
11239 ;; Convert lea to the lea pattern to avoid flags dependency.
11241 [(set (match_operand:DI 0 "register_operand" "")
11242 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11243 (match_operand:QI 2 "immediate_operand" "")))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "TARGET_64BIT && reload_completed
11246 && true_regnum (operands[0]) != true_regnum (operands[1])"
11247 [(set (match_dup 0)
11248 (mult:DI (match_dup 1)
11250 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags. We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashldi3_cmp_rex64"
11256 [(set (reg FLAGS_REG)
11258 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11259 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11261 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11262 (ashift:DI (match_dup 1) (match_dup 2)))]
11264 && (optimize_function_for_size_p (cfun)
11265 || !TARGET_PARTIAL_FLAG_REG_STALL
11266 || (operands[2] == const1_rtx
11268 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11269 && ix86_match_ccmode (insn, CCGOCmode)
11270 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11272 switch (get_attr_type (insn))
11275 gcc_assert (operands[2] == const1_rtx);
11276 return "add{q}\t%0, %0";
11279 if (REG_P (operands[2]))
11280 return "sal{q}\t{%b2, %0|%0, %b2}";
11281 else if (operands[2] == const1_rtx
11282 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11283 return "sal{q}\t%0";
11285 return "sal{q}\t{%2, %0|%0, %2}";
11288 [(set (attr "type")
11289 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11291 (match_operand 0 "register_operand" ""))
11292 (match_operand 2 "const1_operand" ""))
11293 (const_string "alu")
11295 (const_string "ishift")))
11296 (set_attr "mode" "DI")])
11298 (define_insn "*ashldi3_cconly_rex64"
11299 [(set (reg FLAGS_REG)
11301 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11304 (clobber (match_scratch:DI 0 "=r"))]
11306 && (optimize_function_for_size_p (cfun)
11307 || !TARGET_PARTIAL_FLAG_REG_STALL
11308 || (operands[2] == const1_rtx
11310 || TARGET_DOUBLE_WITH_ADD)))
11311 && ix86_match_ccmode (insn, CCGOCmode)
11312 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11314 switch (get_attr_type (insn))
11317 gcc_assert (operands[2] == const1_rtx);
11318 return "add{q}\t%0, %0";
11321 if (REG_P (operands[2]))
11322 return "sal{q}\t{%b2, %0|%0, %b2}";
11323 else if (operands[2] == const1_rtx
11324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11325 return "sal{q}\t%0";
11327 return "sal{q}\t{%2, %0|%0, %2}";
11330 [(set (attr "type")
11331 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11333 (match_operand 0 "register_operand" ""))
11334 (match_operand 2 "const1_operand" ""))
11335 (const_string "alu")
11337 (const_string "ishift")))
11338 (set_attr "mode" "DI")])
11340 (define_insn "*ashldi3_1"
11341 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11342 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11343 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11344 (clobber (reg:CC FLAGS_REG))]
11347 [(set_attr "type" "multi")])
11349 ;; By default we don't ask for a scratch register, because when DImode
11350 ;; values are manipulated, registers are already at a premium. But if
11351 ;; we have one handy, we won't turn it away.
11353 [(match_scratch:SI 3 "r")
11354 (parallel [(set (match_operand:DI 0 "register_operand" "")
11355 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11356 (match_operand:QI 2 "nonmemory_operand" "")))
11357 (clobber (reg:CC FLAGS_REG))])
11359 "!TARGET_64BIT && TARGET_CMOVE"
11361 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11364 [(set (match_operand:DI 0 "register_operand" "")
11365 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11366 (match_operand:QI 2 "nonmemory_operand" "")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11369 ? epilogue_completed : reload_completed)"
11371 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11373 (define_insn "x86_shld"
11374 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11375 (ior:SI (ashift:SI (match_dup 0)
11376 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11377 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11378 (minus:QI (const_int 32) (match_dup 2)))))
11379 (clobber (reg:CC FLAGS_REG))]
11381 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11382 [(set_attr "type" "ishift")
11383 (set_attr "prefix_0f" "1")
11384 (set_attr "mode" "SI")
11385 (set_attr "pent_pair" "np")
11386 (set_attr "athlon_decode" "vector")
11387 (set_attr "amdfam10_decode" "vector")])
11389 (define_expand "x86_shift_adj_1"
11390 [(set (reg:CCZ FLAGS_REG)
11391 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11394 (set (match_operand:SI 0 "register_operand" "")
11395 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11396 (match_operand:SI 1 "register_operand" "")
11399 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11400 (match_operand:SI 3 "register_operand" "r")
11405 (define_expand "x86_shift_adj_2"
11406 [(use (match_operand:SI 0 "register_operand" ""))
11407 (use (match_operand:SI 1 "register_operand" ""))
11408 (use (match_operand:QI 2 "register_operand" ""))]
11411 rtx label = gen_label_rtx ();
11414 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11416 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11417 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11418 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11419 gen_rtx_LABEL_REF (VOIDmode, label),
11421 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11422 JUMP_LABEL (tmp) = label;
11424 emit_move_insn (operands[0], operands[1]);
11425 ix86_expand_clear (operands[1]);
11427 emit_label (label);
11428 LABEL_NUSES (label) = 1;
11433 (define_expand "ashlsi3"
11434 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11435 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11436 (match_operand:QI 2 "nonmemory_operand" "")))]
11438 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11440 (define_insn "*ashlsi3_1"
11441 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11442 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11443 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11444 (clobber (reg:CC FLAGS_REG))]
11445 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11447 switch (get_attr_type (insn))
11450 gcc_assert (operands[2] == const1_rtx);
11451 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11452 return "add{l}\t%0, %0";
11458 if (REG_P (operands[2]))
11459 return "sal{l}\t{%b2, %0|%0, %b2}";
11460 else if (operands[2] == const1_rtx
11461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462 return "sal{l}\t%0";
11464 return "sal{l}\t{%2, %0|%0, %2}";
11467 [(set (attr "type")
11468 (cond [(eq_attr "alternative" "1")
11469 (const_string "lea")
11470 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11472 (match_operand 0 "register_operand" ""))
11473 (match_operand 2 "const1_operand" ""))
11474 (const_string "alu")
11476 (const_string "ishift")))
11477 (set_attr "mode" "SI")])
11479 ;; Convert lea to the lea pattern to avoid flags dependency.
11481 [(set (match_operand 0 "register_operand" "")
11482 (ashift (match_operand 1 "index_register_operand" "")
11483 (match_operand:QI 2 "const_int_operand" "")))
11484 (clobber (reg:CC FLAGS_REG))]
11486 && true_regnum (operands[0]) != true_regnum (operands[1])
11487 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11491 enum machine_mode mode = GET_MODE (operands[0]);
11493 if (GET_MODE_SIZE (mode) < 4)
11494 operands[0] = gen_lowpart (SImode, operands[0]);
11496 operands[1] = gen_lowpart (Pmode, operands[1]);
11497 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11499 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11500 if (Pmode != SImode)
11501 pat = gen_rtx_SUBREG (SImode, pat, 0);
11502 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11506 ;; Rare case of shifting RSP is handled by generating move and shift
11508 [(set (match_operand 0 "register_operand" "")
11509 (ashift (match_operand 1 "register_operand" "")
11510 (match_operand:QI 2 "const_int_operand" "")))
11511 (clobber (reg:CC FLAGS_REG))]
11513 && true_regnum (operands[0]) != true_regnum (operands[1])"
11517 emit_move_insn (operands[0], operands[1]);
11518 pat = gen_rtx_SET (VOIDmode, operands[0],
11519 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11520 operands[0], operands[2]));
11521 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11522 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11526 (define_insn "*ashlsi3_1_zext"
11527 [(set (match_operand:DI 0 "register_operand" "=r,r")
11528 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11529 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11530 (clobber (reg:CC FLAGS_REG))]
11531 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11533 switch (get_attr_type (insn))
11536 gcc_assert (operands[2] == const1_rtx);
11537 return "add{l}\t%k0, %k0";
11543 if (REG_P (operands[2]))
11544 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11545 else if (operands[2] == const1_rtx
11546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11547 return "sal{l}\t%k0";
11549 return "sal{l}\t{%2, %k0|%k0, %2}";
11552 [(set (attr "type")
11553 (cond [(eq_attr "alternative" "1")
11554 (const_string "lea")
11555 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11557 (match_operand 2 "const1_operand" ""))
11558 (const_string "alu")
11560 (const_string "ishift")))
11561 (set_attr "mode" "SI")])
11563 ;; Convert lea to the lea pattern to avoid flags dependency.
11565 [(set (match_operand:DI 0 "register_operand" "")
11566 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11567 (match_operand:QI 2 "const_int_operand" ""))))
11568 (clobber (reg:CC FLAGS_REG))]
11569 "TARGET_64BIT && reload_completed
11570 && true_regnum (operands[0]) != true_regnum (operands[1])"
11571 [(set (match_dup 0) (zero_extend:DI
11572 (subreg:SI (mult:SI (match_dup 1)
11573 (match_dup 2)) 0)))]
11575 operands[1] = gen_lowpart (Pmode, operands[1]);
11576 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags. We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*ashlsi3_cmp"
11583 [(set (reg FLAGS_REG)
11585 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589 (ashift:SI (match_dup 1) (match_dup 2)))]
11590 "(optimize_function_for_size_p (cfun)
11591 || !TARGET_PARTIAL_FLAG_REG_STALL
11592 || (operands[2] == const1_rtx
11594 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11595 && ix86_match_ccmode (insn, CCGOCmode)
11596 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11598 switch (get_attr_type (insn))
11601 gcc_assert (operands[2] == const1_rtx);
11602 return "add{l}\t%0, %0";
11605 if (REG_P (operands[2]))
11606 return "sal{l}\t{%b2, %0|%0, %b2}";
11607 else if (operands[2] == const1_rtx
11608 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11609 return "sal{l}\t%0";
11611 return "sal{l}\t{%2, %0|%0, %2}";
11614 [(set (attr "type")
11615 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11617 (match_operand 0 "register_operand" ""))
11618 (match_operand 2 "const1_operand" ""))
11619 (const_string "alu")
11621 (const_string "ishift")))
11622 (set_attr "mode" "SI")])
11624 (define_insn "*ashlsi3_cconly"
11625 [(set (reg FLAGS_REG)
11627 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11630 (clobber (match_scratch:SI 0 "=r"))]
11631 "(optimize_function_for_size_p (cfun)
11632 || !TARGET_PARTIAL_FLAG_REG_STALL
11633 || (operands[2] == const1_rtx
11635 || TARGET_DOUBLE_WITH_ADD)))
11636 && ix86_match_ccmode (insn, CCGOCmode)
11637 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11639 switch (get_attr_type (insn))
11642 gcc_assert (operands[2] == const1_rtx);
11643 return "add{l}\t%0, %0";
11646 if (REG_P (operands[2]))
11647 return "sal{l}\t{%b2, %0|%0, %b2}";
11648 else if (operands[2] == const1_rtx
11649 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11650 return "sal{l}\t%0";
11652 return "sal{l}\t{%2, %0|%0, %2}";
11655 [(set (attr "type")
11656 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11658 (match_operand 0 "register_operand" ""))
11659 (match_operand 2 "const1_operand" ""))
11660 (const_string "alu")
11662 (const_string "ishift")))
11663 (set_attr "mode" "SI")])
11665 (define_insn "*ashlsi3_cmp_zext"
11666 [(set (reg FLAGS_REG)
11668 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11669 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11671 (set (match_operand:DI 0 "register_operand" "=r")
11672 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11674 && (optimize_function_for_size_p (cfun)
11675 || !TARGET_PARTIAL_FLAG_REG_STALL
11676 || (operands[2] == const1_rtx
11678 || TARGET_DOUBLE_WITH_ADD)))
11679 && ix86_match_ccmode (insn, CCGOCmode)
11680 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11682 switch (get_attr_type (insn))
11685 gcc_assert (operands[2] == const1_rtx);
11686 return "add{l}\t%k0, %k0";
11689 if (REG_P (operands[2]))
11690 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11691 else if (operands[2] == const1_rtx
11692 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11693 return "sal{l}\t%k0";
11695 return "sal{l}\t{%2, %k0|%k0, %2}";
11698 [(set (attr "type")
11699 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11701 (match_operand 2 "const1_operand" ""))
11702 (const_string "alu")
11704 (const_string "ishift")))
11705 (set_attr "mode" "SI")])
11707 (define_expand "ashlhi3"
11708 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11709 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11710 (match_operand:QI 2 "nonmemory_operand" "")))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11714 (define_insn "*ashlhi3_1_lea"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11716 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11717 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "!TARGET_PARTIAL_REG_STALL
11720 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11722 switch (get_attr_type (insn))
11727 gcc_assert (operands[2] == const1_rtx);
11728 return "add{w}\t%0, %0";
11731 if (REG_P (operands[2]))
11732 return "sal{w}\t{%b2, %0|%0, %b2}";
11733 else if (operands[2] == const1_rtx
11734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11735 return "sal{w}\t%0";
11737 return "sal{w}\t{%2, %0|%0, %2}";
11740 [(set (attr "type")
11741 (cond [(eq_attr "alternative" "1")
11742 (const_string "lea")
11743 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11745 (match_operand 0 "register_operand" ""))
11746 (match_operand 2 "const1_operand" ""))
11747 (const_string "alu")
11749 (const_string "ishift")))
11750 (set_attr "mode" "HI,SI")])
11752 (define_insn "*ashlhi3_1"
11753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "nonmemory_operand" "cI")))
11756 (clobber (reg:CC FLAGS_REG))]
11757 "TARGET_PARTIAL_REG_STALL
11758 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11760 switch (get_attr_type (insn))
11763 gcc_assert (operands[2] == const1_rtx);
11764 return "add{w}\t%0, %0";
11767 if (REG_P (operands[2]))
11768 return "sal{w}\t{%b2, %0|%0, %b2}";
11769 else if (operands[2] == const1_rtx
11770 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11771 return "sal{w}\t%0";
11773 return "sal{w}\t{%2, %0|%0, %2}";
11776 [(set (attr "type")
11777 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11779 (match_operand 0 "register_operand" ""))
11780 (match_operand 2 "const1_operand" ""))
11781 (const_string "alu")
11783 (const_string "ishift")))
11784 (set_attr "mode" "HI")])
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags. We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashlhi3_cmp"
11790 [(set (reg FLAGS_REG)
11792 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11793 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11795 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11796 (ashift:HI (match_dup 1) (match_dup 2)))]
11797 "(optimize_function_for_size_p (cfun)
11798 || !TARGET_PARTIAL_FLAG_REG_STALL
11799 || (operands[2] == const1_rtx
11801 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11802 && ix86_match_ccmode (insn, CCGOCmode)
11803 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11805 switch (get_attr_type (insn))
11808 gcc_assert (operands[2] == const1_rtx);
11809 return "add{w}\t%0, %0";
11812 if (REG_P (operands[2]))
11813 return "sal{w}\t{%b2, %0|%0, %b2}";
11814 else if (operands[2] == const1_rtx
11815 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11816 return "sal{w}\t%0";
11818 return "sal{w}\t{%2, %0|%0, %2}";
11821 [(set (attr "type")
11822 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11824 (match_operand 0 "register_operand" ""))
11825 (match_operand 2 "const1_operand" ""))
11826 (const_string "alu")
11828 (const_string "ishift")))
11829 (set_attr "mode" "HI")])
11831 (define_insn "*ashlhi3_cconly"
11832 [(set (reg FLAGS_REG)
11834 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11837 (clobber (match_scratch:HI 0 "=r"))]
11838 "(optimize_function_for_size_p (cfun)
11839 || !TARGET_PARTIAL_FLAG_REG_STALL
11840 || (operands[2] == const1_rtx
11842 || TARGET_DOUBLE_WITH_ADD)))
11843 && ix86_match_ccmode (insn, CCGOCmode)
11844 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11846 switch (get_attr_type (insn))
11849 gcc_assert (operands[2] == const1_rtx);
11850 return "add{w}\t%0, %0";
11853 if (REG_P (operands[2]))
11854 return "sal{w}\t{%b2, %0|%0, %b2}";
11855 else if (operands[2] == const1_rtx
11856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11857 return "sal{w}\t%0";
11859 return "sal{w}\t{%2, %0|%0, %2}";
11862 [(set (attr "type")
11863 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11865 (match_operand 0 "register_operand" ""))
11866 (match_operand 2 "const1_operand" ""))
11867 (const_string "alu")
11869 (const_string "ishift")))
11870 (set_attr "mode" "HI")])
11872 (define_expand "ashlqi3"
11873 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11874 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11875 (match_operand:QI 2 "nonmemory_operand" "")))]
11876 "TARGET_QIMODE_MATH"
11877 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11879 ;; %%% Potential partial reg stall on alternative 2. What to do?
11881 (define_insn "*ashlqi3_1_lea"
11882 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11883 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11884 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "!TARGET_PARTIAL_REG_STALL
11887 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11889 switch (get_attr_type (insn))
11894 gcc_assert (operands[2] == const1_rtx);
11895 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11896 return "add{l}\t%k0, %k0";
11898 return "add{b}\t%0, %0";
11901 if (REG_P (operands[2]))
11903 if (get_attr_mode (insn) == MODE_SI)
11904 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11906 return "sal{b}\t{%b2, %0|%0, %b2}";
11908 else if (operands[2] == const1_rtx
11909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11911 if (get_attr_mode (insn) == MODE_SI)
11912 return "sal{l}\t%0";
11914 return "sal{b}\t%0";
11918 if (get_attr_mode (insn) == MODE_SI)
11919 return "sal{l}\t{%2, %k0|%k0, %2}";
11921 return "sal{b}\t{%2, %0|%0, %2}";
11925 [(set (attr "type")
11926 (cond [(eq_attr "alternative" "2")
11927 (const_string "lea")
11928 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11930 (match_operand 0 "register_operand" ""))
11931 (match_operand 2 "const1_operand" ""))
11932 (const_string "alu")
11934 (const_string "ishift")))
11935 (set_attr "mode" "QI,SI,SI")])
11937 (define_insn "*ashlqi3_1"
11938 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11939 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11940 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11941 (clobber (reg:CC FLAGS_REG))]
11942 "TARGET_PARTIAL_REG_STALL
11943 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11945 switch (get_attr_type (insn))
11948 gcc_assert (operands[2] == const1_rtx);
11949 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11950 return "add{l}\t%k0, %k0";
11952 return "add{b}\t%0, %0";
11955 if (REG_P (operands[2]))
11957 if (get_attr_mode (insn) == MODE_SI)
11958 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11960 return "sal{b}\t{%b2, %0|%0, %b2}";
11962 else if (operands[2] == const1_rtx
11963 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11965 if (get_attr_mode (insn) == MODE_SI)
11966 return "sal{l}\t%0";
11968 return "sal{b}\t%0";
11972 if (get_attr_mode (insn) == MODE_SI)
11973 return "sal{l}\t{%2, %k0|%k0, %2}";
11975 return "sal{b}\t{%2, %0|%0, %2}";
11979 [(set (attr "type")
11980 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11982 (match_operand 0 "register_operand" ""))
11983 (match_operand 2 "const1_operand" ""))
11984 (const_string "alu")
11986 (const_string "ishift")))
11987 (set_attr "mode" "QI,SI")])
11989 ;; This pattern can't accept a variable shift count, since shifts by
11990 ;; zero don't affect the flags. We assume that shifts by constant
11991 ;; zero are optimized away.
11992 (define_insn "*ashlqi3_cmp"
11993 [(set (reg FLAGS_REG)
11995 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11998 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11999 (ashift:QI (match_dup 1) (match_dup 2)))]
12000 "(optimize_function_for_size_p (cfun)
12001 || !TARGET_PARTIAL_FLAG_REG_STALL
12002 || (operands[2] == const1_rtx
12004 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12005 && ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12008 switch (get_attr_type (insn))
12011 gcc_assert (operands[2] == const1_rtx);
12012 return "add{b}\t%0, %0";
12015 if (REG_P (operands[2]))
12016 return "sal{b}\t{%b2, %0|%0, %b2}";
12017 else if (operands[2] == const1_rtx
12018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12019 return "sal{b}\t%0";
12021 return "sal{b}\t{%2, %0|%0, %2}";
12024 [(set (attr "type")
12025 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12027 (match_operand 0 "register_operand" ""))
12028 (match_operand 2 "const1_operand" ""))
12029 (const_string "alu")
12031 (const_string "ishift")))
12032 (set_attr "mode" "QI")])
12034 (define_insn "*ashlqi3_cconly"
12035 [(set (reg FLAGS_REG)
12037 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12040 (clobber (match_scratch:QI 0 "=q"))]
12041 "(optimize_function_for_size_p (cfun)
12042 || !TARGET_PARTIAL_FLAG_REG_STALL
12043 || (operands[2] == const1_rtx
12045 || TARGET_DOUBLE_WITH_ADD)))
12046 && ix86_match_ccmode (insn, CCGOCmode)
12047 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12049 switch (get_attr_type (insn))
12052 gcc_assert (operands[2] == const1_rtx);
12053 return "add{b}\t%0, %0";
12056 if (REG_P (operands[2]))
12057 return "sal{b}\t{%b2, %0|%0, %b2}";
12058 else if (operands[2] == const1_rtx
12059 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12060 return "sal{b}\t%0";
12062 return "sal{b}\t{%2, %0|%0, %2}";
12065 [(set (attr "type")
12066 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12068 (match_operand 0 "register_operand" ""))
12069 (match_operand 2 "const1_operand" ""))
12070 (const_string "alu")
12072 (const_string "ishift")))
12073 (set_attr "mode" "QI")])
12075 ;; See comment above `ashldi3' about how this works.
12077 (define_expand "ashrti3"
12078 [(set (match_operand:TI 0 "register_operand" "")
12079 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))]
12082 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12084 (define_insn "*ashrti3_1"
12085 [(set (match_operand:TI 0 "register_operand" "=r")
12086 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12087 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12088 (clobber (reg:CC FLAGS_REG))]
12091 [(set_attr "type" "multi")])
12094 [(match_scratch:DI 3 "r")
12095 (parallel [(set (match_operand:TI 0 "register_operand" "")
12096 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097 (match_operand:QI 2 "nonmemory_operand" "")))
12098 (clobber (reg:CC FLAGS_REG))])
12102 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12105 [(set (match_operand:TI 0 "register_operand" "")
12106 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12107 (match_operand:QI 2 "nonmemory_operand" "")))
12108 (clobber (reg:CC FLAGS_REG))]
12109 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12110 ? epilogue_completed : reload_completed)"
12112 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12114 (define_insn "x86_64_shrd"
12115 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12116 (ior:DI (ashiftrt:DI (match_dup 0)
12117 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12118 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12119 (minus:QI (const_int 64) (match_dup 2)))))
12120 (clobber (reg:CC FLAGS_REG))]
12122 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12123 [(set_attr "type" "ishift")
12124 (set_attr "prefix_0f" "1")
12125 (set_attr "mode" "DI")
12126 (set_attr "athlon_decode" "vector")
12127 (set_attr "amdfam10_decode" "vector")])
12129 (define_expand "ashrdi3"
12130 [(set (match_operand:DI 0 "shiftdi_operand" "")
12131 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12132 (match_operand:QI 2 "nonmemory_operand" "")))]
12134 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12136 (define_expand "x86_64_shift_adj_3"
12137 [(use (match_operand:DI 0 "register_operand" ""))
12138 (use (match_operand:DI 1 "register_operand" ""))
12139 (use (match_operand:QI 2 "register_operand" ""))]
12142 rtx label = gen_label_rtx ();
12145 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12147 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12148 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12149 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12150 gen_rtx_LABEL_REF (VOIDmode, label),
12152 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12153 JUMP_LABEL (tmp) = label;
12155 emit_move_insn (operands[0], operands[1]);
12156 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12158 emit_label (label);
12159 LABEL_NUSES (label) = 1;
12164 (define_insn "ashrdi3_63_rex64"
12165 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12166 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12167 (match_operand:DI 2 "const_int_operand" "i,i")))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "TARGET_64BIT && INTVAL (operands[2]) == 63
12170 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12171 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12174 sar{q}\t{%2, %0|%0, %2}"
12175 [(set_attr "type" "imovx,ishift")
12176 (set_attr "prefix_0f" "0,*")
12177 (set_attr "length_immediate" "0,*")
12178 (set_attr "modrm" "0,1")
12179 (set_attr "mode" "DI")])
12181 (define_insn "*ashrdi3_1_one_bit_rex64"
12182 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12183 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12184 (match_operand:QI 2 "const1_operand" "")))
12185 (clobber (reg:CC FLAGS_REG))]
12187 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12188 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12190 [(set_attr "type" "ishift")
12191 (set (attr "length")
12192 (if_then_else (match_operand:DI 0 "register_operand" "")
12194 (const_string "*")))])
12196 (define_insn "*ashrdi3_1_rex64"
12197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12198 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12199 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12203 sar{q}\t{%2, %0|%0, %2}
12204 sar{q}\t{%b2, %0|%0, %b2}"
12205 [(set_attr "type" "ishift")
12206 (set_attr "mode" "DI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags. We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12212 [(set (reg FLAGS_REG)
12214 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12215 (match_operand:QI 2 "const1_operand" ""))
12217 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12218 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221 && ix86_match_ccmode (insn, CCGOCmode)
12222 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand:DI 0 "register_operand" "")
12228 (const_string "*")))])
12230 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12231 [(set (reg FLAGS_REG)
12233 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (clobber (match_scratch:DI 0 "=r"))]
12238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239 && ix86_match_ccmode (insn, CCGOCmode)
12240 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12242 [(set_attr "type" "ishift")
12243 (set_attr "length" "2")])
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags. We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*ashrdi3_cmp_rex64"
12249 [(set (reg FLAGS_REG)
12251 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12254 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12255 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12257 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12258 && ix86_match_ccmode (insn, CCGOCmode)
12259 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12260 "sar{q}\t{%2, %0|%0, %2}"
12261 [(set_attr "type" "ishift")
12262 (set_attr "mode" "DI")])
12264 (define_insn "*ashrdi3_cconly_rex64"
12265 [(set (reg FLAGS_REG)
12267 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12268 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12270 (clobber (match_scratch:DI 0 "=r"))]
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_1"
12280 [(set (match_operand:DI 0 "register_operand" "=r")
12281 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12282 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12283 (clobber (reg:CC FLAGS_REG))]
12286 [(set_attr "type" "multi")])
12288 ;; By default we don't ask for a scratch register, because when DImode
12289 ;; values are manipulated, registers are already at a premium. But if
12290 ;; we have one handy, we won't turn it away.
12292 [(match_scratch:SI 3 "r")
12293 (parallel [(set (match_operand:DI 0 "register_operand" "")
12294 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12295 (match_operand:QI 2 "nonmemory_operand" "")))
12296 (clobber (reg:CC FLAGS_REG))])
12298 "!TARGET_64BIT && TARGET_CMOVE"
12300 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12303 [(set (match_operand:DI 0 "register_operand" "")
12304 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12305 (match_operand:QI 2 "nonmemory_operand" "")))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12308 ? epilogue_completed : reload_completed)"
12310 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12312 (define_insn "x86_shrd"
12313 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12314 (ior:SI (ashiftrt:SI (match_dup 0)
12315 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12316 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12317 (minus:QI (const_int 32) (match_dup 2)))))
12318 (clobber (reg:CC FLAGS_REG))]
12320 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12321 [(set_attr "type" "ishift")
12322 (set_attr "prefix_0f" "1")
12323 (set_attr "pent_pair" "np")
12324 (set_attr "mode" "SI")])
12326 (define_expand "x86_shift_adj_3"
12327 [(use (match_operand:SI 0 "register_operand" ""))
12328 (use (match_operand:SI 1 "register_operand" ""))
12329 (use (match_operand:QI 2 "register_operand" ""))]
12332 rtx label = gen_label_rtx ();
12335 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12337 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12338 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12339 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12340 gen_rtx_LABEL_REF (VOIDmode, label),
12342 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12343 JUMP_LABEL (tmp) = label;
12345 emit_move_insn (operands[0], operands[1]);
12346 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12348 emit_label (label);
12349 LABEL_NUSES (label) = 1;
12354 (define_expand "ashrsi3_31"
12355 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12356 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12357 (match_operand:SI 2 "const_int_operand" "i,i")))
12358 (clobber (reg:CC FLAGS_REG))])]
12361 (define_insn "*ashrsi3_31"
12362 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12363 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12364 (match_operand:SI 2 "const_int_operand" "i,i")))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "INTVAL (operands[2]) == 31
12367 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12368 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12371 sar{l}\t{%2, %0|%0, %2}"
12372 [(set_attr "type" "imovx,ishift")
12373 (set_attr "prefix_0f" "0,*")
12374 (set_attr "length_immediate" "0,*")
12375 (set_attr "modrm" "0,1")
12376 (set_attr "mode" "SI")])
12378 (define_insn "*ashrsi3_31_zext"
12379 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12380 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12381 (match_operand:SI 2 "const_int_operand" "i,i"))))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12384 && INTVAL (operands[2]) == 31
12385 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12388 sar{l}\t{%2, %k0|%k0, %2}"
12389 [(set_attr "type" "imovx,ishift")
12390 (set_attr "prefix_0f" "0,*")
12391 (set_attr "length_immediate" "0,*")
12392 (set_attr "modrm" "0,1")
12393 (set_attr "mode" "SI")])
12395 (define_expand "ashrsi3"
12396 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12397 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))]
12400 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12402 (define_insn "*ashrsi3_1_one_bit"
12403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12404 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" "")))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12410 [(set_attr "type" "ishift")
12411 (set (attr "length")
12412 (if_then_else (match_operand:SI 0 "register_operand" "")
12414 (const_string "*")))])
12416 (define_insn "*ashrsi3_1_one_bit_zext"
12417 [(set (match_operand:DI 0 "register_operand" "=r")
12418 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12419 (match_operand:QI 2 "const1_operand" ""))))
12420 (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" "2")])
12428 (define_insn "*ashrsi3_1"
12429 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12430 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12431 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12435 sar{l}\t{%2, %0|%0, %2}
12436 sar{l}\t{%b2, %0|%0, %b2}"
12437 [(set_attr "type" "ishift")
12438 (set_attr "mode" "SI")])
12440 (define_insn "*ashrsi3_1_zext"
12441 [(set (match_operand:DI 0 "register_operand" "=r,r")
12442 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12443 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12444 (clobber (reg:CC FLAGS_REG))]
12445 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12447 sar{l}\t{%2, %k0|%k0, %2}
12448 sar{l}\t{%b2, %k0|%k0, %b2}"
12449 [(set_attr "type" "ishift")
12450 (set_attr "mode" "SI")])
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags. We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrsi3_one_bit_cmp"
12456 [(set (reg FLAGS_REG)
12458 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const1_operand" ""))
12461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12463 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12464 && ix86_match_ccmode (insn, CCGOCmode)
12465 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12467 [(set_attr "type" "ishift")
12468 (set (attr "length")
12469 (if_then_else (match_operand:SI 0 "register_operand" "")
12471 (const_string "*")))])
12473 (define_insn "*ashrsi3_one_bit_cconly"
12474 [(set (reg FLAGS_REG)
12476 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12477 (match_operand:QI 2 "const1_operand" ""))
12479 (clobber (match_scratch:SI 0 "=r"))]
12480 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12481 && ix86_match_ccmode (insn, CCGOCmode)
12482 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12484 [(set_attr "type" "ishift")
12485 (set_attr "length" "2")])
12487 (define_insn "*ashrsi3_one_bit_cmp_zext"
12488 [(set (reg FLAGS_REG)
12490 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12491 (match_operand:QI 2 "const1_operand" ""))
12493 (set (match_operand:DI 0 "register_operand" "=r")
12494 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12496 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497 && ix86_match_ccmode (insn, CCmode)
12498 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12500 [(set_attr "type" "ishift")
12501 (set_attr "length" "2")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrsi3_cmp"
12507 [(set (reg FLAGS_REG)
12509 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515 && ix86_match_ccmode (insn, CCGOCmode)
12516 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517 "sar{l}\t{%2, %0|%0, %2}"
12518 [(set_attr "type" "ishift")
12519 (set_attr "mode" "SI")])
12521 (define_insn "*ashrsi3_cconly"
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 (clobber (match_scratch:SI 0 "=r"))]
12528 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12529 && ix86_match_ccmode (insn, CCGOCmode)
12530 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12531 "sar{l}\t{%2, %0|%0, %2}"
12532 [(set_attr "type" "ishift")
12533 (set_attr "mode" "SI")])
12535 (define_insn "*ashrsi3_cmp_zext"
12536 [(set (reg FLAGS_REG)
12538 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12539 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12541 (set (match_operand:DI 0 "register_operand" "=r")
12542 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12544 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12545 && ix86_match_ccmode (insn, CCGOCmode)
12546 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12547 "sar{l}\t{%2, %k0|%k0, %2}"
12548 [(set_attr "type" "ishift")
12549 (set_attr "mode" "SI")])
12551 (define_expand "ashrhi3"
12552 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12553 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12554 (match_operand:QI 2 "nonmemory_operand" "")))]
12555 "TARGET_HIMODE_MATH"
12556 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12558 (define_insn "*ashrhi3_1_one_bit"
12559 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12560 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12561 (match_operand:QI 2 "const1_operand" "")))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12564 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12566 [(set_attr "type" "ishift")
12567 (set (attr "length")
12568 (if_then_else (match_operand 0 "register_operand" "")
12570 (const_string "*")))])
12572 (define_insn "*ashrhi3_1"
12573 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12574 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12575 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12576 (clobber (reg:CC FLAGS_REG))]
12577 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12579 sar{w}\t{%2, %0|%0, %2}
12580 sar{w}\t{%b2, %0|%0, %b2}"
12581 [(set_attr "type" "ishift")
12582 (set_attr "mode" "HI")])
12584 ;; This pattern can't accept a variable shift count, since shifts by
12585 ;; zero don't affect the flags. We assume that shifts by constant
12586 ;; zero are optimized away.
12587 (define_insn "*ashrhi3_one_bit_cmp"
12588 [(set (reg FLAGS_REG)
12590 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591 (match_operand:QI 2 "const1_operand" ""))
12593 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12594 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12595 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12596 && ix86_match_ccmode (insn, CCGOCmode)
12597 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12599 [(set_attr "type" "ishift")
12600 (set (attr "length")
12601 (if_then_else (match_operand 0 "register_operand" "")
12603 (const_string "*")))])
12605 (define_insn "*ashrhi3_one_bit_cconly"
12606 [(set (reg FLAGS_REG)
12608 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609 (match_operand:QI 2 "const1_operand" ""))
12611 (clobber (match_scratch:HI 0 "=r"))]
12612 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12613 && ix86_match_ccmode (insn, CCGOCmode)
12614 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12616 [(set_attr "type" "ishift")
12617 (set_attr "length" "2")])
12619 ;; This pattern can't accept a variable shift count, since shifts by
12620 ;; zero don't affect the flags. We assume that shifts by constant
12621 ;; zero are optimized away.
12622 (define_insn "*ashrhi3_cmp"
12623 [(set (reg FLAGS_REG)
12625 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12626 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12628 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12630 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12631 && ix86_match_ccmode (insn, CCGOCmode)
12632 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12633 "sar{w}\t{%2, %0|%0, %2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12637 (define_insn "*ashrhi3_cconly"
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 (clobber (match_scratch:HI 0 "=r"))]
12644 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12645 && ix86_match_ccmode (insn, CCGOCmode)
12646 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12647 "sar{w}\t{%2, %0|%0, %2}"
12648 [(set_attr "type" "ishift")
12649 (set_attr "mode" "HI")])
12651 (define_expand "ashrqi3"
12652 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12653 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12654 (match_operand:QI 2 "nonmemory_operand" "")))]
12655 "TARGET_QIMODE_MATH"
12656 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12658 (define_insn "*ashrqi3_1_one_bit"
12659 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12661 (match_operand:QI 2 "const1_operand" "")))
12662 (clobber (reg:CC FLAGS_REG))]
12663 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12664 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12666 [(set_attr "type" "ishift")
12667 (set (attr "length")
12668 (if_then_else (match_operand 0 "register_operand" "")
12670 (const_string "*")))])
12672 (define_insn "*ashrqi3_1_one_bit_slp"
12673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12674 (ashiftrt:QI (match_dup 0)
12675 (match_operand:QI 1 "const1_operand" "")))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12681 [(set_attr "type" "ishift1")
12682 (set (attr "length")
12683 (if_then_else (match_operand 0 "register_operand" "")
12685 (const_string "*")))])
12687 (define_insn "*ashrqi3_1"
12688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12689 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12690 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12694 sar{b}\t{%2, %0|%0, %2}
12695 sar{b}\t{%b2, %0|%0, %b2}"
12696 [(set_attr "type" "ishift")
12697 (set_attr "mode" "QI")])
12699 (define_insn "*ashrqi3_1_slp"
12700 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12701 (ashiftrt:QI (match_dup 0)
12702 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12705 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12707 sar{b}\t{%1, %0|%0, %1}
12708 sar{b}\t{%b1, %0|%0, %b1}"
12709 [(set_attr "type" "ishift1")
12710 (set_attr "mode" "QI")])
12712 ;; This pattern can't accept a variable shift count, since shifts by
12713 ;; zero don't affect the flags. We assume that shifts by constant
12714 ;; zero are optimized away.
12715 (define_insn "*ashrqi3_one_bit_cmp"
12716 [(set (reg FLAGS_REG)
12718 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12719 (match_operand:QI 2 "const1_operand" "I"))
12721 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12722 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12723 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12724 && ix86_match_ccmode (insn, CCGOCmode)
12725 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12727 [(set_attr "type" "ishift")
12728 (set (attr "length")
12729 (if_then_else (match_operand 0 "register_operand" "")
12731 (const_string "*")))])
12733 (define_insn "*ashrqi3_one_bit_cconly"
12734 [(set (reg FLAGS_REG)
12736 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12737 (match_operand:QI 2 "const1_operand" ""))
12739 (clobber (match_scratch:QI 0 "=q"))]
12740 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12741 && ix86_match_ccmode (insn, CCGOCmode)
12742 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12744 [(set_attr "type" "ishift")
12745 (set_attr "length" "2")])
12747 ;; This pattern can't accept a variable shift count, since shifts by
12748 ;; zero don't affect the flags. We assume that shifts by constant
12749 ;; zero are optimized away.
12750 (define_insn "*ashrqi3_cmp"
12751 [(set (reg FLAGS_REG)
12753 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12754 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12756 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12758 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12759 && ix86_match_ccmode (insn, CCGOCmode)
12760 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12761 "sar{b}\t{%2, %0|%0, %2}"
12762 [(set_attr "type" "ishift")
12763 (set_attr "mode" "QI")])
12765 (define_insn "*ashrqi3_cconly"
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 (clobber (match_scratch:QI 0 "=q"))]
12772 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12773 && ix86_match_ccmode (insn, CCGOCmode)
12774 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12775 "sar{b}\t{%2, %0|%0, %2}"
12776 [(set_attr "type" "ishift")
12777 (set_attr "mode" "QI")])
12780 ;; Logical shift instructions
12782 ;; See comment above `ashldi3' about how this works.
12784 (define_expand "lshrti3"
12785 [(set (match_operand:TI 0 "register_operand" "")
12786 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12787 (match_operand:QI 2 "nonmemory_operand" "")))]
12789 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12791 ;; This pattern must be defined before *lshrti3_1 to prevent
12792 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12794 (define_insn "*avx_lshrti3"
12795 [(set (match_operand:TI 0 "register_operand" "=x")
12796 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12797 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12800 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12801 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12803 [(set_attr "type" "sseishft")
12804 (set_attr "prefix" "vex")
12805 (set_attr "mode" "TI")])
12807 (define_insn "sse2_lshrti3"
12808 [(set (match_operand:TI 0 "register_operand" "=x")
12809 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12810 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12813 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12814 return "psrldq\t{%2, %0|%0, %2}";
12816 [(set_attr "type" "sseishft")
12817 (set_attr "prefix_data16" "1")
12818 (set_attr "mode" "TI")])
12820 (define_insn "*lshrti3_1"
12821 [(set (match_operand:TI 0 "register_operand" "=r")
12822 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12823 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12824 (clobber (reg:CC FLAGS_REG))]
12827 [(set_attr "type" "multi")])
12830 [(match_scratch:DI 3 "r")
12831 (parallel [(set (match_operand:TI 0 "register_operand" "")
12832 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833 (match_operand:QI 2 "nonmemory_operand" "")))
12834 (clobber (reg:CC FLAGS_REG))])
12838 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12841 [(set (match_operand:TI 0 "register_operand" "")
12842 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12843 (match_operand:QI 2 "nonmemory_operand" "")))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12846 ? epilogue_completed : reload_completed)"
12848 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12850 (define_expand "lshrdi3"
12851 [(set (match_operand:DI 0 "shiftdi_operand" "")
12852 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12853 (match_operand:QI 2 "nonmemory_operand" "")))]
12855 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12857 (define_insn "*lshrdi3_1_one_bit_rex64"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12866 [(set_attr "type" "ishift")
12867 (set (attr "length")
12868 (if_then_else (match_operand:DI 0 "register_operand" "")
12870 (const_string "*")))])
12872 (define_insn "*lshrdi3_1_rex64"
12873 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12874 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12875 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12876 (clobber (reg:CC FLAGS_REG))]
12877 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12879 shr{q}\t{%2, %0|%0, %2}
12880 shr{q}\t{%b2, %0|%0, %b2}"
12881 [(set_attr "type" "ishift")
12882 (set_attr "mode" "DI")])
12884 ;; This pattern can't accept a variable shift count, since shifts by
12885 ;; zero don't affect the flags. We assume that shifts by constant
12886 ;; zero are optimized away.
12887 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12888 [(set (reg FLAGS_REG)
12890 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12891 (match_operand:QI 2 "const1_operand" ""))
12893 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12894 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12896 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897 && ix86_match_ccmode (insn, CCGOCmode)
12898 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12900 [(set_attr "type" "ishift")
12901 (set (attr "length")
12902 (if_then_else (match_operand:DI 0 "register_operand" "")
12904 (const_string "*")))])
12906 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12907 [(set (reg FLAGS_REG)
12909 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910 (match_operand:QI 2 "const1_operand" ""))
12912 (clobber (match_scratch:DI 0 "=r"))]
12914 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12915 && ix86_match_ccmode (insn, CCGOCmode)
12916 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12918 [(set_attr "type" "ishift")
12919 (set_attr "length" "2")])
12921 ;; This pattern can't accept a variable shift count, since shifts by
12922 ;; zero don't affect the flags. We assume that shifts by constant
12923 ;; zero are optimized away.
12924 (define_insn "*lshrdi3_cmp_rex64"
12925 [(set (reg FLAGS_REG)
12927 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12928 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12930 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12931 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12933 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12934 && ix86_match_ccmode (insn, CCGOCmode)
12935 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936 "shr{q}\t{%2, %0|%0, %2}"
12937 [(set_attr "type" "ishift")
12938 (set_attr "mode" "DI")])
12940 (define_insn "*lshrdi3_cconly_rex64"
12941 [(set (reg FLAGS_REG)
12943 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12944 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12946 (clobber (match_scratch:DI 0 "=r"))]
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_1"
12956 [(set (match_operand:DI 0 "register_operand" "=r")
12957 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12958 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12959 (clobber (reg:CC FLAGS_REG))]
12962 [(set_attr "type" "multi")])
12964 ;; By default we don't ask for a scratch register, because when DImode
12965 ;; values are manipulated, registers are already at a premium. But if
12966 ;; we have one handy, we won't turn it away.
12968 [(match_scratch:SI 3 "r")
12969 (parallel [(set (match_operand:DI 0 "register_operand" "")
12970 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12971 (match_operand:QI 2 "nonmemory_operand" "")))
12972 (clobber (reg:CC FLAGS_REG))])
12974 "!TARGET_64BIT && TARGET_CMOVE"
12976 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12979 [(set (match_operand:DI 0 "register_operand" "")
12980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12981 (match_operand:QI 2 "nonmemory_operand" "")))
12982 (clobber (reg:CC FLAGS_REG))]
12983 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12984 ? epilogue_completed : reload_completed)"
12986 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12988 (define_expand "lshrsi3"
12989 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12990 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12991 (match_operand:QI 2 "nonmemory_operand" "")))]
12993 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12995 (define_insn "*lshrsi3_1_one_bit"
12996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const1_operand" "")))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13001 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13003 [(set_attr "type" "ishift")
13004 (set (attr "length")
13005 (if_then_else (match_operand:SI 0 "register_operand" "")
13007 (const_string "*")))])
13009 (define_insn "*lshrsi3_1_one_bit_zext"
13010 [(set (match_operand:DI 0 "register_operand" "=r")
13011 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13012 (match_operand:QI 2 "const1_operand" "")))
13013 (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" "2")])
13021 (define_insn "*lshrsi3_1"
13022 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13023 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13024 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13025 (clobber (reg:CC FLAGS_REG))]
13026 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13028 shr{l}\t{%2, %0|%0, %2}
13029 shr{l}\t{%b2, %0|%0, %b2}"
13030 [(set_attr "type" "ishift")
13031 (set_attr "mode" "SI")])
13033 (define_insn "*lshrsi3_1_zext"
13034 [(set (match_operand:DI 0 "register_operand" "=r,r")
13036 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13037 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13038 (clobber (reg:CC FLAGS_REG))]
13039 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13041 shr{l}\t{%2, %k0|%k0, %2}
13042 shr{l}\t{%b2, %k0|%k0, %b2}"
13043 [(set_attr "type" "ishift")
13044 (set_attr "mode" "SI")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags. We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrsi3_one_bit_cmp"
13050 [(set (reg FLAGS_REG)
13052 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const1_operand" ""))
13055 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13056 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13057 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13061 [(set_attr "type" "ishift")
13062 (set (attr "length")
13063 (if_then_else (match_operand:SI 0 "register_operand" "")
13065 (const_string "*")))])
13067 (define_insn "*lshrsi3_one_bit_cconly"
13068 [(set (reg FLAGS_REG)
13070 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13071 (match_operand:QI 2 "const1_operand" ""))
13073 (clobber (match_scratch:SI 0 "=r"))]
13074 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13075 && ix86_match_ccmode (insn, CCGOCmode)
13076 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13078 [(set_attr "type" "ishift")
13079 (set_attr "length" "2")])
13081 (define_insn "*lshrsi3_cmp_one_bit_zext"
13082 [(set (reg FLAGS_REG)
13084 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const1_operand" ""))
13087 (set (match_operand:DI 0 "register_operand" "=r")
13088 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091 && ix86_match_ccmode (insn, CCGOCmode)
13092 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13094 [(set_attr "type" "ishift")
13095 (set_attr "length" "2")])
13097 ;; This pattern can't accept a variable shift count, since shifts by
13098 ;; zero don't affect the flags. We assume that shifts by constant
13099 ;; zero are optimized away.
13100 (define_insn "*lshrsi3_cmp"
13101 [(set (reg FLAGS_REG)
13103 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13106 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13107 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13108 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13109 && ix86_match_ccmode (insn, CCGOCmode)
13110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111 "shr{l}\t{%2, %0|%0, %2}"
13112 [(set_attr "type" "ishift")
13113 (set_attr "mode" "SI")])
13115 (define_insn "*lshrsi3_cconly"
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 (clobber (match_scratch:SI 0 "=r"))]
13122 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13123 && ix86_match_ccmode (insn, CCGOCmode)
13124 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13125 "shr{l}\t{%2, %0|%0, %2}"
13126 [(set_attr "type" "ishift")
13127 (set_attr "mode" "SI")])
13129 (define_insn "*lshrsi3_cmp_zext"
13130 [(set (reg FLAGS_REG)
13132 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13133 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13135 (set (match_operand:DI 0 "register_operand" "=r")
13136 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13138 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13139 && ix86_match_ccmode (insn, CCGOCmode)
13140 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13141 "shr{l}\t{%2, %k0|%k0, %2}"
13142 [(set_attr "type" "ishift")
13143 (set_attr "mode" "SI")])
13145 (define_expand "lshrhi3"
13146 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13147 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13148 (match_operand:QI 2 "nonmemory_operand" "")))]
13149 "TARGET_HIMODE_MATH"
13150 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13152 (define_insn "*lshrhi3_1_one_bit"
13153 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13154 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13155 (match_operand:QI 2 "const1_operand" "")))
13156 (clobber (reg:CC FLAGS_REG))]
13157 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13158 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13160 [(set_attr "type" "ishift")
13161 (set (attr "length")
13162 (if_then_else (match_operand 0 "register_operand" "")
13164 (const_string "*")))])
13166 (define_insn "*lshrhi3_1"
13167 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13168 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13169 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13170 (clobber (reg:CC FLAGS_REG))]
13171 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13173 shr{w}\t{%2, %0|%0, %2}
13174 shr{w}\t{%b2, %0|%0, %b2}"
13175 [(set_attr "type" "ishift")
13176 (set_attr "mode" "HI")])
13178 ;; This pattern can't accept a variable shift count, since shifts by
13179 ;; zero don't affect the flags. We assume that shifts by constant
13180 ;; zero are optimized away.
13181 (define_insn "*lshrhi3_one_bit_cmp"
13182 [(set (reg FLAGS_REG)
13184 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13185 (match_operand:QI 2 "const1_operand" ""))
13187 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13188 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13189 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13190 && ix86_match_ccmode (insn, CCGOCmode)
13191 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13193 [(set_attr "type" "ishift")
13194 (set (attr "length")
13195 (if_then_else (match_operand:SI 0 "register_operand" "")
13197 (const_string "*")))])
13199 (define_insn "*lshrhi3_one_bit_cconly"
13200 [(set (reg FLAGS_REG)
13202 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13203 (match_operand:QI 2 "const1_operand" ""))
13205 (clobber (match_scratch:HI 0 "=r"))]
13206 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13207 && ix86_match_ccmode (insn, CCGOCmode)
13208 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13210 [(set_attr "type" "ishift")
13211 (set_attr "length" "2")])
13213 ;; This pattern can't accept a variable shift count, since shifts by
13214 ;; zero don't affect the flags. We assume that shifts by constant
13215 ;; zero are optimized away.
13216 (define_insn "*lshrhi3_cmp"
13217 [(set (reg FLAGS_REG)
13219 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13220 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13222 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13223 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13224 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13225 && ix86_match_ccmode (insn, CCGOCmode)
13226 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13227 "shr{w}\t{%2, %0|%0, %2}"
13228 [(set_attr "type" "ishift")
13229 (set_attr "mode" "HI")])
13231 (define_insn "*lshrhi3_cconly"
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 (clobber (match_scratch:HI 0 "=r"))]
13238 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13239 && ix86_match_ccmode (insn, CCGOCmode)
13240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13241 "shr{w}\t{%2, %0|%0, %2}"
13242 [(set_attr "type" "ishift")
13243 (set_attr "mode" "HI")])
13245 (define_expand "lshrqi3"
13246 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13247 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13248 (match_operand:QI 2 "nonmemory_operand" "")))]
13249 "TARGET_QIMODE_MATH"
13250 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13252 (define_insn "*lshrqi3_1_one_bit"
13253 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13254 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13255 (match_operand:QI 2 "const1_operand" "")))
13256 (clobber (reg:CC FLAGS_REG))]
13257 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13258 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13260 [(set_attr "type" "ishift")
13261 (set (attr "length")
13262 (if_then_else (match_operand 0 "register_operand" "")
13264 (const_string "*")))])
13266 (define_insn "*lshrqi3_1_one_bit_slp"
13267 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13268 (lshiftrt:QI (match_dup 0)
13269 (match_operand:QI 1 "const1_operand" "")))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13272 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13274 [(set_attr "type" "ishift1")
13275 (set (attr "length")
13276 (if_then_else (match_operand 0 "register_operand" "")
13278 (const_string "*")))])
13280 (define_insn "*lshrqi3_1"
13281 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13282 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13283 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13284 (clobber (reg:CC FLAGS_REG))]
13285 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13287 shr{b}\t{%2, %0|%0, %2}
13288 shr{b}\t{%b2, %0|%0, %b2}"
13289 [(set_attr "type" "ishift")
13290 (set_attr "mode" "QI")])
13292 (define_insn "*lshrqi3_1_slp"
13293 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13294 (lshiftrt:QI (match_dup 0)
13295 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13296 (clobber (reg:CC FLAGS_REG))]
13297 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13298 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13300 shr{b}\t{%1, %0|%0, %1}
13301 shr{b}\t{%b1, %0|%0, %b1}"
13302 [(set_attr "type" "ishift1")
13303 (set_attr "mode" "QI")])
13305 ;; This pattern can't accept a variable shift count, since shifts by
13306 ;; zero don't affect the flags. We assume that shifts by constant
13307 ;; zero are optimized away.
13308 (define_insn "*lshrqi2_one_bit_cmp"
13309 [(set (reg FLAGS_REG)
13311 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13312 (match_operand:QI 2 "const1_operand" ""))
13314 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13316 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13317 && ix86_match_ccmode (insn, CCGOCmode)
13318 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13320 [(set_attr "type" "ishift")
13321 (set (attr "length")
13322 (if_then_else (match_operand:SI 0 "register_operand" "")
13324 (const_string "*")))])
13326 (define_insn "*lshrqi2_one_bit_cconly"
13327 [(set (reg FLAGS_REG)
13329 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330 (match_operand:QI 2 "const1_operand" ""))
13332 (clobber (match_scratch:QI 0 "=q"))]
13333 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13334 && ix86_match_ccmode (insn, CCGOCmode)
13335 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13337 [(set_attr "type" "ishift")
13338 (set_attr "length" "2")])
13340 ;; This pattern can't accept a variable shift count, since shifts by
13341 ;; zero don't affect the flags. We assume that shifts by constant
13342 ;; zero are optimized away.
13343 (define_insn "*lshrqi2_cmp"
13344 [(set (reg FLAGS_REG)
13346 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13347 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13349 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13350 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13351 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13352 && ix86_match_ccmode (insn, CCGOCmode)
13353 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13354 "shr{b}\t{%2, %0|%0, %2}"
13355 [(set_attr "type" "ishift")
13356 (set_attr "mode" "QI")])
13358 (define_insn "*lshrqi2_cconly"
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 (clobber (match_scratch:QI 0 "=q"))]
13365 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13366 && ix86_match_ccmode (insn, CCGOCmode)
13367 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13368 "shr{b}\t{%2, %0|%0, %2}"
13369 [(set_attr "type" "ishift")
13370 (set_attr "mode" "QI")])
13372 ;; Rotate instructions
13374 (define_expand "rotldi3"
13375 [(set (match_operand:DI 0 "shiftdi_operand" "")
13376 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13377 (match_operand:QI 2 "nonmemory_operand" "")))]
13382 ix86_expand_binary_operator (ROTATE, DImode, operands);
13385 if (!const_1_to_31_operand (operands[2], VOIDmode))
13387 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13391 ;; Implement rotation using two double-precision shift instructions
13392 ;; and a scratch register.
13393 (define_insn_and_split "ix86_rotldi3"
13394 [(set (match_operand:DI 0 "register_operand" "=r")
13395 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13396 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13397 (clobber (reg:CC FLAGS_REG))
13398 (clobber (match_scratch:SI 3 "=&r"))]
13401 "&& reload_completed"
13402 [(set (match_dup 3) (match_dup 4))
13404 [(set (match_dup 4)
13405 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13406 (lshiftrt:SI (match_dup 5)
13407 (minus:QI (const_int 32) (match_dup 2)))))
13408 (clobber (reg:CC FLAGS_REG))])
13410 [(set (match_dup 5)
13411 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13412 (lshiftrt:SI (match_dup 3)
13413 (minus:QI (const_int 32) (match_dup 2)))))
13414 (clobber (reg:CC FLAGS_REG))])]
13415 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13417 (define_insn "*rotlsi3_1_one_bit_rex64"
13418 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13419 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13420 (match_operand:QI 2 "const1_operand" "")))
13421 (clobber (reg:CC FLAGS_REG))]
13423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13424 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13426 [(set_attr "type" "rotate")
13427 (set (attr "length")
13428 (if_then_else (match_operand:DI 0 "register_operand" "")
13430 (const_string "*")))])
13432 (define_insn "*rotldi3_1_rex64"
13433 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13434 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13435 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13436 (clobber (reg:CC FLAGS_REG))]
13437 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13439 rol{q}\t{%2, %0|%0, %2}
13440 rol{q}\t{%b2, %0|%0, %b2}"
13441 [(set_attr "type" "rotate")
13442 (set_attr "mode" "DI")])
13444 (define_expand "rotlsi3"
13445 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13446 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13447 (match_operand:QI 2 "nonmemory_operand" "")))]
13449 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13451 (define_insn "*rotlsi3_1_one_bit"
13452 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13453 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13454 (match_operand:QI 2 "const1_operand" "")))
13455 (clobber (reg:CC FLAGS_REG))]
13456 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13459 [(set_attr "type" "rotate")
13460 (set (attr "length")
13461 (if_then_else (match_operand:SI 0 "register_operand" "")
13463 (const_string "*")))])
13465 (define_insn "*rotlsi3_1_one_bit_zext"
13466 [(set (match_operand:DI 0 "register_operand" "=r")
13468 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13469 (match_operand:QI 2 "const1_operand" ""))))
13470 (clobber (reg:CC FLAGS_REG))]
13472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13473 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13475 [(set_attr "type" "rotate")
13476 (set_attr "length" "2")])
13478 (define_insn "*rotlsi3_1"
13479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13480 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13485 rol{l}\t{%2, %0|%0, %2}
13486 rol{l}\t{%b2, %0|%0, %b2}"
13487 [(set_attr "type" "rotate")
13488 (set_attr "mode" "SI")])
13490 (define_insn "*rotlsi3_1_zext"
13491 [(set (match_operand:DI 0 "register_operand" "=r,r")
13493 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13498 rol{l}\t{%2, %k0|%k0, %2}
13499 rol{l}\t{%b2, %k0|%k0, %b2}"
13500 [(set_attr "type" "rotate")
13501 (set_attr "mode" "SI")])
13503 (define_expand "rotlhi3"
13504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13505 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13506 (match_operand:QI 2 "nonmemory_operand" "")))]
13507 "TARGET_HIMODE_MATH"
13508 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13510 (define_insn "*rotlhi3_1_one_bit"
13511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13512 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13513 (match_operand:QI 2 "const1_operand" "")))
13514 (clobber (reg:CC FLAGS_REG))]
13515 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13516 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13518 [(set_attr "type" "rotate")
13519 (set (attr "length")
13520 (if_then_else (match_operand 0 "register_operand" "")
13522 (const_string "*")))])
13524 (define_insn "*rotlhi3_1"
13525 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13526 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13527 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528 (clobber (reg:CC FLAGS_REG))]
13529 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13531 rol{w}\t{%2, %0|%0, %2}
13532 rol{w}\t{%b2, %0|%0, %b2}"
13533 [(set_attr "type" "rotate")
13534 (set_attr "mode" "HI")])
13537 [(set (match_operand:HI 0 "register_operand" "")
13538 (rotate:HI (match_dup 0) (const_int 8)))
13539 (clobber (reg:CC FLAGS_REG))]
13541 [(parallel [(set (strict_low_part (match_dup 0))
13542 (bswap:HI (match_dup 0)))
13543 (clobber (reg:CC FLAGS_REG))])]
13546 (define_expand "rotlqi3"
13547 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13548 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13549 (match_operand:QI 2 "nonmemory_operand" "")))]
13550 "TARGET_QIMODE_MATH"
13551 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13553 (define_insn "*rotlqi3_1_one_bit_slp"
13554 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13555 (rotate:QI (match_dup 0)
13556 (match_operand:QI 1 "const1_operand" "")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13561 [(set_attr "type" "rotate1")
13562 (set (attr "length")
13563 (if_then_else (match_operand 0 "register_operand" "")
13565 (const_string "*")))])
13567 (define_insn "*rotlqi3_1_one_bit"
13568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13569 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13570 (match_operand:QI 2 "const1_operand" "")))
13571 (clobber (reg:CC FLAGS_REG))]
13572 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13573 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13575 [(set_attr "type" "rotate")
13576 (set (attr "length")
13577 (if_then_else (match_operand 0 "register_operand" "")
13579 (const_string "*")))])
13581 (define_insn "*rotlqi3_1_slp"
13582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13583 (rotate:QI (match_dup 0)
13584 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13585 (clobber (reg:CC FLAGS_REG))]
13586 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13587 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13589 rol{b}\t{%1, %0|%0, %1}
13590 rol{b}\t{%b1, %0|%0, %b1}"
13591 [(set_attr "type" "rotate1")
13592 (set_attr "mode" "QI")])
13594 (define_insn "*rotlqi3_1"
13595 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13596 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13597 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13598 (clobber (reg:CC FLAGS_REG))]
13599 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13601 rol{b}\t{%2, %0|%0, %2}
13602 rol{b}\t{%b2, %0|%0, %b2}"
13603 [(set_attr "type" "rotate")
13604 (set_attr "mode" "QI")])
13606 (define_expand "rotrdi3"
13607 [(set (match_operand:DI 0 "shiftdi_operand" "")
13608 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13609 (match_operand:QI 2 "nonmemory_operand" "")))]
13614 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13617 if (!const_1_to_31_operand (operands[2], VOIDmode))
13619 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13623 ;; Implement rotation using two double-precision shift instructions
13624 ;; and a scratch register.
13625 (define_insn_and_split "ix86_rotrdi3"
13626 [(set (match_operand:DI 0 "register_operand" "=r")
13627 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13628 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13629 (clobber (reg:CC FLAGS_REG))
13630 (clobber (match_scratch:SI 3 "=&r"))]
13633 "&& reload_completed"
13634 [(set (match_dup 3) (match_dup 4))
13636 [(set (match_dup 4)
13637 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13638 (ashift:SI (match_dup 5)
13639 (minus:QI (const_int 32) (match_dup 2)))))
13640 (clobber (reg:CC FLAGS_REG))])
13642 [(set (match_dup 5)
13643 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13644 (ashift:SI (match_dup 3)
13645 (minus:QI (const_int 32) (match_dup 2)))))
13646 (clobber (reg:CC FLAGS_REG))])]
13647 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13649 (define_insn "*rotrdi3_1_one_bit_rex64"
13650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13651 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13652 (match_operand:QI 2 "const1_operand" "")))
13653 (clobber (reg:CC FLAGS_REG))]
13655 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13656 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13658 [(set_attr "type" "rotate")
13659 (set (attr "length")
13660 (if_then_else (match_operand:DI 0 "register_operand" "")
13662 (const_string "*")))])
13664 (define_insn "*rotrdi3_1_rex64"
13665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13666 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13667 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13668 (clobber (reg:CC FLAGS_REG))]
13669 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13671 ror{q}\t{%2, %0|%0, %2}
13672 ror{q}\t{%b2, %0|%0, %b2}"
13673 [(set_attr "type" "rotate")
13674 (set_attr "mode" "DI")])
13676 (define_expand "rotrsi3"
13677 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13678 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13679 (match_operand:QI 2 "nonmemory_operand" "")))]
13681 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13683 (define_insn "*rotrsi3_1_one_bit"
13684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13685 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13686 (match_operand:QI 2 "const1_operand" "")))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13691 [(set_attr "type" "rotate")
13692 (set (attr "length")
13693 (if_then_else (match_operand:SI 0 "register_operand" "")
13695 (const_string "*")))])
13697 (define_insn "*rotrsi3_1_one_bit_zext"
13698 [(set (match_operand:DI 0 "register_operand" "=r")
13700 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13701 (match_operand:QI 2 "const1_operand" ""))))
13702 (clobber (reg:CC FLAGS_REG))]
13704 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13705 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13707 [(set_attr "type" "rotate")
13708 (set (attr "length")
13709 (if_then_else (match_operand:SI 0 "register_operand" "")
13711 (const_string "*")))])
13713 (define_insn "*rotrsi3_1"
13714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13715 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13716 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13717 (clobber (reg:CC FLAGS_REG))]
13718 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13720 ror{l}\t{%2, %0|%0, %2}
13721 ror{l}\t{%b2, %0|%0, %b2}"
13722 [(set_attr "type" "rotate")
13723 (set_attr "mode" "SI")])
13725 (define_insn "*rotrsi3_1_zext"
13726 [(set (match_operand:DI 0 "register_operand" "=r,r")
13728 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13729 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13730 (clobber (reg:CC FLAGS_REG))]
13731 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13733 ror{l}\t{%2, %k0|%k0, %2}
13734 ror{l}\t{%b2, %k0|%k0, %b2}"
13735 [(set_attr "type" "rotate")
13736 (set_attr "mode" "SI")])
13738 (define_expand "rotrhi3"
13739 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13740 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13741 (match_operand:QI 2 "nonmemory_operand" "")))]
13742 "TARGET_HIMODE_MATH"
13743 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13745 (define_insn "*rotrhi3_one_bit"
13746 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13747 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13748 (match_operand:QI 2 "const1_operand" "")))
13749 (clobber (reg:CC FLAGS_REG))]
13750 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13753 [(set_attr "type" "rotate")
13754 (set (attr "length")
13755 (if_then_else (match_operand 0 "register_operand" "")
13757 (const_string "*")))])
13759 (define_insn "*rotrhi3_1"
13760 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13761 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13762 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13766 ror{w}\t{%2, %0|%0, %2}
13767 ror{w}\t{%b2, %0|%0, %b2}"
13768 [(set_attr "type" "rotate")
13769 (set_attr "mode" "HI")])
13772 [(set (match_operand:HI 0 "register_operand" "")
13773 (rotatert:HI (match_dup 0) (const_int 8)))
13774 (clobber (reg:CC FLAGS_REG))]
13776 [(parallel [(set (strict_low_part (match_dup 0))
13777 (bswap:HI (match_dup 0)))
13778 (clobber (reg:CC FLAGS_REG))])]
13781 (define_expand "rotrqi3"
13782 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13783 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13784 (match_operand:QI 2 "nonmemory_operand" "")))]
13785 "TARGET_QIMODE_MATH"
13786 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13788 (define_insn "*rotrqi3_1_one_bit"
13789 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13790 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13791 (match_operand:QI 2 "const1_operand" "")))
13792 (clobber (reg:CC FLAGS_REG))]
13793 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13794 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13796 [(set_attr "type" "rotate")
13797 (set (attr "length")
13798 (if_then_else (match_operand 0 "register_operand" "")
13800 (const_string "*")))])
13802 (define_insn "*rotrqi3_1_one_bit_slp"
13803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13804 (rotatert:QI (match_dup 0)
13805 (match_operand:QI 1 "const1_operand" "")))
13806 (clobber (reg:CC FLAGS_REG))]
13807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13808 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13810 [(set_attr "type" "rotate1")
13811 (set (attr "length")
13812 (if_then_else (match_operand 0 "register_operand" "")
13814 (const_string "*")))])
13816 (define_insn "*rotrqi3_1"
13817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13818 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13819 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13820 (clobber (reg:CC FLAGS_REG))]
13821 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13823 ror{b}\t{%2, %0|%0, %2}
13824 ror{b}\t{%b2, %0|%0, %b2}"
13825 [(set_attr "type" "rotate")
13826 (set_attr "mode" "QI")])
13828 (define_insn "*rotrqi3_1_slp"
13829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13830 (rotatert:QI (match_dup 0)
13831 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13832 (clobber (reg:CC FLAGS_REG))]
13833 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13836 ror{b}\t{%1, %0|%0, %1}
13837 ror{b}\t{%b1, %0|%0, %b1}"
13838 [(set_attr "type" "rotate1")
13839 (set_attr "mode" "QI")])
13841 ;; Bit set / bit test instructions
13843 (define_expand "extv"
13844 [(set (match_operand:SI 0 "register_operand" "")
13845 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13846 (match_operand:SI 2 "const8_operand" "")
13847 (match_operand:SI 3 "const8_operand" "")))]
13850 /* Handle extractions from %ah et al. */
13851 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13854 /* From mips.md: extract_bit_field doesn't verify that our source
13855 matches the predicate, so check it again here. */
13856 if (! ext_register_operand (operands[1], VOIDmode))
13860 (define_expand "extzv"
13861 [(set (match_operand:SI 0 "register_operand" "")
13862 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13863 (match_operand:SI 2 "const8_operand" "")
13864 (match_operand:SI 3 "const8_operand" "")))]
13867 /* Handle extractions from %ah et al. */
13868 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13871 /* From mips.md: extract_bit_field doesn't verify that our source
13872 matches the predicate, so check it again here. */
13873 if (! ext_register_operand (operands[1], VOIDmode))
13877 (define_expand "insv"
13878 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13879 (match_operand 1 "const8_operand" "")
13880 (match_operand 2 "const8_operand" ""))
13881 (match_operand 3 "register_operand" ""))]
13884 /* Handle insertions to %ah et al. */
13885 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13888 /* From mips.md: insert_bit_field doesn't verify that our source
13889 matches the predicate, so check it again here. */
13890 if (! ext_register_operand (operands[0], VOIDmode))
13894 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13896 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13901 ;; %%% bts, btr, btc, bt.
13902 ;; In general these instructions are *slow* when applied to memory,
13903 ;; since they enforce atomic operation. When applied to registers,
13904 ;; it depends on the cpu implementation. They're never faster than
13905 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13906 ;; no point. But in 64-bit, we can't hold the relevant immediates
13907 ;; within the instruction itself, so operating on bits in the high
13908 ;; 32-bits of a register becomes easier.
13910 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13911 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13912 ;; negdf respectively, so they can never be disabled entirely.
13914 (define_insn "*btsq"
13915 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13917 (match_operand:DI 1 "const_0_to_63_operand" ""))
13919 (clobber (reg:CC FLAGS_REG))]
13920 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13921 "bts{q}\t{%1, %0|%0, %1}"
13922 [(set_attr "type" "alu1")])
13924 (define_insn "*btrq"
13925 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13927 (match_operand:DI 1 "const_0_to_63_operand" ""))
13929 (clobber (reg:CC FLAGS_REG))]
13930 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13931 "btr{q}\t{%1, %0|%0, %1}"
13932 [(set_attr "type" "alu1")])
13934 (define_insn "*btcq"
13935 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13937 (match_operand:DI 1 "const_0_to_63_operand" ""))
13938 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13939 (clobber (reg:CC FLAGS_REG))]
13940 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13941 "btc{q}\t{%1, %0|%0, %1}"
13942 [(set_attr "type" "alu1")])
13944 ;; Allow Nocona to avoid these instructions if a register is available.
13947 [(match_scratch:DI 2 "r")
13948 (parallel [(set (zero_extract:DI
13949 (match_operand:DI 0 "register_operand" "")
13951 (match_operand:DI 1 "const_0_to_63_operand" ""))
13953 (clobber (reg:CC FLAGS_REG))])]
13954 "TARGET_64BIT && !TARGET_USE_BT"
13957 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13960 if (HOST_BITS_PER_WIDE_INT >= 64)
13961 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13962 else if (i < HOST_BITS_PER_WIDE_INT)
13963 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13965 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13967 op1 = immed_double_const (lo, hi, DImode);
13970 emit_move_insn (operands[2], op1);
13974 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13979 [(match_scratch:DI 2 "r")
13980 (parallel [(set (zero_extract:DI
13981 (match_operand:DI 0 "register_operand" "")
13983 (match_operand:DI 1 "const_0_to_63_operand" ""))
13985 (clobber (reg:CC FLAGS_REG))])]
13986 "TARGET_64BIT && !TARGET_USE_BT"
13989 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13992 if (HOST_BITS_PER_WIDE_INT >= 64)
13993 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13994 else if (i < HOST_BITS_PER_WIDE_INT)
13995 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13997 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13999 op1 = immed_double_const (~lo, ~hi, DImode);
14002 emit_move_insn (operands[2], op1);
14006 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14011 [(match_scratch:DI 2 "r")
14012 (parallel [(set (zero_extract:DI
14013 (match_operand:DI 0 "register_operand" "")
14015 (match_operand:DI 1 "const_0_to_63_operand" ""))
14016 (not:DI (zero_extract:DI
14017 (match_dup 0) (const_int 1) (match_dup 1))))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 "TARGET_64BIT && !TARGET_USE_BT"
14022 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14025 if (HOST_BITS_PER_WIDE_INT >= 64)
14026 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027 else if (i < HOST_BITS_PER_WIDE_INT)
14028 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14030 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14032 op1 = immed_double_const (lo, hi, DImode);
14035 emit_move_insn (operands[2], op1);
14039 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14043 (define_insn "*btdi_rex64"
14044 [(set (reg:CCC FLAGS_REG)
14047 (match_operand:DI 0 "register_operand" "r")
14049 (match_operand:DI 1 "nonmemory_operand" "rN"))
14051 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14052 "bt{q}\t{%1, %0|%0, %1}"
14053 [(set_attr "type" "alu1")])
14055 (define_insn "*btsi"
14056 [(set (reg:CCC FLAGS_REG)
14059 (match_operand:SI 0 "register_operand" "r")
14061 (match_operand:SI 1 "nonmemory_operand" "rN"))
14063 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14064 "bt{l}\t{%1, %0|%0, %1}"
14065 [(set_attr "type" "alu1")])
14067 ;; Store-flag instructions.
14069 ;; For all sCOND expanders, also expand the compare or test insn that
14070 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14072 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14073 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14074 ;; way, which can later delete the movzx if only QImode is needed.
14076 (define_expand "s<code>"
14077 [(set (match_operand:QI 0 "register_operand" "")
14078 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14080 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14082 (define_expand "s<code>"
14083 [(set (match_operand:QI 0 "register_operand" "")
14084 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14085 "TARGET_80387 || TARGET_SSE"
14086 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14088 (define_insn "*setcc_1"
14089 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14090 (match_operator:QI 1 "ix86_comparison_operator"
14091 [(reg FLAGS_REG) (const_int 0)]))]
14094 [(set_attr "type" "setcc")
14095 (set_attr "mode" "QI")])
14097 (define_insn "*setcc_2"
14098 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14099 (match_operator:QI 1 "ix86_comparison_operator"
14100 [(reg FLAGS_REG) (const_int 0)]))]
14103 [(set_attr "type" "setcc")
14104 (set_attr "mode" "QI")])
14106 ;; In general it is not safe to assume too much about CCmode registers,
14107 ;; so simplify-rtx stops when it sees a second one. Under certain
14108 ;; conditions this is safe on x86, so help combine not create
14115 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14116 (ne:QI (match_operator 1 "ix86_comparison_operator"
14117 [(reg FLAGS_REG) (const_int 0)])
14120 [(set (match_dup 0) (match_dup 1))]
14122 PUT_MODE (operands[1], QImode);
14126 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14127 (ne:QI (match_operator 1 "ix86_comparison_operator"
14128 [(reg FLAGS_REG) (const_int 0)])
14131 [(set (match_dup 0) (match_dup 1))]
14133 PUT_MODE (operands[1], QImode);
14137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14138 (eq:QI (match_operator 1 "ix86_comparison_operator"
14139 [(reg FLAGS_REG) (const_int 0)])
14142 [(set (match_dup 0) (match_dup 1))]
14144 rtx new_op1 = copy_rtx (operands[1]);
14145 operands[1] = new_op1;
14146 PUT_MODE (new_op1, QImode);
14147 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14148 GET_MODE (XEXP (new_op1, 0))));
14150 /* Make sure that (a) the CCmode we have for the flags is strong
14151 enough for the reversed compare or (b) we have a valid FP compare. */
14152 if (! ix86_comparison_operator (new_op1, VOIDmode))
14157 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14158 (eq:QI (match_operator 1 "ix86_comparison_operator"
14159 [(reg FLAGS_REG) (const_int 0)])
14162 [(set (match_dup 0) (match_dup 1))]
14164 rtx new_op1 = copy_rtx (operands[1]);
14165 operands[1] = new_op1;
14166 PUT_MODE (new_op1, QImode);
14167 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14168 GET_MODE (XEXP (new_op1, 0))));
14170 /* Make sure that (a) the CCmode we have for the flags is strong
14171 enough for the reversed compare or (b) we have a valid FP compare. */
14172 if (! ix86_comparison_operator (new_op1, VOIDmode))
14176 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14177 ;; subsequent logical operations are used to imitate conditional moves.
14178 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14181 (define_insn "*avx_setcc<mode>"
14182 [(set (match_operand:MODEF 0 "register_operand" "=x")
14183 (match_operator:MODEF 1 "avx_comparison_float_operator"
14184 [(match_operand:MODEF 2 "register_operand" "x")
14185 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14187 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14188 [(set_attr "type" "ssecmp")
14189 (set_attr "prefix" "vex")
14190 (set_attr "mode" "<MODE>")])
14192 (define_insn "*sse_setcc<mode>"
14193 [(set (match_operand:MODEF 0 "register_operand" "=x")
14194 (match_operator:MODEF 1 "sse_comparison_operator"
14195 [(match_operand:MODEF 2 "register_operand" "0")
14196 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14197 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14198 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14199 [(set_attr "type" "ssecmp")
14200 (set_attr "mode" "<MODE>")])
14202 (define_insn "*sse5_setcc<mode>"
14203 [(set (match_operand:MODEF 0 "register_operand" "=x")
14204 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14205 [(match_operand:MODEF 2 "register_operand" "x")
14206 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14208 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14209 [(set_attr "type" "sse4arg")
14210 (set_attr "mode" "<MODE>")])
14213 ;; Basic conditional jump instructions.
14214 ;; We ignore the overflow flag for signed branch instructions.
14216 ;; For all bCOND expanders, also expand the compare or test insn that
14217 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14219 (define_expand "b<code>"
14221 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14223 (label_ref (match_operand 0 ""))
14226 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14228 (define_expand "b<code>"
14230 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14232 (label_ref (match_operand 0 ""))
14234 "TARGET_80387 || TARGET_SSE_MATH"
14235 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14237 (define_insn "*jcc_1"
14239 (if_then_else (match_operator 1 "ix86_comparison_operator"
14240 [(reg FLAGS_REG) (const_int 0)])
14241 (label_ref (match_operand 0 "" ""))
14245 [(set_attr "type" "ibr")
14246 (set_attr "modrm" "0")
14247 (set (attr "length")
14248 (if_then_else (and (ge (minus (match_dup 0) (pc))
14250 (lt (minus (match_dup 0) (pc))
14255 (define_insn "*jcc_2"
14257 (if_then_else (match_operator 1 "ix86_comparison_operator"
14258 [(reg FLAGS_REG) (const_int 0)])
14260 (label_ref (match_operand 0 "" ""))))]
14263 [(set_attr "type" "ibr")
14264 (set_attr "modrm" "0")
14265 (set (attr "length")
14266 (if_then_else (and (ge (minus (match_dup 0) (pc))
14268 (lt (minus (match_dup 0) (pc))
14273 ;; In general it is not safe to assume too much about CCmode registers,
14274 ;; so simplify-rtx stops when it sees a second one. Under certain
14275 ;; conditions this is safe on x86, so help combine not create
14283 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14284 [(reg FLAGS_REG) (const_int 0)])
14286 (label_ref (match_operand 1 "" ""))
14290 (if_then_else (match_dup 0)
14291 (label_ref (match_dup 1))
14294 PUT_MODE (operands[0], VOIDmode);
14299 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14300 [(reg FLAGS_REG) (const_int 0)])
14302 (label_ref (match_operand 1 "" ""))
14306 (if_then_else (match_dup 0)
14307 (label_ref (match_dup 1))
14310 rtx new_op0 = copy_rtx (operands[0]);
14311 operands[0] = new_op0;
14312 PUT_MODE (new_op0, VOIDmode);
14313 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14314 GET_MODE (XEXP (new_op0, 0))));
14316 /* Make sure that (a) the CCmode we have for the flags is strong
14317 enough for the reversed compare or (b) we have a valid FP compare. */
14318 if (! ix86_comparison_operator (new_op0, VOIDmode))
14322 ;; zero_extend in SImode is correct, since this is what combine pass
14323 ;; generates from shift insn with QImode operand. Actually, the mode of
14324 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14325 ;; appropriate modulo of the bit offset value.
14327 (define_insn_and_split "*jcc_btdi_rex64"
14329 (if_then_else (match_operator 0 "bt_comparison_operator"
14331 (match_operand:DI 1 "register_operand" "r")
14334 (match_operand:QI 2 "register_operand" "r")))
14336 (label_ref (match_operand 3 "" ""))
14338 (clobber (reg:CC FLAGS_REG))]
14339 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14342 [(set (reg:CCC FLAGS_REG)
14350 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14351 (label_ref (match_dup 3))
14354 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14356 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14359 ;; avoid useless masking of bit offset operand
14360 (define_insn_and_split "*jcc_btdi_mask_rex64"
14362 (if_then_else (match_operator 0 "bt_comparison_operator"
14364 (match_operand:DI 1 "register_operand" "r")
14367 (match_operand:SI 2 "register_operand" "r")
14368 (match_operand:SI 3 "const_int_operand" "n")))])
14369 (label_ref (match_operand 4 "" ""))
14371 (clobber (reg:CC FLAGS_REG))]
14372 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14373 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14376 [(set (reg:CCC FLAGS_REG)
14384 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14385 (label_ref (match_dup 4))
14388 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14390 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14393 (define_insn_and_split "*jcc_btsi"
14395 (if_then_else (match_operator 0 "bt_comparison_operator"
14397 (match_operand:SI 1 "register_operand" "r")
14400 (match_operand:QI 2 "register_operand" "r")))
14402 (label_ref (match_operand 3 "" ""))
14404 (clobber (reg:CC FLAGS_REG))]
14405 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14408 [(set (reg:CCC FLAGS_REG)
14416 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14417 (label_ref (match_dup 3))
14420 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14422 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14425 ;; avoid useless masking of bit offset operand
14426 (define_insn_and_split "*jcc_btsi_mask"
14428 (if_then_else (match_operator 0 "bt_comparison_operator"
14430 (match_operand:SI 1 "register_operand" "r")
14433 (match_operand:SI 2 "register_operand" "r")
14434 (match_operand:SI 3 "const_int_operand" "n")))])
14435 (label_ref (match_operand 4 "" ""))
14437 (clobber (reg:CC FLAGS_REG))]
14438 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14439 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14442 [(set (reg:CCC FLAGS_REG)
14450 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14451 (label_ref (match_dup 4))
14453 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14455 (define_insn_and_split "*jcc_btsi_1"
14457 (if_then_else (match_operator 0 "bt_comparison_operator"
14460 (match_operand:SI 1 "register_operand" "r")
14461 (match_operand:QI 2 "register_operand" "r"))
14464 (label_ref (match_operand 3 "" ""))
14466 (clobber (reg:CC FLAGS_REG))]
14467 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14470 [(set (reg:CCC FLAGS_REG)
14478 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14479 (label_ref (match_dup 3))
14482 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14484 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14487 ;; avoid useless masking of bit offset operand
14488 (define_insn_and_split "*jcc_btsi_mask_1"
14491 (match_operator 0 "bt_comparison_operator"
14494 (match_operand:SI 1 "register_operand" "r")
14497 (match_operand:SI 2 "register_operand" "r")
14498 (match_operand:SI 3 "const_int_operand" "n")) 0))
14501 (label_ref (match_operand 4 "" ""))
14503 (clobber (reg:CC FLAGS_REG))]
14504 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14505 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14508 [(set (reg:CCC FLAGS_REG)
14516 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14517 (label_ref (match_dup 4))
14519 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14521 ;; Define combination compare-and-branch fp compare instructions to use
14522 ;; during early optimization. Splitting the operation apart early makes
14523 ;; for bad code when we want to reverse the operation.
14525 (define_insn "*fp_jcc_1_mixed"
14527 (if_then_else (match_operator 0 "comparison_operator"
14528 [(match_operand 1 "register_operand" "f,x")
14529 (match_operand 2 "nonimmediate_operand" "f,xm")])
14530 (label_ref (match_operand 3 "" ""))
14532 (clobber (reg:CCFP FPSR_REG))
14533 (clobber (reg:CCFP FLAGS_REG))]
14534 "TARGET_MIX_SSE_I387
14535 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14536 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14537 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14540 (define_insn "*fp_jcc_1_sse"
14542 (if_then_else (match_operator 0 "comparison_operator"
14543 [(match_operand 1 "register_operand" "x")
14544 (match_operand 2 "nonimmediate_operand" "xm")])
14545 (label_ref (match_operand 3 "" ""))
14547 (clobber (reg:CCFP FPSR_REG))
14548 (clobber (reg:CCFP FLAGS_REG))]
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_387"
14557 (if_then_else (match_operator 0 "comparison_operator"
14558 [(match_operand 1 "register_operand" "f")
14559 (match_operand 2 "register_operand" "f")])
14560 (label_ref (match_operand 3 "" ""))
14562 (clobber (reg:CCFP FPSR_REG))
14563 (clobber (reg:CCFP FLAGS_REG))]
14564 "X87_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_2_mixed"
14572 (if_then_else (match_operator 0 "comparison_operator"
14573 [(match_operand 1 "register_operand" "f,x")
14574 (match_operand 2 "nonimmediate_operand" "f,xm")])
14576 (label_ref (match_operand 3 "" ""))))
14577 (clobber (reg:CCFP FPSR_REG))
14578 (clobber (reg:CCFP FLAGS_REG))]
14579 "TARGET_MIX_SSE_I387
14580 && SSE_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_sse"
14587 (if_then_else (match_operator 0 "comparison_operator"
14588 [(match_operand 1 "register_operand" "x")
14589 (match_operand 2 "nonimmediate_operand" "xm")])
14591 (label_ref (match_operand 3 "" ""))))
14592 (clobber (reg:CCFP FPSR_REG))
14593 (clobber (reg:CCFP FLAGS_REG))]
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_387"
14602 (if_then_else (match_operator 0 "comparison_operator"
14603 [(match_operand 1 "register_operand" "f")
14604 (match_operand 2 "register_operand" "f")])
14606 (label_ref (match_operand 3 "" ""))))
14607 (clobber (reg:CCFP FPSR_REG))
14608 (clobber (reg:CCFP FLAGS_REG))]
14609 "X87_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_3_387"
14617 (if_then_else (match_operator 0 "comparison_operator"
14618 [(match_operand 1 "register_operand" "f")
14619 (match_operand 2 "nonimmediate_operand" "fm")])
14620 (label_ref (match_operand 3 "" ""))
14622 (clobber (reg:CCFP FPSR_REG))
14623 (clobber (reg:CCFP FLAGS_REG))
14624 (clobber (match_scratch:HI 4 "=a"))]
14626 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14627 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14629 && SELECT_CC_MODE (GET_CODE (operands[0]),
14630 operands[1], operands[2]) == CCFPmode
14631 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14634 (define_insn "*fp_jcc_4_387"
14636 (if_then_else (match_operator 0 "comparison_operator"
14637 [(match_operand 1 "register_operand" "f")
14638 (match_operand 2 "nonimmediate_operand" "fm")])
14640 (label_ref (match_operand 3 "" ""))))
14641 (clobber (reg:CCFP FPSR_REG))
14642 (clobber (reg:CCFP FLAGS_REG))
14643 (clobber (match_scratch:HI 4 "=a"))]
14645 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648 && SELECT_CC_MODE (GET_CODE (operands[0]),
14649 operands[1], operands[2]) == CCFPmode
14650 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14653 (define_insn "*fp_jcc_5_387"
14655 (if_then_else (match_operator 0 "comparison_operator"
14656 [(match_operand 1 "register_operand" "f")
14657 (match_operand 2 "register_operand" "f")])
14658 (label_ref (match_operand 3 "" ""))
14660 (clobber (reg:CCFP FPSR_REG))
14661 (clobber (reg:CCFP FLAGS_REG))
14662 (clobber (match_scratch:HI 4 "=a"))]
14663 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14664 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14665 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14668 (define_insn "*fp_jcc_6_387"
14670 (if_then_else (match_operator 0 "comparison_operator"
14671 [(match_operand 1 "register_operand" "f")
14672 (match_operand 2 "register_operand" "f")])
14674 (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_7_387"
14685 (if_then_else (match_operator 0 "comparison_operator"
14686 [(match_operand 1 "register_operand" "f")
14687 (match_operand 2 "const0_operand" "")])
14688 (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_use_fcomi_compare (GET_CODE (operands[0]))
14696 && SELECT_CC_MODE (GET_CODE (operands[0]),
14697 operands[1], operands[2]) == CCFPmode
14698 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14701 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14702 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14703 ;; with a precedence over other operators and is always put in the first
14704 ;; place. Swap condition and operands to match ficom instruction.
14706 (define_insn "*fp_jcc_8<mode>_387"
14708 (if_then_else (match_operator 0 "comparison_operator"
14709 [(match_operator 1 "float_operator"
14710 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14711 (match_operand 3 "register_operand" "f,f")])
14712 (label_ref (match_operand 4 "" ""))
14714 (clobber (reg:CCFP FPSR_REG))
14715 (clobber (reg:CCFP FLAGS_REG))
14716 (clobber (match_scratch:HI 5 "=a,a"))]
14717 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14718 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14719 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14720 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14721 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14722 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14727 (if_then_else (match_operator 0 "comparison_operator"
14728 [(match_operand 1 "register_operand" "")
14729 (match_operand 2 "nonimmediate_operand" "")])
14730 (match_operand 3 "" "")
14731 (match_operand 4 "" "")))
14732 (clobber (reg:CCFP FPSR_REG))
14733 (clobber (reg:CCFP FLAGS_REG))]
14737 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14738 operands[3], operands[4], NULL_RTX, NULL_RTX);
14744 (if_then_else (match_operator 0 "comparison_operator"
14745 [(match_operand 1 "register_operand" "")
14746 (match_operand 2 "general_operand" "")])
14747 (match_operand 3 "" "")
14748 (match_operand 4 "" "")))
14749 (clobber (reg:CCFP FPSR_REG))
14750 (clobber (reg:CCFP FLAGS_REG))
14751 (clobber (match_scratch:HI 5 "=a"))]
14755 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14756 operands[3], operands[4], operands[5], NULL_RTX);
14762 (if_then_else (match_operator 0 "comparison_operator"
14763 [(match_operator 1 "float_operator"
14764 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14765 (match_operand 3 "register_operand" "")])
14766 (match_operand 4 "" "")
14767 (match_operand 5 "" "")))
14768 (clobber (reg:CCFP FPSR_REG))
14769 (clobber (reg:CCFP FLAGS_REG))
14770 (clobber (match_scratch:HI 6 "=a"))]
14774 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14775 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14776 operands[3], operands[7],
14777 operands[4], operands[5], operands[6], NULL_RTX);
14781 ;; %%% Kill this when reload knows how to do it.
14784 (if_then_else (match_operator 0 "comparison_operator"
14785 [(match_operator 1 "float_operator"
14786 [(match_operand:X87MODEI12 2 "register_operand" "")])
14787 (match_operand 3 "register_operand" "")])
14788 (match_operand 4 "" "")
14789 (match_operand 5 "" "")))
14790 (clobber (reg:CCFP FPSR_REG))
14791 (clobber (reg:CCFP FLAGS_REG))
14792 (clobber (match_scratch:HI 6 "=a"))]
14796 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14797 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14798 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14799 operands[3], operands[7],
14800 operands[4], operands[5], operands[6], operands[2]);
14804 ;; Unconditional and other jump instructions
14806 (define_insn "jump"
14808 (label_ref (match_operand 0 "" "")))]
14811 [(set_attr "type" "ibr")
14812 (set (attr "length")
14813 (if_then_else (and (ge (minus (match_dup 0) (pc))
14815 (lt (minus (match_dup 0) (pc))
14819 (set_attr "modrm" "0")])
14821 (define_expand "indirect_jump"
14822 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14826 (define_insn "*indirect_jump"
14827 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14830 [(set_attr "type" "ibr")
14831 (set_attr "length_immediate" "0")])
14833 (define_expand "tablejump"
14834 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14835 (use (label_ref (match_operand 1 "" "")))])]
14838 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14839 relative. Convert the relative address to an absolute address. */
14843 enum rtx_code code;
14845 /* We can't use @GOTOFF for text labels on VxWorks;
14846 see gotoff_operand. */
14847 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14851 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14853 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14857 op1 = pic_offset_table_rtx;
14862 op0 = pic_offset_table_rtx;
14866 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14871 (define_insn "*tablejump_1"
14872 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14873 (use (label_ref (match_operand 1 "" "")))]
14876 [(set_attr "type" "ibr")
14877 (set_attr "length_immediate" "0")])
14879 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14882 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14883 (set (match_operand:QI 1 "register_operand" "")
14884 (match_operator:QI 2 "ix86_comparison_operator"
14885 [(reg FLAGS_REG) (const_int 0)]))
14886 (set (match_operand 3 "q_regs_operand" "")
14887 (zero_extend (match_dup 1)))]
14888 "(peep2_reg_dead_p (3, operands[1])
14889 || operands_match_p (operands[1], operands[3]))
14890 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14891 [(set (match_dup 4) (match_dup 0))
14892 (set (strict_low_part (match_dup 5))
14895 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14896 operands[5] = gen_lowpart (QImode, operands[3]);
14897 ix86_expand_clear (operands[3]);
14900 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14903 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14904 (set (match_operand:QI 1 "register_operand" "")
14905 (match_operator:QI 2 "ix86_comparison_operator"
14906 [(reg FLAGS_REG) (const_int 0)]))
14907 (parallel [(set (match_operand 3 "q_regs_operand" "")
14908 (zero_extend (match_dup 1)))
14909 (clobber (reg:CC FLAGS_REG))])]
14910 "(peep2_reg_dead_p (3, operands[1])
14911 || operands_match_p (operands[1], operands[3]))
14912 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14913 [(set (match_dup 4) (match_dup 0))
14914 (set (strict_low_part (match_dup 5))
14917 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14918 operands[5] = gen_lowpart (QImode, operands[3]);
14919 ix86_expand_clear (operands[3]);
14922 ;; Call instructions.
14924 ;; The predicates normally associated with named expanders are not properly
14925 ;; checked for calls. This is a bug in the generic code, but it isn't that
14926 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14928 ;; Call subroutine returning no value.
14930 (define_expand "call_pop"
14931 [(parallel [(call (match_operand:QI 0 "" "")
14932 (match_operand:SI 1 "" ""))
14933 (set (reg:SI SP_REG)
14934 (plus:SI (reg:SI SP_REG)
14935 (match_operand:SI 3 "" "")))])]
14938 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14942 (define_insn "*call_pop_0"
14943 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14944 (match_operand:SI 1 "" ""))
14945 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14946 (match_operand:SI 2 "immediate_operand" "")))]
14949 if (SIBLING_CALL_P (insn))
14952 return "call\t%P0";
14954 [(set_attr "type" "call")])
14956 (define_insn "*call_pop_1"
14957 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14958 (match_operand:SI 1 "" ""))
14959 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14960 (match_operand:SI 2 "immediate_operand" "i")))]
14963 if (constant_call_address_operand (operands[0], Pmode))
14965 if (SIBLING_CALL_P (insn))
14968 return "call\t%P0";
14970 if (SIBLING_CALL_P (insn))
14973 return "call\t%A0";
14975 [(set_attr "type" "call")])
14977 (define_expand "call"
14978 [(call (match_operand:QI 0 "" "")
14979 (match_operand 1 "" ""))
14980 (use (match_operand 2 "" ""))]
14983 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14987 (define_expand "sibcall"
14988 [(call (match_operand:QI 0 "" "")
14989 (match_operand 1 "" ""))
14990 (use (match_operand 2 "" ""))]
14993 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14997 (define_insn "*call_0"
14998 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14999 (match_operand 1 "" ""))]
15002 if (SIBLING_CALL_P (insn))
15005 return "call\t%P0";
15007 [(set_attr "type" "call")])
15009 (define_insn "*call_1"
15010 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15011 (match_operand 1 "" ""))]
15012 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15014 if (constant_call_address_operand (operands[0], Pmode))
15015 return "call\t%P0";
15016 return "call\t%A0";
15018 [(set_attr "type" "call")])
15020 (define_insn "*sibcall_1"
15021 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15022 (match_operand 1 "" ""))]
15023 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15025 if (constant_call_address_operand (operands[0], Pmode))
15029 [(set_attr "type" "call")])
15031 (define_insn "*call_1_rex64"
15032 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15033 (match_operand 1 "" ""))]
15034 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15035 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15037 if (constant_call_address_operand (operands[0], Pmode))
15038 return "call\t%P0";
15039 return "call\t%A0";
15041 [(set_attr "type" "call")])
15043 (define_insn "*call_1_rex64_ms_sysv"
15044 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15045 (match_operand 1 "" ""))
15046 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15047 (clobber (reg:TI 27))
15048 (clobber (reg:TI 28))
15049 (clobber (reg:TI 45))
15050 (clobber (reg:TI 46))
15051 (clobber (reg:TI 47))
15052 (clobber (reg:TI 48))
15053 (clobber (reg:TI 49))
15054 (clobber (reg:TI 50))
15055 (clobber (reg:TI 51))
15056 (clobber (reg:TI 52))
15057 (clobber (reg:DI SI_REG))
15058 (clobber (reg:DI DI_REG))]
15059 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15061 if (constant_call_address_operand (operands[0], Pmode))
15062 return "call\t%P0";
15063 return "call\t%A0";
15065 [(set_attr "type" "call")])
15067 (define_insn "*call_1_rex64_large"
15068 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15069 (match_operand 1 "" ""))]
15070 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15072 [(set_attr "type" "call")])
15074 (define_insn "*sibcall_1_rex64"
15075 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15076 (match_operand 1 "" ""))]
15077 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15079 [(set_attr "type" "call")])
15081 (define_insn "*sibcall_1_rex64_v"
15082 [(call (mem:QI (reg:DI R11_REG))
15083 (match_operand 0 "" ""))]
15084 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15086 [(set_attr "type" "call")])
15089 ;; Call subroutine, returning value in operand 0
15091 (define_expand "call_value_pop"
15092 [(parallel [(set (match_operand 0 "" "")
15093 (call (match_operand:QI 1 "" "")
15094 (match_operand:SI 2 "" "")))
15095 (set (reg:SI SP_REG)
15096 (plus:SI (reg:SI SP_REG)
15097 (match_operand:SI 4 "" "")))])]
15100 ix86_expand_call (operands[0], operands[1], operands[2],
15101 operands[3], operands[4], 0);
15105 (define_expand "call_value"
15106 [(set (match_operand 0 "" "")
15107 (call (match_operand:QI 1 "" "")
15108 (match_operand:SI 2 "" "")))
15109 (use (match_operand:SI 3 "" ""))]
15110 ;; Operand 2 not used on the i386.
15113 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15117 (define_expand "sibcall_value"
15118 [(set (match_operand 0 "" "")
15119 (call (match_operand:QI 1 "" "")
15120 (match_operand:SI 2 "" "")))
15121 (use (match_operand:SI 3 "" ""))]
15122 ;; Operand 2 not used on the i386.
15125 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15129 ;; Call subroutine returning any type.
15131 (define_expand "untyped_call"
15132 [(parallel [(call (match_operand 0 "" "")
15134 (match_operand 1 "" "")
15135 (match_operand 2 "" "")])]
15140 /* In order to give reg-stack an easier job in validating two
15141 coprocessor registers as containing a possible return value,
15142 simply pretend the untyped call returns a complex long double
15145 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15146 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15147 operands[0], const0_rtx,
15148 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15149 : X64_SSE_REGPARM_MAX)
15153 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15155 rtx set = XVECEXP (operands[2], 0, i);
15156 emit_move_insn (SET_DEST (set), SET_SRC (set));
15159 /* The optimizer does not know that the call sets the function value
15160 registers we stored in the result block. We avoid problems by
15161 claiming that all hard registers are used and clobbered at this
15163 emit_insn (gen_blockage ());
15168 ;; Prologue and epilogue instructions
15170 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15171 ;; all of memory. This blocks insns from being moved across this point.
15173 (define_insn "blockage"
15174 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15177 [(set_attr "length" "0")])
15179 ;; Do not schedule instructions accessing memory across this point.
15181 (define_expand "memory_blockage"
15182 [(set (match_dup 0)
15183 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15186 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15187 MEM_VOLATILE_P (operands[0]) = 1;
15190 (define_insn "*memory_blockage"
15191 [(set (match_operand:BLK 0 "" "")
15192 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15195 [(set_attr "length" "0")])
15197 ;; As USE insns aren't meaningful after reload, this is used instead
15198 ;; to prevent deleting instructions setting registers for PIC code
15199 (define_insn "prologue_use"
15200 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15203 [(set_attr "length" "0")])
15205 ;; Insn emitted into the body of a function to return from a function.
15206 ;; This is only done if the function's epilogue is known to be simple.
15207 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15209 (define_expand "return"
15211 "ix86_can_use_return_insn_p ()"
15213 if (crtl->args.pops_args)
15215 rtx popc = GEN_INT (crtl->args.pops_args);
15216 emit_jump_insn (gen_return_pop_internal (popc));
15221 (define_insn "return_internal"
15225 [(set_attr "length" "1")
15226 (set_attr "length_immediate" "0")
15227 (set_attr "modrm" "0")])
15229 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15230 ;; instruction Athlon and K8 have.
15232 (define_insn "return_internal_long"
15234 (unspec [(const_int 0)] UNSPEC_REP)]
15237 [(set_attr "length" "1")
15238 (set_attr "length_immediate" "0")
15239 (set_attr "prefix_rep" "1")
15240 (set_attr "modrm" "0")])
15242 (define_insn "return_pop_internal"
15244 (use (match_operand:SI 0 "const_int_operand" ""))]
15247 [(set_attr "length" "3")
15248 (set_attr "length_immediate" "2")
15249 (set_attr "modrm" "0")])
15251 (define_insn "return_indirect_internal"
15253 (use (match_operand:SI 0 "register_operand" "r"))]
15256 [(set_attr "type" "ibr")
15257 (set_attr "length_immediate" "0")])
15263 [(set_attr "length" "1")
15264 (set_attr "length_immediate" "0")
15265 (set_attr "modrm" "0")])
15267 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15268 ;; branch prediction penalty for the third jump in a 16-byte
15271 (define_insn "align"
15272 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15275 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15276 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15278 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15279 The align insn is used to avoid 3 jump instructions in the row to improve
15280 branch prediction and the benefits hardly outweigh the cost of extra 8
15281 nops on the average inserted by full alignment pseudo operation. */
15285 [(set_attr "length" "16")])
15287 (define_expand "prologue"
15290 "ix86_expand_prologue (); DONE;")
15292 (define_insn "set_got"
15293 [(set (match_operand:SI 0 "register_operand" "=r")
15294 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15295 (clobber (reg:CC FLAGS_REG))]
15297 { return output_set_got (operands[0], NULL_RTX); }
15298 [(set_attr "type" "multi")
15299 (set_attr "length" "12")])
15301 (define_insn "set_got_labelled"
15302 [(set (match_operand:SI 0 "register_operand" "=r")
15303 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15305 (clobber (reg:CC FLAGS_REG))]
15307 { return output_set_got (operands[0], operands[1]); }
15308 [(set_attr "type" "multi")
15309 (set_attr "length" "12")])
15311 (define_insn "set_got_rex64"
15312 [(set (match_operand:DI 0 "register_operand" "=r")
15313 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15315 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15316 [(set_attr "type" "lea")
15317 (set_attr "length" "6")])
15319 (define_insn "set_rip_rex64"
15320 [(set (match_operand:DI 0 "register_operand" "=r")
15321 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15323 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15324 [(set_attr "type" "lea")
15325 (set_attr "length" "6")])
15327 (define_insn "set_got_offset_rex64"
15328 [(set (match_operand:DI 0 "register_operand" "=r")
15330 [(label_ref (match_operand 1 "" ""))]
15331 UNSPEC_SET_GOT_OFFSET))]
15333 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15334 [(set_attr "type" "imov")
15335 (set_attr "length" "11")])
15337 (define_expand "epilogue"
15340 "ix86_expand_epilogue (1); DONE;")
15342 (define_expand "sibcall_epilogue"
15345 "ix86_expand_epilogue (0); DONE;")
15347 (define_expand "eh_return"
15348 [(use (match_operand 0 "register_operand" ""))]
15351 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15353 /* Tricky bit: we write the address of the handler to which we will
15354 be returning into someone else's stack frame, one word below the
15355 stack address we wish to restore. */
15356 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15357 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15358 tmp = gen_rtx_MEM (Pmode, tmp);
15359 emit_move_insn (tmp, ra);
15361 if (Pmode == SImode)
15362 emit_jump_insn (gen_eh_return_si (sa));
15364 emit_jump_insn (gen_eh_return_di (sa));
15369 (define_insn_and_split "eh_return_<mode>"
15371 (unspec [(match_operand:P 0 "register_operand" "c")]
15372 UNSPEC_EH_RETURN))]
15377 "ix86_expand_epilogue (2); DONE;")
15379 (define_insn "leave"
15380 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15381 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15382 (clobber (mem:BLK (scratch)))]
15385 [(set_attr "type" "leave")])
15387 (define_insn "leave_rex64"
15388 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15389 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15390 (clobber (mem:BLK (scratch)))]
15393 [(set_attr "type" "leave")])
15395 (define_expand "ffssi2"
15397 [(set (match_operand:SI 0 "register_operand" "")
15398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15399 (clobber (match_scratch:SI 2 ""))
15400 (clobber (reg:CC FLAGS_REG))])]
15405 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15410 (define_expand "ffs_cmove"
15411 [(set (match_dup 2) (const_int -1))
15412 (parallel [(set (reg:CCZ FLAGS_REG)
15413 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15415 (set (match_operand:SI 0 "register_operand" "")
15416 (ctz:SI (match_dup 1)))])
15417 (set (match_dup 0) (if_then_else:SI
15418 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15421 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15422 (clobber (reg:CC FLAGS_REG))])]
15424 "operands[2] = gen_reg_rtx (SImode);")
15426 (define_insn_and_split "*ffs_no_cmove"
15427 [(set (match_operand:SI 0 "register_operand" "=r")
15428 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15429 (clobber (match_scratch:SI 2 "=&q"))
15430 (clobber (reg:CC FLAGS_REG))]
15433 "&& reload_completed"
15434 [(parallel [(set (reg:CCZ FLAGS_REG)
15435 (compare:CCZ (match_dup 1) (const_int 0)))
15436 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15437 (set (strict_low_part (match_dup 3))
15438 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15439 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15440 (clobber (reg:CC FLAGS_REG))])
15441 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15442 (clobber (reg:CC FLAGS_REG))])
15443 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15444 (clobber (reg:CC FLAGS_REG))])]
15446 operands[3] = gen_lowpart (QImode, operands[2]);
15447 ix86_expand_clear (operands[2]);
15450 (define_insn "*ffssi_1"
15451 [(set (reg:CCZ FLAGS_REG)
15452 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15454 (set (match_operand:SI 0 "register_operand" "=r")
15455 (ctz:SI (match_dup 1)))]
15457 "bsf{l}\t{%1, %0|%0, %1}"
15458 [(set_attr "prefix_0f" "1")])
15460 (define_expand "ffsdi2"
15461 [(set (match_dup 2) (const_int -1))
15462 (parallel [(set (reg:CCZ FLAGS_REG)
15463 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15465 (set (match_operand:DI 0 "register_operand" "")
15466 (ctz:DI (match_dup 1)))])
15467 (set (match_dup 0) (if_then_else:DI
15468 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15471 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15472 (clobber (reg:CC FLAGS_REG))])]
15474 "operands[2] = gen_reg_rtx (DImode);")
15476 (define_insn "*ffsdi_1"
15477 [(set (reg:CCZ FLAGS_REG)
15478 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15480 (set (match_operand:DI 0 "register_operand" "=r")
15481 (ctz:DI (match_dup 1)))]
15483 "bsf{q}\t{%1, %0|%0, %1}"
15484 [(set_attr "prefix_0f" "1")])
15486 (define_insn "ctzsi2"
15487 [(set (match_operand:SI 0 "register_operand" "=r")
15488 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15489 (clobber (reg:CC FLAGS_REG))]
15491 "bsf{l}\t{%1, %0|%0, %1}"
15492 [(set_attr "prefix_0f" "1")])
15494 (define_insn "ctzdi2"
15495 [(set (match_operand:DI 0 "register_operand" "=r")
15496 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15497 (clobber (reg:CC FLAGS_REG))]
15499 "bsf{q}\t{%1, %0|%0, %1}"
15500 [(set_attr "prefix_0f" "1")])
15502 (define_expand "clzsi2"
15504 [(set (match_operand:SI 0 "register_operand" "")
15505 (minus:SI (const_int 31)
15506 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15507 (clobber (reg:CC FLAGS_REG))])
15509 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15510 (clobber (reg:CC FLAGS_REG))])]
15515 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15520 (define_insn "clzsi2_abm"
15521 [(set (match_operand:SI 0 "register_operand" "=r")
15522 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15523 (clobber (reg:CC FLAGS_REG))]
15525 "lzcnt{l}\t{%1, %0|%0, %1}"
15526 [(set_attr "prefix_rep" "1")
15527 (set_attr "type" "bitmanip")
15528 (set_attr "mode" "SI")])
15530 (define_insn "*bsr"
15531 [(set (match_operand:SI 0 "register_operand" "=r")
15532 (minus:SI (const_int 31)
15533 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15534 (clobber (reg:CC FLAGS_REG))]
15536 "bsr{l}\t{%1, %0|%0, %1}"
15537 [(set_attr "prefix_0f" "1")
15538 (set_attr "mode" "SI")])
15540 (define_insn "popcount<mode>2"
15541 [(set (match_operand:SWI248 0 "register_operand" "=r")
15543 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15544 (clobber (reg:CC FLAGS_REG))]
15548 return "popcnt\t{%1, %0|%0, %1}";
15550 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15553 [(set_attr "prefix_rep" "1")
15554 (set_attr "type" "bitmanip")
15555 (set_attr "mode" "<MODE>")])
15557 (define_insn "*popcount<mode>2_cmp"
15558 [(set (reg FLAGS_REG)
15561 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15563 (set (match_operand:SWI248 0 "register_operand" "=r")
15564 (popcount:SWI248 (match_dup 1)))]
15565 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15568 return "popcnt\t{%1, %0|%0, %1}";
15570 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15573 [(set_attr "prefix_rep" "1")
15574 (set_attr "type" "bitmanip")
15575 (set_attr "mode" "<MODE>")])
15577 (define_insn "*popcountsi2_cmp_zext"
15578 [(set (reg FLAGS_REG)
15580 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15582 (set (match_operand:DI 0 "register_operand" "=r")
15583 (zero_extend:DI(popcount:SI (match_dup 1))))]
15584 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15587 return "popcnt\t{%1, %0|%0, %1}";
15589 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15592 [(set_attr "prefix_rep" "1")
15593 (set_attr "type" "bitmanip")
15594 (set_attr "mode" "SI")])
15596 (define_expand "bswapsi2"
15597 [(set (match_operand:SI 0 "register_operand" "")
15598 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15603 rtx x = operands[0];
15605 emit_move_insn (x, operands[1]);
15606 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15607 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15608 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15613 (define_insn "*bswapsi_1"
15614 [(set (match_operand:SI 0 "register_operand" "=r")
15615 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15618 [(set_attr "prefix_0f" "1")
15619 (set_attr "length" "2")])
15621 (define_insn "*bswaphi_lowpart_1"
15622 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15623 (bswap:HI (match_dup 0)))
15624 (clobber (reg:CC FLAGS_REG))]
15625 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15627 xchg{b}\t{%h0, %b0|%b0, %h0}
15628 rol{w}\t{$8, %0|%0, 8}"
15629 [(set_attr "length" "2,4")
15630 (set_attr "mode" "QI,HI")])
15632 (define_insn "bswaphi_lowpart"
15633 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15634 (bswap:HI (match_dup 0)))
15635 (clobber (reg:CC FLAGS_REG))]
15637 "rol{w}\t{$8, %0|%0, 8}"
15638 [(set_attr "length" "4")
15639 (set_attr "mode" "HI")])
15641 (define_insn "bswapdi2"
15642 [(set (match_operand:DI 0 "register_operand" "=r")
15643 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15646 [(set_attr "prefix_0f" "1")
15647 (set_attr "length" "3")])
15649 (define_expand "clzdi2"
15651 [(set (match_operand:DI 0 "register_operand" "")
15652 (minus:DI (const_int 63)
15653 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15654 (clobber (reg:CC FLAGS_REG))])
15656 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15657 (clobber (reg:CC FLAGS_REG))])]
15662 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15667 (define_insn "clzdi2_abm"
15668 [(set (match_operand:DI 0 "register_operand" "=r")
15669 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15670 (clobber (reg:CC FLAGS_REG))]
15671 "TARGET_64BIT && TARGET_ABM"
15672 "lzcnt{q}\t{%1, %0|%0, %1}"
15673 [(set_attr "prefix_rep" "1")
15674 (set_attr "type" "bitmanip")
15675 (set_attr "mode" "DI")])
15677 (define_insn "*bsr_rex64"
15678 [(set (match_operand:DI 0 "register_operand" "=r")
15679 (minus:DI (const_int 63)
15680 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15681 (clobber (reg:CC FLAGS_REG))]
15683 "bsr{q}\t{%1, %0|%0, %1}"
15684 [(set_attr "prefix_0f" "1")
15685 (set_attr "mode" "DI")])
15687 (define_expand "clzhi2"
15689 [(set (match_operand:HI 0 "register_operand" "")
15690 (minus:HI (const_int 15)
15691 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15692 (clobber (reg:CC FLAGS_REG))])
15694 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15695 (clobber (reg:CC FLAGS_REG))])]
15700 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15705 (define_insn "clzhi2_abm"
15706 [(set (match_operand:HI 0 "register_operand" "=r")
15707 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15708 (clobber (reg:CC FLAGS_REG))]
15710 "lzcnt{w}\t{%1, %0|%0, %1}"
15711 [(set_attr "prefix_rep" "1")
15712 (set_attr "type" "bitmanip")
15713 (set_attr "mode" "HI")])
15715 (define_insn "*bsrhi"
15716 [(set (match_operand:HI 0 "register_operand" "=r")
15717 (minus:HI (const_int 15)
15718 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15719 (clobber (reg:CC FLAGS_REG))]
15721 "bsr{w}\t{%1, %0|%0, %1}"
15722 [(set_attr "prefix_0f" "1")
15723 (set_attr "mode" "HI")])
15725 (define_expand "paritydi2"
15726 [(set (match_operand:DI 0 "register_operand" "")
15727 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15730 rtx scratch = gen_reg_rtx (QImode);
15733 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15734 NULL_RTX, operands[1]));
15736 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15737 gen_rtx_REG (CCmode, FLAGS_REG),
15739 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15742 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15745 rtx tmp = gen_reg_rtx (SImode);
15747 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15748 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15753 (define_insn_and_split "paritydi2_cmp"
15754 [(set (reg:CC FLAGS_REG)
15755 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15756 (clobber (match_scratch:DI 0 "=r"))
15757 (clobber (match_scratch:SI 1 "=&r"))
15758 (clobber (match_scratch:HI 2 "=Q"))]
15761 "&& reload_completed"
15763 [(set (match_dup 1)
15764 (xor:SI (match_dup 1) (match_dup 4)))
15765 (clobber (reg:CC FLAGS_REG))])
15767 [(set (reg:CC FLAGS_REG)
15768 (parity:CC (match_dup 1)))
15769 (clobber (match_dup 1))
15770 (clobber (match_dup 2))])]
15772 operands[4] = gen_lowpart (SImode, operands[3]);
15776 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15777 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15780 operands[1] = gen_highpart (SImode, operands[3]);
15783 (define_expand "paritysi2"
15784 [(set (match_operand:SI 0 "register_operand" "")
15785 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15788 rtx scratch = gen_reg_rtx (QImode);
15791 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15793 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15794 gen_rtx_REG (CCmode, FLAGS_REG),
15796 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15798 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15802 (define_insn_and_split "paritysi2_cmp"
15803 [(set (reg:CC FLAGS_REG)
15804 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15805 (clobber (match_scratch:SI 0 "=r"))
15806 (clobber (match_scratch:HI 1 "=&Q"))]
15809 "&& reload_completed"
15811 [(set (match_dup 1)
15812 (xor:HI (match_dup 1) (match_dup 3)))
15813 (clobber (reg:CC FLAGS_REG))])
15815 [(set (reg:CC FLAGS_REG)
15816 (parity:CC (match_dup 1)))
15817 (clobber (match_dup 1))])]
15819 operands[3] = gen_lowpart (HImode, operands[2]);
15821 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15822 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15825 (define_insn "*parityhi2_cmp"
15826 [(set (reg:CC FLAGS_REG)
15827 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15828 (clobber (match_scratch:HI 0 "=Q"))]
15830 "xor{b}\t{%h0, %b0|%b0, %h0}"
15831 [(set_attr "length" "2")
15832 (set_attr "mode" "HI")])
15834 (define_insn "*parityqi2_cmp"
15835 [(set (reg:CC FLAGS_REG)
15836 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15839 [(set_attr "length" "2")
15840 (set_attr "mode" "QI")])
15842 ;; Thread-local storage patterns for ELF.
15844 ;; Note that these code sequences must appear exactly as shown
15845 ;; in order to allow linker relaxation.
15847 (define_insn "*tls_global_dynamic_32_gnu"
15848 [(set (match_operand:SI 0 "register_operand" "=a")
15849 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15850 (match_operand:SI 2 "tls_symbolic_operand" "")
15851 (match_operand:SI 3 "call_insn_operand" "")]
15853 (clobber (match_scratch:SI 4 "=d"))
15854 (clobber (match_scratch:SI 5 "=c"))
15855 (clobber (reg:CC FLAGS_REG))]
15856 "!TARGET_64BIT && TARGET_GNU_TLS"
15857 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15858 [(set_attr "type" "multi")
15859 (set_attr "length" "12")])
15861 (define_insn "*tls_global_dynamic_32_sun"
15862 [(set (match_operand:SI 0 "register_operand" "=a")
15863 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15864 (match_operand:SI 2 "tls_symbolic_operand" "")
15865 (match_operand:SI 3 "call_insn_operand" "")]
15867 (clobber (match_scratch:SI 4 "=d"))
15868 (clobber (match_scratch:SI 5 "=c"))
15869 (clobber (reg:CC FLAGS_REG))]
15870 "!TARGET_64BIT && TARGET_SUN_TLS"
15871 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15872 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15873 [(set_attr "type" "multi")
15874 (set_attr "length" "14")])
15876 (define_expand "tls_global_dynamic_32"
15877 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15880 (match_operand:SI 1 "tls_symbolic_operand" "")
15883 (clobber (match_scratch:SI 4 ""))
15884 (clobber (match_scratch:SI 5 ""))
15885 (clobber (reg:CC FLAGS_REG))])]
15889 operands[2] = pic_offset_table_rtx;
15892 operands[2] = gen_reg_rtx (Pmode);
15893 emit_insn (gen_set_got (operands[2]));
15895 if (TARGET_GNU2_TLS)
15897 emit_insn (gen_tls_dynamic_gnu2_32
15898 (operands[0], operands[1], operands[2]));
15901 operands[3] = ix86_tls_get_addr ();
15904 (define_insn "*tls_global_dynamic_64"
15905 [(set (match_operand:DI 0 "register_operand" "=a")
15906 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15907 (match_operand:DI 3 "" "")))
15908 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15911 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15912 [(set_attr "type" "multi")
15913 (set_attr "length" "16")])
15915 (define_expand "tls_global_dynamic_64"
15916 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15917 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15918 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15922 if (TARGET_GNU2_TLS)
15924 emit_insn (gen_tls_dynamic_gnu2_64
15925 (operands[0], operands[1]));
15928 operands[2] = ix86_tls_get_addr ();
15931 (define_insn "*tls_local_dynamic_base_32_gnu"
15932 [(set (match_operand:SI 0 "register_operand" "=a")
15933 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15934 (match_operand:SI 2 "call_insn_operand" "")]
15935 UNSPEC_TLS_LD_BASE))
15936 (clobber (match_scratch:SI 3 "=d"))
15937 (clobber (match_scratch:SI 4 "=c"))
15938 (clobber (reg:CC FLAGS_REG))]
15939 "!TARGET_64BIT && TARGET_GNU_TLS"
15940 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15941 [(set_attr "type" "multi")
15942 (set_attr "length" "11")])
15944 (define_insn "*tls_local_dynamic_base_32_sun"
15945 [(set (match_operand:SI 0 "register_operand" "=a")
15946 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15947 (match_operand:SI 2 "call_insn_operand" "")]
15948 UNSPEC_TLS_LD_BASE))
15949 (clobber (match_scratch:SI 3 "=d"))
15950 (clobber (match_scratch:SI 4 "=c"))
15951 (clobber (reg:CC FLAGS_REG))]
15952 "!TARGET_64BIT && TARGET_SUN_TLS"
15953 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15954 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15955 [(set_attr "type" "multi")
15956 (set_attr "length" "13")])
15958 (define_expand "tls_local_dynamic_base_32"
15959 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15960 (unspec:SI [(match_dup 1) (match_dup 2)]
15961 UNSPEC_TLS_LD_BASE))
15962 (clobber (match_scratch:SI 3 ""))
15963 (clobber (match_scratch:SI 4 ""))
15964 (clobber (reg:CC FLAGS_REG))])]
15968 operands[1] = pic_offset_table_rtx;
15971 operands[1] = gen_reg_rtx (Pmode);
15972 emit_insn (gen_set_got (operands[1]));
15974 if (TARGET_GNU2_TLS)
15976 emit_insn (gen_tls_dynamic_gnu2_32
15977 (operands[0], ix86_tls_module_base (), operands[1]));
15980 operands[2] = ix86_tls_get_addr ();
15983 (define_insn "*tls_local_dynamic_base_64"
15984 [(set (match_operand:DI 0 "register_operand" "=a")
15985 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15986 (match_operand:DI 2 "" "")))
15987 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15989 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15990 [(set_attr "type" "multi")
15991 (set_attr "length" "12")])
15993 (define_expand "tls_local_dynamic_base_64"
15994 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15995 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15996 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15999 if (TARGET_GNU2_TLS)
16001 emit_insn (gen_tls_dynamic_gnu2_64
16002 (operands[0], ix86_tls_module_base ()));
16005 operands[1] = ix86_tls_get_addr ();
16008 ;; Local dynamic of a single variable is a lose. Show combine how
16009 ;; to convert that back to global dynamic.
16011 (define_insn_and_split "*tls_local_dynamic_32_once"
16012 [(set (match_operand:SI 0 "register_operand" "=a")
16013 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16014 (match_operand:SI 2 "call_insn_operand" "")]
16015 UNSPEC_TLS_LD_BASE)
16016 (const:SI (unspec:SI
16017 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16019 (clobber (match_scratch:SI 4 "=d"))
16020 (clobber (match_scratch:SI 5 "=c"))
16021 (clobber (reg:CC FLAGS_REG))]
16025 [(parallel [(set (match_dup 0)
16026 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16028 (clobber (match_dup 4))
16029 (clobber (match_dup 5))
16030 (clobber (reg:CC FLAGS_REG))])]
16033 ;; Load and add the thread base pointer from %gs:0.
16035 (define_insn "*load_tp_si"
16036 [(set (match_operand:SI 0 "register_operand" "=r")
16037 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16039 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16040 [(set_attr "type" "imov")
16041 (set_attr "modrm" "0")
16042 (set_attr "length" "7")
16043 (set_attr "memory" "load")
16044 (set_attr "imm_disp" "false")])
16046 (define_insn "*add_tp_si"
16047 [(set (match_operand:SI 0 "register_operand" "=r")
16048 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16049 (match_operand:SI 1 "register_operand" "0")))
16050 (clobber (reg:CC FLAGS_REG))]
16052 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16053 [(set_attr "type" "alu")
16054 (set_attr "modrm" "0")
16055 (set_attr "length" "7")
16056 (set_attr "memory" "load")
16057 (set_attr "imm_disp" "false")])
16059 (define_insn "*load_tp_di"
16060 [(set (match_operand:DI 0 "register_operand" "=r")
16061 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16063 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16064 [(set_attr "type" "imov")
16065 (set_attr "modrm" "0")
16066 (set_attr "length" "7")
16067 (set_attr "memory" "load")
16068 (set_attr "imm_disp" "false")])
16070 (define_insn "*add_tp_di"
16071 [(set (match_operand:DI 0 "register_operand" "=r")
16072 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16073 (match_operand:DI 1 "register_operand" "0")))
16074 (clobber (reg:CC FLAGS_REG))]
16076 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16077 [(set_attr "type" "alu")
16078 (set_attr "modrm" "0")
16079 (set_attr "length" "7")
16080 (set_attr "memory" "load")
16081 (set_attr "imm_disp" "false")])
16083 ;; GNU2 TLS patterns can be split.
16085 (define_expand "tls_dynamic_gnu2_32"
16086 [(set (match_dup 3)
16087 (plus:SI (match_operand:SI 2 "register_operand" "")
16089 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16092 [(set (match_operand:SI 0 "register_operand" "")
16093 (unspec:SI [(match_dup 1) (match_dup 3)
16094 (match_dup 2) (reg:SI SP_REG)]
16096 (clobber (reg:CC FLAGS_REG))])]
16097 "!TARGET_64BIT && TARGET_GNU2_TLS"
16099 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16100 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16103 (define_insn "*tls_dynamic_lea_32"
16104 [(set (match_operand:SI 0 "register_operand" "=r")
16105 (plus:SI (match_operand:SI 1 "register_operand" "b")
16107 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16108 UNSPEC_TLSDESC))))]
16109 "!TARGET_64BIT && TARGET_GNU2_TLS"
16110 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16111 [(set_attr "type" "lea")
16112 (set_attr "mode" "SI")
16113 (set_attr "length" "6")
16114 (set_attr "length_address" "4")])
16116 (define_insn "*tls_dynamic_call_32"
16117 [(set (match_operand:SI 0 "register_operand" "=a")
16118 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16119 (match_operand:SI 2 "register_operand" "0")
16120 ;; we have to make sure %ebx still points to the GOT
16121 (match_operand:SI 3 "register_operand" "b")
16124 (clobber (reg:CC FLAGS_REG))]
16125 "!TARGET_64BIT && TARGET_GNU2_TLS"
16126 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16127 [(set_attr "type" "call")
16128 (set_attr "length" "2")
16129 (set_attr "length_address" "0")])
16131 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16132 [(set (match_operand:SI 0 "register_operand" "=&a")
16134 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16135 (match_operand:SI 4 "" "")
16136 (match_operand:SI 2 "register_operand" "b")
16139 (const:SI (unspec:SI
16140 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16142 (clobber (reg:CC FLAGS_REG))]
16143 "!TARGET_64BIT && TARGET_GNU2_TLS"
16146 [(set (match_dup 0) (match_dup 5))]
16148 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16149 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16152 (define_expand "tls_dynamic_gnu2_64"
16153 [(set (match_dup 2)
16154 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16157 [(set (match_operand:DI 0 "register_operand" "")
16158 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16160 (clobber (reg:CC FLAGS_REG))])]
16161 "TARGET_64BIT && TARGET_GNU2_TLS"
16163 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16167 (define_insn "*tls_dynamic_lea_64"
16168 [(set (match_operand:DI 0 "register_operand" "=r")
16169 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16171 "TARGET_64BIT && TARGET_GNU2_TLS"
16172 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16173 [(set_attr "type" "lea")
16174 (set_attr "mode" "DI")
16175 (set_attr "length" "7")
16176 (set_attr "length_address" "4")])
16178 (define_insn "*tls_dynamic_call_64"
16179 [(set (match_operand:DI 0 "register_operand" "=a")
16180 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16181 (match_operand:DI 2 "register_operand" "0")
16184 (clobber (reg:CC FLAGS_REG))]
16185 "TARGET_64BIT && TARGET_GNU2_TLS"
16186 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16187 [(set_attr "type" "call")
16188 (set_attr "length" "2")
16189 (set_attr "length_address" "0")])
16191 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16192 [(set (match_operand:DI 0 "register_operand" "=&a")
16194 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16195 (match_operand:DI 3 "" "")
16198 (const:DI (unspec:DI
16199 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16201 (clobber (reg:CC FLAGS_REG))]
16202 "TARGET_64BIT && TARGET_GNU2_TLS"
16205 [(set (match_dup 0) (match_dup 4))]
16207 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16208 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16213 ;; These patterns match the binary 387 instructions for addM3, subM3,
16214 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16215 ;; SFmode. The first is the normal insn, the second the same insn but
16216 ;; with one operand a conversion, and the third the same insn but with
16217 ;; the other operand a conversion. The conversion may be SFmode or
16218 ;; SImode if the target mode DFmode, but only SImode if the target mode
16221 ;; Gcc is slightly more smart about handling normal two address instructions
16222 ;; so use special patterns for add and mull.
16224 (define_insn "*fop_<mode>_comm_mixed_avx"
16225 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16226 (match_operator:MODEF 3 "binary_fp_operator"
16227 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16228 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16229 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16230 && COMMUTATIVE_ARITH_P (operands[3])
16231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16232 "* return output_387_binary_op (insn, operands);"
16233 [(set (attr "type")
16234 (if_then_else (eq_attr "alternative" "1")
16235 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16236 (const_string "ssemul")
16237 (const_string "sseadd"))
16238 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16239 (const_string "fmul")
16240 (const_string "fop"))))
16241 (set_attr "prefix" "orig,maybe_vex")
16242 (set_attr "mode" "<MODE>")])
16244 (define_insn "*fop_<mode>_comm_mixed"
16245 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16246 (match_operator:MODEF 3 "binary_fp_operator"
16247 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16248 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16249 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16250 && COMMUTATIVE_ARITH_P (operands[3])
16251 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16252 "* return output_387_binary_op (insn, operands);"
16253 [(set (attr "type")
16254 (if_then_else (eq_attr "alternative" "1")
16255 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16256 (const_string "ssemul")
16257 (const_string "sseadd"))
16258 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16259 (const_string "fmul")
16260 (const_string "fop"))))
16261 (set_attr "mode" "<MODE>")])
16263 (define_insn "*fop_<mode>_comm_avx"
16264 [(set (match_operand:MODEF 0 "register_operand" "=x")
16265 (match_operator:MODEF 3 "binary_fp_operator"
16266 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16268 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16269 && COMMUTATIVE_ARITH_P (operands[3])
16270 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16271 "* return output_387_binary_op (insn, operands);"
16272 [(set (attr "type")
16273 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274 (const_string "ssemul")
16275 (const_string "sseadd")))
16276 (set_attr "prefix" "vex")
16277 (set_attr "mode" "<MODE>")])
16279 (define_insn "*fop_<mode>_comm_sse"
16280 [(set (match_operand:MODEF 0 "register_operand" "=x")
16281 (match_operator:MODEF 3 "binary_fp_operator"
16282 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16283 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16284 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16285 && COMMUTATIVE_ARITH_P (operands[3])
16286 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16287 "* return output_387_binary_op (insn, operands);"
16288 [(set (attr "type")
16289 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16290 (const_string "ssemul")
16291 (const_string "sseadd")))
16292 (set_attr "mode" "<MODE>")])
16294 (define_insn "*fop_<mode>_comm_i387"
16295 [(set (match_operand:MODEF 0 "register_operand" "=f")
16296 (match_operator:MODEF 3 "binary_fp_operator"
16297 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16300 && COMMUTATIVE_ARITH_P (operands[3])
16301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302 "* return output_387_binary_op (insn, operands);"
16303 [(set (attr "type")
16304 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305 (const_string "fmul")
16306 (const_string "fop")))
16307 (set_attr "mode" "<MODE>")])
16309 (define_insn "*fop_<mode>_1_mixed_avx"
16310 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16311 (match_operator:MODEF 3 "binary_fp_operator"
16312 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16313 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16314 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16315 && !COMMUTATIVE_ARITH_P (operands[3])
16316 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317 "* return output_387_binary_op (insn, operands);"
16318 [(set (attr "type")
16319 (cond [(and (eq_attr "alternative" "2")
16320 (match_operand:MODEF 3 "mult_operator" ""))
16321 (const_string "ssemul")
16322 (and (eq_attr "alternative" "2")
16323 (match_operand:MODEF 3 "div_operator" ""))
16324 (const_string "ssediv")
16325 (eq_attr "alternative" "2")
16326 (const_string "sseadd")
16327 (match_operand:MODEF 3 "mult_operator" "")
16328 (const_string "fmul")
16329 (match_operand:MODEF 3 "div_operator" "")
16330 (const_string "fdiv")
16332 (const_string "fop")))
16333 (set_attr "prefix" "orig,orig,maybe_vex")
16334 (set_attr "mode" "<MODE>")])
16336 (define_insn "*fop_<mode>_1_mixed"
16337 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16338 (match_operator:MODEF 3 "binary_fp_operator"
16339 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16340 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16341 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16342 && !COMMUTATIVE_ARITH_P (operands[3])
16343 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16344 "* return output_387_binary_op (insn, operands);"
16345 [(set (attr "type")
16346 (cond [(and (eq_attr "alternative" "2")
16347 (match_operand:MODEF 3 "mult_operator" ""))
16348 (const_string "ssemul")
16349 (and (eq_attr "alternative" "2")
16350 (match_operand:MODEF 3 "div_operator" ""))
16351 (const_string "ssediv")
16352 (eq_attr "alternative" "2")
16353 (const_string "sseadd")
16354 (match_operand:MODEF 3 "mult_operator" "")
16355 (const_string "fmul")
16356 (match_operand:MODEF 3 "div_operator" "")
16357 (const_string "fdiv")
16359 (const_string "fop")))
16360 (set_attr "mode" "<MODE>")])
16362 (define_insn "*rcpsf2_sse"
16363 [(set (match_operand:SF 0 "register_operand" "=x")
16364 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16367 "%vrcpss\t{%1, %d0|%d0, %1}"
16368 [(set_attr "type" "sse")
16369 (set_attr "prefix" "maybe_vex")
16370 (set_attr "mode" "SF")])
16372 (define_insn "*fop_<mode>_1_avx"
16373 [(set (match_operand:MODEF 0 "register_operand" "=x")
16374 (match_operator:MODEF 3 "binary_fp_operator"
16375 [(match_operand:MODEF 1 "register_operand" "x")
16376 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16377 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378 && !COMMUTATIVE_ARITH_P (operands[3])"
16379 "* return output_387_binary_op (insn, operands);"
16380 [(set (attr "type")
16381 (cond [(match_operand:MODEF 3 "mult_operator" "")
16382 (const_string "ssemul")
16383 (match_operand:MODEF 3 "div_operator" "")
16384 (const_string "ssediv")
16386 (const_string "sseadd")))
16387 (set_attr "prefix" "vex")
16388 (set_attr "mode" "<MODE>")])
16390 (define_insn "*fop_<mode>_1_sse"
16391 [(set (match_operand:MODEF 0 "register_operand" "=x")
16392 (match_operator:MODEF 3 "binary_fp_operator"
16393 [(match_operand:MODEF 1 "register_operand" "0")
16394 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16395 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16396 && !COMMUTATIVE_ARITH_P (operands[3])"
16397 "* return output_387_binary_op (insn, operands);"
16398 [(set (attr "type")
16399 (cond [(match_operand:MODEF 3 "mult_operator" "")
16400 (const_string "ssemul")
16401 (match_operand:MODEF 3 "div_operator" "")
16402 (const_string "ssediv")
16404 (const_string "sseadd")))
16405 (set_attr "mode" "<MODE>")])
16407 ;; This pattern is not fully shadowed by the pattern above.
16408 (define_insn "*fop_<mode>_1_i387"
16409 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16410 (match_operator:MODEF 3 "binary_fp_operator"
16411 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16412 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16413 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16414 && !COMMUTATIVE_ARITH_P (operands[3])
16415 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16416 "* return output_387_binary_op (insn, operands);"
16417 [(set (attr "type")
16418 (cond [(match_operand:MODEF 3 "mult_operator" "")
16419 (const_string "fmul")
16420 (match_operand:MODEF 3 "div_operator" "")
16421 (const_string "fdiv")
16423 (const_string "fop")))
16424 (set_attr "mode" "<MODE>")])
16426 ;; ??? Add SSE splitters for these!
16427 (define_insn "*fop_<MODEF:mode>_2_i387"
16428 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429 (match_operator:MODEF 3 "binary_fp_operator"
16431 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16432 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16433 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16434 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436 [(set (attr "type")
16437 (cond [(match_operand:MODEF 3 "mult_operator" "")
16438 (const_string "fmul")
16439 (match_operand:MODEF 3 "div_operator" "")
16440 (const_string "fdiv")
16442 (const_string "fop")))
16443 (set_attr "fp_int_src" "true")
16444 (set_attr "mode" "<X87MODEI12:MODE>")])
16446 (define_insn "*fop_<MODEF:mode>_3_i387"
16447 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16448 (match_operator:MODEF 3 "binary_fp_operator"
16449 [(match_operand:MODEF 1 "register_operand" "0,0")
16451 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16452 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16453 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16454 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16455 [(set (attr "type")
16456 (cond [(match_operand:MODEF 3 "mult_operator" "")
16457 (const_string "fmul")
16458 (match_operand:MODEF 3 "div_operator" "")
16459 (const_string "fdiv")
16461 (const_string "fop")))
16462 (set_attr "fp_int_src" "true")
16463 (set_attr "mode" "<MODE>")])
16465 (define_insn "*fop_df_4_i387"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f")
16467 (match_operator:DF 3 "binary_fp_operator"
16469 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16470 (match_operand:DF 2 "register_operand" "0,f")]))]
16471 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16473 "* return output_387_binary_op (insn, operands);"
16474 [(set (attr "type")
16475 (cond [(match_operand:DF 3 "mult_operator" "")
16476 (const_string "fmul")
16477 (match_operand:DF 3 "div_operator" "")
16478 (const_string "fdiv")
16480 (const_string "fop")))
16481 (set_attr "mode" "SF")])
16483 (define_insn "*fop_df_5_i387"
16484 [(set (match_operand:DF 0 "register_operand" "=f,f")
16485 (match_operator:DF 3 "binary_fp_operator"
16486 [(match_operand:DF 1 "register_operand" "0,f")
16488 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16489 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16490 "* return output_387_binary_op (insn, operands);"
16491 [(set (attr "type")
16492 (cond [(match_operand:DF 3 "mult_operator" "")
16493 (const_string "fmul")
16494 (match_operand:DF 3 "div_operator" "")
16495 (const_string "fdiv")
16497 (const_string "fop")))
16498 (set_attr "mode" "SF")])
16500 (define_insn "*fop_df_6_i387"
16501 [(set (match_operand:DF 0 "register_operand" "=f,f")
16502 (match_operator:DF 3 "binary_fp_operator"
16504 (match_operand:SF 1 "register_operand" "0,f"))
16506 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16507 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16508 "* return output_387_binary_op (insn, operands);"
16509 [(set (attr "type")
16510 (cond [(match_operand:DF 3 "mult_operator" "")
16511 (const_string "fmul")
16512 (match_operand:DF 3 "div_operator" "")
16513 (const_string "fdiv")
16515 (const_string "fop")))
16516 (set_attr "mode" "SF")])
16518 (define_insn "*fop_xf_comm_i387"
16519 [(set (match_operand:XF 0 "register_operand" "=f")
16520 (match_operator:XF 3 "binary_fp_operator"
16521 [(match_operand:XF 1 "register_operand" "%0")
16522 (match_operand:XF 2 "register_operand" "f")]))]
16524 && COMMUTATIVE_ARITH_P (operands[3])"
16525 "* return output_387_binary_op (insn, operands);"
16526 [(set (attr "type")
16527 (if_then_else (match_operand:XF 3 "mult_operator" "")
16528 (const_string "fmul")
16529 (const_string "fop")))
16530 (set_attr "mode" "XF")])
16532 (define_insn "*fop_xf_1_i387"
16533 [(set (match_operand:XF 0 "register_operand" "=f,f")
16534 (match_operator:XF 3 "binary_fp_operator"
16535 [(match_operand:XF 1 "register_operand" "0,f")
16536 (match_operand:XF 2 "register_operand" "f,0")]))]
16538 && !COMMUTATIVE_ARITH_P (operands[3])"
16539 "* return output_387_binary_op (insn, operands);"
16540 [(set (attr "type")
16541 (cond [(match_operand:XF 3 "mult_operator" "")
16542 (const_string "fmul")
16543 (match_operand:XF 3 "div_operator" "")
16544 (const_string "fdiv")
16546 (const_string "fop")))
16547 (set_attr "mode" "XF")])
16549 (define_insn "*fop_xf_2_i387"
16550 [(set (match_operand:XF 0 "register_operand" "=f,f")
16551 (match_operator:XF 3 "binary_fp_operator"
16553 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16554 (match_operand:XF 2 "register_operand" "0,0")]))]
16555 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557 [(set (attr "type")
16558 (cond [(match_operand:XF 3 "mult_operator" "")
16559 (const_string "fmul")
16560 (match_operand:XF 3 "div_operator" "")
16561 (const_string "fdiv")
16563 (const_string "fop")))
16564 (set_attr "fp_int_src" "true")
16565 (set_attr "mode" "<MODE>")])
16567 (define_insn "*fop_xf_3_i387"
16568 [(set (match_operand:XF 0 "register_operand" "=f,f")
16569 (match_operator:XF 3 "binary_fp_operator"
16570 [(match_operand:XF 1 "register_operand" "0,0")
16572 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16573 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16574 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16575 [(set (attr "type")
16576 (cond [(match_operand:XF 3 "mult_operator" "")
16577 (const_string "fmul")
16578 (match_operand:XF 3 "div_operator" "")
16579 (const_string "fdiv")
16581 (const_string "fop")))
16582 (set_attr "fp_int_src" "true")
16583 (set_attr "mode" "<MODE>")])
16585 (define_insn "*fop_xf_4_i387"
16586 [(set (match_operand:XF 0 "register_operand" "=f,f")
16587 (match_operator:XF 3 "binary_fp_operator"
16589 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16590 (match_operand:XF 2 "register_operand" "0,f")]))]
16592 "* return output_387_binary_op (insn, operands);"
16593 [(set (attr "type")
16594 (cond [(match_operand:XF 3 "mult_operator" "")
16595 (const_string "fmul")
16596 (match_operand:XF 3 "div_operator" "")
16597 (const_string "fdiv")
16599 (const_string "fop")))
16600 (set_attr "mode" "<MODE>")])
16602 (define_insn "*fop_xf_5_i387"
16603 [(set (match_operand:XF 0 "register_operand" "=f,f")
16604 (match_operator:XF 3 "binary_fp_operator"
16605 [(match_operand:XF 1 "register_operand" "0,f")
16607 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16609 "* return output_387_binary_op (insn, operands);"
16610 [(set (attr "type")
16611 (cond [(match_operand:XF 3 "mult_operator" "")
16612 (const_string "fmul")
16613 (match_operand:XF 3 "div_operator" "")
16614 (const_string "fdiv")
16616 (const_string "fop")))
16617 (set_attr "mode" "<MODE>")])
16619 (define_insn "*fop_xf_6_i387"
16620 [(set (match_operand:XF 0 "register_operand" "=f,f")
16621 (match_operator:XF 3 "binary_fp_operator"
16623 (match_operand:MODEF 1 "register_operand" "0,f"))
16625 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16627 "* return output_387_binary_op (insn, operands);"
16628 [(set (attr "type")
16629 (cond [(match_operand:XF 3 "mult_operator" "")
16630 (const_string "fmul")
16631 (match_operand:XF 3 "div_operator" "")
16632 (const_string "fdiv")
16634 (const_string "fop")))
16635 (set_attr "mode" "<MODE>")])
16638 [(set (match_operand 0 "register_operand" "")
16639 (match_operator 3 "binary_fp_operator"
16640 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16641 (match_operand 2 "register_operand" "")]))]
16643 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16646 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16647 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16648 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16649 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16650 GET_MODE (operands[3]),
16653 ix86_free_from_memory (GET_MODE (operands[1]));
16658 [(set (match_operand 0 "register_operand" "")
16659 (match_operator 3 "binary_fp_operator"
16660 [(match_operand 1 "register_operand" "")
16661 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16663 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16666 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16667 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16668 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16669 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16670 GET_MODE (operands[3]),
16673 ix86_free_from_memory (GET_MODE (operands[2]));
16677 ;; FPU special functions.
16679 ;; This pattern implements a no-op XFmode truncation for
16680 ;; all fancy i386 XFmode math functions.
16682 (define_insn "truncxf<mode>2_i387_noop_unspec"
16683 [(set (match_operand:MODEF 0 "register_operand" "=f")
16684 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16685 UNSPEC_TRUNC_NOOP))]
16686 "TARGET_USE_FANCY_MATH_387"
16687 "* return output_387_reg_move (insn, operands);"
16688 [(set_attr "type" "fmov")
16689 (set_attr "mode" "<MODE>")])
16691 (define_insn "sqrtxf2"
16692 [(set (match_operand:XF 0 "register_operand" "=f")
16693 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16694 "TARGET_USE_FANCY_MATH_387"
16696 [(set_attr "type" "fpspc")
16697 (set_attr "mode" "XF")
16698 (set_attr "athlon_decode" "direct")
16699 (set_attr "amdfam10_decode" "direct")])
16701 (define_insn "sqrt_extend<mode>xf2_i387"
16702 [(set (match_operand:XF 0 "register_operand" "=f")
16705 (match_operand:MODEF 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 "*rsqrtsf2_sse"
16714 [(set (match_operand:SF 0 "register_operand" "=x")
16715 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16718 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16719 [(set_attr "type" "sse")
16720 (set_attr "prefix" "maybe_vex")
16721 (set_attr "mode" "SF")])
16723 (define_expand "rsqrtsf2"
16724 [(set (match_operand:SF 0 "register_operand" "")
16725 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16729 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16733 (define_insn "*sqrt<mode>2_sse"
16734 [(set (match_operand:MODEF 0 "register_operand" "=x")
16736 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16737 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16738 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16739 [(set_attr "type" "sse")
16740 (set_attr "prefix" "maybe_vex")
16741 (set_attr "mode" "<MODE>")
16742 (set_attr "athlon_decode" "*")
16743 (set_attr "amdfam10_decode" "*")])
16745 (define_expand "sqrt<mode>2"
16746 [(set (match_operand:MODEF 0 "register_operand" "")
16748 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16749 "TARGET_USE_FANCY_MATH_387
16750 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16752 if (<MODE>mode == SFmode
16753 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16754 && flag_finite_math_only && !flag_trapping_math
16755 && flag_unsafe_math_optimizations)
16757 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16761 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16763 rtx op0 = gen_reg_rtx (XFmode);
16764 rtx op1 = force_reg (<MODE>mode, operands[1]);
16766 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16767 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16772 (define_insn "fpremxf4_i387"
16773 [(set (match_operand:XF 0 "register_operand" "=f")
16774 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16775 (match_operand:XF 3 "register_operand" "1")]
16777 (set (match_operand:XF 1 "register_operand" "=u")
16778 (unspec:XF [(match_dup 2) (match_dup 3)]
16780 (set (reg:CCFP FPSR_REG)
16781 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16783 "TARGET_USE_FANCY_MATH_387"
16785 [(set_attr "type" "fpspc")
16786 (set_attr "mode" "XF")])
16788 (define_expand "fmodxf3"
16789 [(use (match_operand:XF 0 "register_operand" ""))
16790 (use (match_operand:XF 1 "general_operand" ""))
16791 (use (match_operand:XF 2 "general_operand" ""))]
16792 "TARGET_USE_FANCY_MATH_387"
16794 rtx label = gen_label_rtx ();
16796 rtx op1 = gen_reg_rtx (XFmode);
16797 rtx op2 = gen_reg_rtx (XFmode);
16799 emit_move_insn (op2, operands[2]);
16800 emit_move_insn (op1, operands[1]);
16802 emit_label (label);
16803 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16804 ix86_emit_fp_unordered_jump (label);
16805 LABEL_NUSES (label) = 1;
16807 emit_move_insn (operands[0], op1);
16811 (define_expand "fmod<mode>3"
16812 [(use (match_operand:MODEF 0 "register_operand" ""))
16813 (use (match_operand:MODEF 1 "general_operand" ""))
16814 (use (match_operand:MODEF 2 "general_operand" ""))]
16815 "TARGET_USE_FANCY_MATH_387"
16817 rtx label = gen_label_rtx ();
16819 rtx op1 = gen_reg_rtx (XFmode);
16820 rtx op2 = gen_reg_rtx (XFmode);
16822 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16823 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16825 emit_label (label);
16826 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16827 ix86_emit_fp_unordered_jump (label);
16828 LABEL_NUSES (label) = 1;
16830 /* Truncate the result properly for strict SSE math. */
16831 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16832 && !TARGET_MIX_SSE_I387)
16833 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16835 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16840 (define_insn "fprem1xf4_i387"
16841 [(set (match_operand:XF 0 "register_operand" "=f")
16842 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16843 (match_operand:XF 3 "register_operand" "1")]
16845 (set (match_operand:XF 1 "register_operand" "=u")
16846 (unspec:XF [(match_dup 2) (match_dup 3)]
16848 (set (reg:CCFP FPSR_REG)
16849 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16851 "TARGET_USE_FANCY_MATH_387"
16853 [(set_attr "type" "fpspc")
16854 (set_attr "mode" "XF")])
16856 (define_expand "remainderxf3"
16857 [(use (match_operand:XF 0 "register_operand" ""))
16858 (use (match_operand:XF 1 "general_operand" ""))
16859 (use (match_operand:XF 2 "general_operand" ""))]
16860 "TARGET_USE_FANCY_MATH_387"
16862 rtx label = gen_label_rtx ();
16864 rtx op1 = gen_reg_rtx (XFmode);
16865 rtx op2 = gen_reg_rtx (XFmode);
16867 emit_move_insn (op2, operands[2]);
16868 emit_move_insn (op1, operands[1]);
16870 emit_label (label);
16871 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16872 ix86_emit_fp_unordered_jump (label);
16873 LABEL_NUSES (label) = 1;
16875 emit_move_insn (operands[0], op1);
16879 (define_expand "remainder<mode>3"
16880 [(use (match_operand:MODEF 0 "register_operand" ""))
16881 (use (match_operand:MODEF 1 "general_operand" ""))
16882 (use (match_operand:MODEF 2 "general_operand" ""))]
16883 "TARGET_USE_FANCY_MATH_387"
16885 rtx label = gen_label_rtx ();
16887 rtx op1 = gen_reg_rtx (XFmode);
16888 rtx op2 = gen_reg_rtx (XFmode);
16890 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16891 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16893 emit_label (label);
16895 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16896 ix86_emit_fp_unordered_jump (label);
16897 LABEL_NUSES (label) = 1;
16899 /* Truncate the result properly for strict SSE math. */
16900 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16901 && !TARGET_MIX_SSE_I387)
16902 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16904 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16909 (define_insn "*sinxf2_i387"
16910 [(set (match_operand:XF 0 "register_operand" "=f")
16911 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && flag_unsafe_math_optimizations"
16915 [(set_attr "type" "fpspc")
16916 (set_attr "mode" "XF")])
16918 (define_insn "*sin_extend<mode>xf2_i387"
16919 [(set (match_operand:XF 0 "register_operand" "=f")
16920 (unspec:XF [(float_extend:XF
16921 (match_operand:MODEF 1 "register_operand" "0"))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations"
16928 [(set_attr "type" "fpspc")
16929 (set_attr "mode" "XF")])
16931 (define_insn "*cosxf2_i387"
16932 [(set (match_operand:XF 0 "register_operand" "=f")
16933 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16934 "TARGET_USE_FANCY_MATH_387
16935 && flag_unsafe_math_optimizations"
16937 [(set_attr "type" "fpspc")
16938 (set_attr "mode" "XF")])
16940 (define_insn "*cos_extend<mode>xf2_i387"
16941 [(set (match_operand:XF 0 "register_operand" "=f")
16942 (unspec:XF [(float_extend:XF
16943 (match_operand:MODEF 1 "register_operand" "0"))]
16945 "TARGET_USE_FANCY_MATH_387
16946 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16947 || TARGET_MIX_SSE_I387)
16948 && flag_unsafe_math_optimizations"
16950 [(set_attr "type" "fpspc")
16951 (set_attr "mode" "XF")])
16953 ;; When sincos pattern is defined, sin and cos builtin functions will be
16954 ;; expanded to sincos pattern with one of its outputs left unused.
16955 ;; CSE pass will figure out if two sincos patterns can be combined,
16956 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16957 ;; depending on the unused output.
16959 (define_insn "sincosxf3"
16960 [(set (match_operand:XF 0 "register_operand" "=f")
16961 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16962 UNSPEC_SINCOS_COS))
16963 (set (match_operand:XF 1 "register_operand" "=u")
16964 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations"
16968 [(set_attr "type" "fpspc")
16969 (set_attr "mode" "XF")])
16972 [(set (match_operand:XF 0 "register_operand" "")
16973 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16974 UNSPEC_SINCOS_COS))
16975 (set (match_operand:XF 1 "register_operand" "")
16976 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16977 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16978 && !(reload_completed || reload_in_progress)"
16979 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16983 [(set (match_operand:XF 0 "register_operand" "")
16984 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16985 UNSPEC_SINCOS_COS))
16986 (set (match_operand:XF 1 "register_operand" "")
16987 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16988 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16989 && !(reload_completed || reload_in_progress)"
16990 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16993 (define_insn "sincos_extend<mode>xf3_i387"
16994 [(set (match_operand:XF 0 "register_operand" "=f")
16995 (unspec:XF [(float_extend:XF
16996 (match_operand:MODEF 2 "register_operand" "0"))]
16997 UNSPEC_SINCOS_COS))
16998 (set (match_operand:XF 1 "register_operand" "=u")
16999 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17000 "TARGET_USE_FANCY_MATH_387
17001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17002 || TARGET_MIX_SSE_I387)
17003 && flag_unsafe_math_optimizations"
17005 [(set_attr "type" "fpspc")
17006 (set_attr "mode" "XF")])
17009 [(set (match_operand:XF 0 "register_operand" "")
17010 (unspec:XF [(float_extend:XF
17011 (match_operand:MODEF 2 "register_operand" ""))]
17012 UNSPEC_SINCOS_COS))
17013 (set (match_operand:XF 1 "register_operand" "")
17014 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17016 && !(reload_completed || reload_in_progress)"
17017 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
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[1]))
17028 && !(reload_completed || reload_in_progress)"
17029 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17032 (define_expand "sincos<mode>3"
17033 [(use (match_operand:MODEF 0 "register_operand" ""))
17034 (use (match_operand:MODEF 1 "register_operand" ""))
17035 (use (match_operand:MODEF 2 "register_operand" ""))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038 || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations"
17041 rtx op0 = gen_reg_rtx (XFmode);
17042 rtx op1 = gen_reg_rtx (XFmode);
17044 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17045 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17050 (define_insn "fptanxf4_i387"
17051 [(set (match_operand:XF 0 "register_operand" "=f")
17052 (match_operand:XF 3 "const_double_operand" "F"))
17053 (set (match_operand:XF 1 "register_operand" "=u")
17054 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations
17058 && standard_80387_constant_p (operands[3]) == 2"
17060 [(set_attr "type" "fpspc")
17061 (set_attr "mode" "XF")])
17063 (define_insn "fptan_extend<mode>xf4_i387"
17064 [(set (match_operand:MODEF 0 "register_operand" "=f")
17065 (match_operand:MODEF 3 "const_double_operand" "F"))
17066 (set (match_operand:XF 1 "register_operand" "=u")
17067 (unspec:XF [(float_extend:XF
17068 (match_operand:MODEF 2 "register_operand" "0"))]
17070 "TARGET_USE_FANCY_MATH_387
17071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17072 || TARGET_MIX_SSE_I387)
17073 && flag_unsafe_math_optimizations
17074 && standard_80387_constant_p (operands[3]) == 2"
17076 [(set_attr "type" "fpspc")
17077 (set_attr "mode" "XF")])
17079 (define_expand "tanxf2"
17080 [(use (match_operand:XF 0 "register_operand" ""))
17081 (use (match_operand:XF 1 "register_operand" ""))]
17082 "TARGET_USE_FANCY_MATH_387
17083 && flag_unsafe_math_optimizations"
17085 rtx one = gen_reg_rtx (XFmode);
17086 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17088 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17092 (define_expand "tan<mode>2"
17093 [(use (match_operand:MODEF 0 "register_operand" ""))
17094 (use (match_operand:MODEF 1 "register_operand" ""))]
17095 "TARGET_USE_FANCY_MATH_387
17096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17097 || TARGET_MIX_SSE_I387)
17098 && flag_unsafe_math_optimizations"
17100 rtx op0 = gen_reg_rtx (XFmode);
17102 rtx one = gen_reg_rtx (<MODE>mode);
17103 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17105 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17106 operands[1], op2));
17107 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17111 (define_insn "*fpatanxf3_i387"
17112 [(set (match_operand:XF 0 "register_operand" "=f")
17113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17114 (match_operand:XF 2 "register_operand" "u")]
17116 (clobber (match_scratch:XF 3 "=2"))]
17117 "TARGET_USE_FANCY_MATH_387
17118 && flag_unsafe_math_optimizations"
17120 [(set_attr "type" "fpspc")
17121 (set_attr "mode" "XF")])
17123 (define_insn "fpatan_extend<mode>xf3_i387"
17124 [(set (match_operand:XF 0 "register_operand" "=f")
17125 (unspec:XF [(float_extend:XF
17126 (match_operand:MODEF 1 "register_operand" "0"))
17128 (match_operand:MODEF 2 "register_operand" "u"))]
17130 (clobber (match_scratch:XF 3 "=2"))]
17131 "TARGET_USE_FANCY_MATH_387
17132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17133 || TARGET_MIX_SSE_I387)
17134 && flag_unsafe_math_optimizations"
17136 [(set_attr "type" "fpspc")
17137 (set_attr "mode" "XF")])
17139 (define_expand "atan2xf3"
17140 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17141 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17142 (match_operand:XF 1 "register_operand" "")]
17144 (clobber (match_scratch:XF 3 ""))])]
17145 "TARGET_USE_FANCY_MATH_387
17146 && flag_unsafe_math_optimizations"
17149 (define_expand "atan2<mode>3"
17150 [(use (match_operand:MODEF 0 "register_operand" ""))
17151 (use (match_operand:MODEF 1 "register_operand" ""))
17152 (use (match_operand:MODEF 2 "register_operand" ""))]
17153 "TARGET_USE_FANCY_MATH_387
17154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17155 || TARGET_MIX_SSE_I387)
17156 && flag_unsafe_math_optimizations"
17158 rtx op0 = gen_reg_rtx (XFmode);
17160 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17165 (define_expand "atanxf2"
17166 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17167 (unspec:XF [(match_dup 2)
17168 (match_operand:XF 1 "register_operand" "")]
17170 (clobber (match_scratch:XF 3 ""))])]
17171 "TARGET_USE_FANCY_MATH_387
17172 && flag_unsafe_math_optimizations"
17174 operands[2] = gen_reg_rtx (XFmode);
17175 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17178 (define_expand "atan<mode>2"
17179 [(use (match_operand:MODEF 0 "register_operand" ""))
17180 (use (match_operand:MODEF 1 "register_operand" ""))]
17181 "TARGET_USE_FANCY_MATH_387
17182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183 || TARGET_MIX_SSE_I387)
17184 && flag_unsafe_math_optimizations"
17186 rtx op0 = gen_reg_rtx (XFmode);
17188 rtx op2 = gen_reg_rtx (<MODE>mode);
17189 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17191 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17192 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17196 (define_expand "asinxf2"
17197 [(set (match_dup 2)
17198 (mult:XF (match_operand:XF 1 "register_operand" "")
17200 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17201 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17202 (parallel [(set (match_operand:XF 0 "register_operand" "")
17203 (unspec:XF [(match_dup 5) (match_dup 1)]
17205 (clobber (match_scratch:XF 6 ""))])]
17206 "TARGET_USE_FANCY_MATH_387
17207 && flag_unsafe_math_optimizations"
17211 if (optimize_insn_for_size_p ())
17214 for (i = 2; i < 6; i++)
17215 operands[i] = gen_reg_rtx (XFmode);
17217 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17220 (define_expand "asin<mode>2"
17221 [(use (match_operand:MODEF 0 "register_operand" ""))
17222 (use (match_operand:MODEF 1 "general_operand" ""))]
17223 "TARGET_USE_FANCY_MATH_387
17224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17225 || TARGET_MIX_SSE_I387)
17226 && flag_unsafe_math_optimizations"
17228 rtx op0 = gen_reg_rtx (XFmode);
17229 rtx op1 = gen_reg_rtx (XFmode);
17231 if (optimize_insn_for_size_p ())
17234 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17235 emit_insn (gen_asinxf2 (op0, op1));
17236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17240 (define_expand "acosxf2"
17241 [(set (match_dup 2)
17242 (mult:XF (match_operand:XF 1 "register_operand" "")
17244 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17245 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17246 (parallel [(set (match_operand:XF 0 "register_operand" "")
17247 (unspec:XF [(match_dup 1) (match_dup 5)]
17249 (clobber (match_scratch:XF 6 ""))])]
17250 "TARGET_USE_FANCY_MATH_387
17251 && flag_unsafe_math_optimizations"
17255 if (optimize_insn_for_size_p ())
17258 for (i = 2; i < 6; i++)
17259 operands[i] = gen_reg_rtx (XFmode);
17261 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17264 (define_expand "acos<mode>2"
17265 [(use (match_operand:MODEF 0 "register_operand" ""))
17266 (use (match_operand:MODEF 1 "general_operand" ""))]
17267 "TARGET_USE_FANCY_MATH_387
17268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17269 || TARGET_MIX_SSE_I387)
17270 && flag_unsafe_math_optimizations"
17272 rtx op0 = gen_reg_rtx (XFmode);
17273 rtx op1 = gen_reg_rtx (XFmode);
17275 if (optimize_insn_for_size_p ())
17278 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17279 emit_insn (gen_acosxf2 (op0, op1));
17280 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17284 (define_insn "fyl2xxf3_i387"
17285 [(set (match_operand:XF 0 "register_operand" "=f")
17286 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17287 (match_operand:XF 2 "register_operand" "u")]
17289 (clobber (match_scratch:XF 3 "=2"))]
17290 "TARGET_USE_FANCY_MATH_387
17291 && flag_unsafe_math_optimizations"
17293 [(set_attr "type" "fpspc")
17294 (set_attr "mode" "XF")])
17296 (define_insn "fyl2x_extend<mode>xf3_i387"
17297 [(set (match_operand:XF 0 "register_operand" "=f")
17298 (unspec:XF [(float_extend:XF
17299 (match_operand:MODEF 1 "register_operand" "0"))
17300 (match_operand:XF 2 "register_operand" "u")]
17302 (clobber (match_scratch:XF 3 "=2"))]
17303 "TARGET_USE_FANCY_MATH_387
17304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17305 || TARGET_MIX_SSE_I387)
17306 && flag_unsafe_math_optimizations"
17308 [(set_attr "type" "fpspc")
17309 (set_attr "mode" "XF")])
17311 (define_expand "logxf2"
17312 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17313 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17314 (match_dup 2)] UNSPEC_FYL2X))
17315 (clobber (match_scratch:XF 3 ""))])]
17316 "TARGET_USE_FANCY_MATH_387
17317 && flag_unsafe_math_optimizations"
17319 operands[2] = gen_reg_rtx (XFmode);
17320 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17323 (define_expand "log<mode>2"
17324 [(use (match_operand:MODEF 0 "register_operand" ""))
17325 (use (match_operand:MODEF 1 "register_operand" ""))]
17326 "TARGET_USE_FANCY_MATH_387
17327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17328 || TARGET_MIX_SSE_I387)
17329 && flag_unsafe_math_optimizations"
17331 rtx op0 = gen_reg_rtx (XFmode);
17333 rtx op2 = gen_reg_rtx (XFmode);
17334 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17336 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341 (define_expand "log10xf2"
17342 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17343 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17344 (match_dup 2)] UNSPEC_FYL2X))
17345 (clobber (match_scratch:XF 3 ""))])]
17346 "TARGET_USE_FANCY_MATH_387
17347 && flag_unsafe_math_optimizations"
17349 operands[2] = gen_reg_rtx (XFmode);
17350 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17353 (define_expand "log10<mode>2"
17354 [(use (match_operand:MODEF 0 "register_operand" ""))
17355 (use (match_operand:MODEF 1 "register_operand" ""))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17358 || TARGET_MIX_SSE_I387)
17359 && flag_unsafe_math_optimizations"
17361 rtx op0 = gen_reg_rtx (XFmode);
17363 rtx op2 = gen_reg_rtx (XFmode);
17364 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17366 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17367 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17371 (define_expand "log2xf2"
17372 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17373 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17374 (match_dup 2)] UNSPEC_FYL2X))
17375 (clobber (match_scratch:XF 3 ""))])]
17376 "TARGET_USE_FANCY_MATH_387
17377 && flag_unsafe_math_optimizations"
17379 operands[2] = gen_reg_rtx (XFmode);
17380 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17383 (define_expand "log2<mode>2"
17384 [(use (match_operand:MODEF 0 "register_operand" ""))
17385 (use (match_operand:MODEF 1 "register_operand" ""))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388 || TARGET_MIX_SSE_I387)
17389 && flag_unsafe_math_optimizations"
17391 rtx op0 = gen_reg_rtx (XFmode);
17393 rtx op2 = gen_reg_rtx (XFmode);
17394 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17396 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17401 (define_insn "fyl2xp1xf3_i387"
17402 [(set (match_operand:XF 0 "register_operand" "=f")
17403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17404 (match_operand:XF 2 "register_operand" "u")]
17406 (clobber (match_scratch:XF 3 "=2"))]
17407 "TARGET_USE_FANCY_MATH_387
17408 && flag_unsafe_math_optimizations"
17410 [(set_attr "type" "fpspc")
17411 (set_attr "mode" "XF")])
17413 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17414 [(set (match_operand:XF 0 "register_operand" "=f")
17415 (unspec:XF [(float_extend:XF
17416 (match_operand:MODEF 1 "register_operand" "0"))
17417 (match_operand:XF 2 "register_operand" "u")]
17419 (clobber (match_scratch:XF 3 "=2"))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17422 || TARGET_MIX_SSE_I387)
17423 && flag_unsafe_math_optimizations"
17425 [(set_attr "type" "fpspc")
17426 (set_attr "mode" "XF")])
17428 (define_expand "log1pxf2"
17429 [(use (match_operand:XF 0 "register_operand" ""))
17430 (use (match_operand:XF 1 "register_operand" ""))]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations"
17434 if (optimize_insn_for_size_p ())
17437 ix86_emit_i387_log1p (operands[0], operands[1]);
17441 (define_expand "log1p<mode>2"
17442 [(use (match_operand:MODEF 0 "register_operand" ""))
17443 (use (match_operand:MODEF 1 "register_operand" ""))]
17444 "TARGET_USE_FANCY_MATH_387
17445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17446 || TARGET_MIX_SSE_I387)
17447 && flag_unsafe_math_optimizations"
17451 if (optimize_insn_for_size_p ())
17454 op0 = gen_reg_rtx (XFmode);
17456 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17458 ix86_emit_i387_log1p (op0, operands[1]);
17459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17463 (define_insn "fxtractxf3_i387"
17464 [(set (match_operand:XF 0 "register_operand" "=f")
17465 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17466 UNSPEC_XTRACT_FRACT))
17467 (set (match_operand:XF 1 "register_operand" "=u")
17468 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17469 "TARGET_USE_FANCY_MATH_387
17470 && flag_unsafe_math_optimizations"
17472 [(set_attr "type" "fpspc")
17473 (set_attr "mode" "XF")])
17475 (define_insn "fxtract_extend<mode>xf3_i387"
17476 [(set (match_operand:XF 0 "register_operand" "=f")
17477 (unspec:XF [(float_extend:XF
17478 (match_operand:MODEF 2 "register_operand" "0"))]
17479 UNSPEC_XTRACT_FRACT))
17480 (set (match_operand:XF 1 "register_operand" "=u")
17481 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17482 "TARGET_USE_FANCY_MATH_387
17483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17484 || TARGET_MIX_SSE_I387)
17485 && flag_unsafe_math_optimizations"
17487 [(set_attr "type" "fpspc")
17488 (set_attr "mode" "XF")])
17490 (define_expand "logbxf2"
17491 [(parallel [(set (match_dup 2)
17492 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17493 UNSPEC_XTRACT_FRACT))
17494 (set (match_operand:XF 0 "register_operand" "")
17495 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17496 "TARGET_USE_FANCY_MATH_387
17497 && flag_unsafe_math_optimizations"
17499 operands[2] = gen_reg_rtx (XFmode);
17502 (define_expand "logb<mode>2"
17503 [(use (match_operand:MODEF 0 "register_operand" ""))
17504 (use (match_operand:MODEF 1 "register_operand" ""))]
17505 "TARGET_USE_FANCY_MATH_387
17506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17507 || TARGET_MIX_SSE_I387)
17508 && flag_unsafe_math_optimizations"
17510 rtx op0 = gen_reg_rtx (XFmode);
17511 rtx op1 = gen_reg_rtx (XFmode);
17513 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17518 (define_expand "ilogbxf2"
17519 [(use (match_operand:SI 0 "register_operand" ""))
17520 (use (match_operand:XF 1 "register_operand" ""))]
17521 "TARGET_USE_FANCY_MATH_387
17522 && flag_unsafe_math_optimizations"
17526 if (optimize_insn_for_size_p ())
17529 op0 = gen_reg_rtx (XFmode);
17530 op1 = gen_reg_rtx (XFmode);
17532 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17533 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17537 (define_expand "ilogb<mode>2"
17538 [(use (match_operand:SI 0 "register_operand" ""))
17539 (use (match_operand:MODEF 1 "register_operand" ""))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17542 || TARGET_MIX_SSE_I387)
17543 && flag_unsafe_math_optimizations"
17547 if (optimize_insn_for_size_p ())
17550 op0 = gen_reg_rtx (XFmode);
17551 op1 = gen_reg_rtx (XFmode);
17553 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17554 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17558 (define_insn "*f2xm1xf2_i387"
17559 [(set (match_operand:XF 0 "register_operand" "=f")
17560 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17562 "TARGET_USE_FANCY_MATH_387
17563 && flag_unsafe_math_optimizations"
17565 [(set_attr "type" "fpspc")
17566 (set_attr "mode" "XF")])
17568 (define_insn "*fscalexf4_i387"
17569 [(set (match_operand:XF 0 "register_operand" "=f")
17570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17571 (match_operand:XF 3 "register_operand" "1")]
17572 UNSPEC_FSCALE_FRACT))
17573 (set (match_operand:XF 1 "register_operand" "=u")
17574 (unspec:XF [(match_dup 2) (match_dup 3)]
17575 UNSPEC_FSCALE_EXP))]
17576 "TARGET_USE_FANCY_MATH_387
17577 && flag_unsafe_math_optimizations"
17579 [(set_attr "type" "fpspc")
17580 (set_attr "mode" "XF")])
17582 (define_expand "expNcorexf3"
17583 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17584 (match_operand:XF 2 "register_operand" "")))
17585 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17586 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17587 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17588 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17589 (parallel [(set (match_operand:XF 0 "register_operand" "")
17590 (unspec:XF [(match_dup 8) (match_dup 4)]
17591 UNSPEC_FSCALE_FRACT))
17593 (unspec:XF [(match_dup 8) (match_dup 4)]
17594 UNSPEC_FSCALE_EXP))])]
17595 "TARGET_USE_FANCY_MATH_387
17596 && flag_unsafe_math_optimizations"
17600 if (optimize_insn_for_size_p ())
17603 for (i = 3; i < 10; i++)
17604 operands[i] = gen_reg_rtx (XFmode);
17606 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17609 (define_expand "expxf2"
17610 [(use (match_operand:XF 0 "register_operand" ""))
17611 (use (match_operand:XF 1 "register_operand" ""))]
17612 "TARGET_USE_FANCY_MATH_387
17613 && flag_unsafe_math_optimizations"
17617 if (optimize_insn_for_size_p ())
17620 op2 = gen_reg_rtx (XFmode);
17621 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17623 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17627 (define_expand "exp<mode>2"
17628 [(use (match_operand:MODEF 0 "register_operand" ""))
17629 (use (match_operand:MODEF 1 "general_operand" ""))]
17630 "TARGET_USE_FANCY_MATH_387
17631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17632 || TARGET_MIX_SSE_I387)
17633 && flag_unsafe_math_optimizations"
17637 if (optimize_insn_for_size_p ())
17640 op0 = gen_reg_rtx (XFmode);
17641 op1 = gen_reg_rtx (XFmode);
17643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17644 emit_insn (gen_expxf2 (op0, op1));
17645 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17649 (define_expand "exp10xf2"
17650 [(use (match_operand:XF 0 "register_operand" ""))
17651 (use (match_operand:XF 1 "register_operand" ""))]
17652 "TARGET_USE_FANCY_MATH_387
17653 && flag_unsafe_math_optimizations"
17657 if (optimize_insn_for_size_p ())
17660 op2 = gen_reg_rtx (XFmode);
17661 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17663 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17667 (define_expand "exp10<mode>2"
17668 [(use (match_operand:MODEF 0 "register_operand" ""))
17669 (use (match_operand:MODEF 1 "general_operand" ""))]
17670 "TARGET_USE_FANCY_MATH_387
17671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17672 || TARGET_MIX_SSE_I387)
17673 && flag_unsafe_math_optimizations"
17677 if (optimize_insn_for_size_p ())
17680 op0 = gen_reg_rtx (XFmode);
17681 op1 = gen_reg_rtx (XFmode);
17683 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17684 emit_insn (gen_exp10xf2 (op0, op1));
17685 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17689 (define_expand "exp2xf2"
17690 [(use (match_operand:XF 0 "register_operand" ""))
17691 (use (match_operand:XF 1 "register_operand" ""))]
17692 "TARGET_USE_FANCY_MATH_387
17693 && flag_unsafe_math_optimizations"
17697 if (optimize_insn_for_size_p ())
17700 op2 = gen_reg_rtx (XFmode);
17701 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17703 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17707 (define_expand "exp2<mode>2"
17708 [(use (match_operand:MODEF 0 "register_operand" ""))
17709 (use (match_operand:MODEF 1 "general_operand" ""))]
17710 "TARGET_USE_FANCY_MATH_387
17711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17712 || TARGET_MIX_SSE_I387)
17713 && flag_unsafe_math_optimizations"
17717 if (optimize_insn_for_size_p ())
17720 op0 = gen_reg_rtx (XFmode);
17721 op1 = gen_reg_rtx (XFmode);
17723 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17724 emit_insn (gen_exp2xf2 (op0, op1));
17725 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17729 (define_expand "expm1xf2"
17730 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17732 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17733 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17734 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17735 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17736 (parallel [(set (match_dup 7)
17737 (unspec:XF [(match_dup 6) (match_dup 4)]
17738 UNSPEC_FSCALE_FRACT))
17740 (unspec:XF [(match_dup 6) (match_dup 4)]
17741 UNSPEC_FSCALE_EXP))])
17742 (parallel [(set (match_dup 10)
17743 (unspec:XF [(match_dup 9) (match_dup 8)]
17744 UNSPEC_FSCALE_FRACT))
17745 (set (match_dup 11)
17746 (unspec:XF [(match_dup 9) (match_dup 8)]
17747 UNSPEC_FSCALE_EXP))])
17748 (set (match_dup 12) (minus:XF (match_dup 10)
17749 (float_extend:XF (match_dup 13))))
17750 (set (match_operand:XF 0 "register_operand" "")
17751 (plus:XF (match_dup 12) (match_dup 7)))]
17752 "TARGET_USE_FANCY_MATH_387
17753 && flag_unsafe_math_optimizations"
17757 if (optimize_insn_for_size_p ())
17760 for (i = 2; i < 13; i++)
17761 operands[i] = gen_reg_rtx (XFmode);
17764 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17766 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17769 (define_expand "expm1<mode>2"
17770 [(use (match_operand:MODEF 0 "register_operand" ""))
17771 (use (match_operand:MODEF 1 "general_operand" ""))]
17772 "TARGET_USE_FANCY_MATH_387
17773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774 || TARGET_MIX_SSE_I387)
17775 && flag_unsafe_math_optimizations"
17779 if (optimize_insn_for_size_p ())
17782 op0 = gen_reg_rtx (XFmode);
17783 op1 = gen_reg_rtx (XFmode);
17785 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17786 emit_insn (gen_expm1xf2 (op0, op1));
17787 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17791 (define_expand "ldexpxf3"
17792 [(set (match_dup 3)
17793 (float:XF (match_operand:SI 2 "register_operand" "")))
17794 (parallel [(set (match_operand:XF 0 " register_operand" "")
17795 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17797 UNSPEC_FSCALE_FRACT))
17799 (unspec:XF [(match_dup 1) (match_dup 3)]
17800 UNSPEC_FSCALE_EXP))])]
17801 "TARGET_USE_FANCY_MATH_387
17802 && flag_unsafe_math_optimizations"
17804 if (optimize_insn_for_size_p ())
17807 operands[3] = gen_reg_rtx (XFmode);
17808 operands[4] = gen_reg_rtx (XFmode);
17811 (define_expand "ldexp<mode>3"
17812 [(use (match_operand:MODEF 0 "register_operand" ""))
17813 (use (match_operand:MODEF 1 "general_operand" ""))
17814 (use (match_operand:SI 2 "register_operand" ""))]
17815 "TARGET_USE_FANCY_MATH_387
17816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17817 || TARGET_MIX_SSE_I387)
17818 && flag_unsafe_math_optimizations"
17822 if (optimize_insn_for_size_p ())
17825 op0 = gen_reg_rtx (XFmode);
17826 op1 = gen_reg_rtx (XFmode);
17828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17829 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17830 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17834 (define_expand "scalbxf3"
17835 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17836 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17837 (match_operand:XF 2 "register_operand" "")]
17838 UNSPEC_FSCALE_FRACT))
17840 (unspec:XF [(match_dup 1) (match_dup 2)]
17841 UNSPEC_FSCALE_EXP))])]
17842 "TARGET_USE_FANCY_MATH_387
17843 && flag_unsafe_math_optimizations"
17845 if (optimize_insn_for_size_p ())
17848 operands[3] = gen_reg_rtx (XFmode);
17851 (define_expand "scalb<mode>3"
17852 [(use (match_operand:MODEF 0 "register_operand" ""))
17853 (use (match_operand:MODEF 1 "general_operand" ""))
17854 (use (match_operand:MODEF 2 "register_operand" ""))]
17855 "TARGET_USE_FANCY_MATH_387
17856 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17857 || TARGET_MIX_SSE_I387)
17858 && flag_unsafe_math_optimizations"
17862 if (optimize_insn_for_size_p ())
17865 op0 = gen_reg_rtx (XFmode);
17866 op1 = gen_reg_rtx (XFmode);
17867 op2 = gen_reg_rtx (XFmode);
17869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17870 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17871 emit_insn (gen_scalbxf3 (op0, op1, op2));
17872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17877 (define_insn "sse4_1_round<mode>2"
17878 [(set (match_operand:MODEF 0 "register_operand" "=x")
17879 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17880 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17883 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17884 [(set_attr "type" "ssecvt")
17885 (set_attr "prefix_extra" "1")
17886 (set_attr "prefix" "maybe_vex")
17887 (set_attr "mode" "<MODE>")])
17889 (define_insn "rintxf2"
17890 [(set (match_operand:XF 0 "register_operand" "=f")
17891 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17893 "TARGET_USE_FANCY_MATH_387
17894 && flag_unsafe_math_optimizations"
17896 [(set_attr "type" "fpspc")
17897 (set_attr "mode" "XF")])
17899 (define_expand "rint<mode>2"
17900 [(use (match_operand:MODEF 0 "register_operand" ""))
17901 (use (match_operand:MODEF 1 "register_operand" ""))]
17902 "(TARGET_USE_FANCY_MATH_387
17903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17904 || TARGET_MIX_SSE_I387)
17905 && flag_unsafe_math_optimizations)
17906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17907 && !flag_trapping_math)"
17909 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17910 && !flag_trapping_math)
17912 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17915 emit_insn (gen_sse4_1_round<mode>2
17916 (operands[0], operands[1], GEN_INT (0x04)));
17918 ix86_expand_rint (operand0, operand1);
17922 rtx op0 = gen_reg_rtx (XFmode);
17923 rtx op1 = gen_reg_rtx (XFmode);
17925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17926 emit_insn (gen_rintxf2 (op0, op1));
17928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17933 (define_expand "round<mode>2"
17934 [(match_operand:MODEF 0 "register_operand" "")
17935 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17936 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17937 && !flag_trapping_math && !flag_rounding_math"
17939 if (optimize_insn_for_size_p ())
17941 if (TARGET_64BIT || (<MODE>mode != DFmode))
17942 ix86_expand_round (operand0, operand1);
17944 ix86_expand_rounddf_32 (operand0, operand1);
17948 (define_insn_and_split "*fistdi2_1"
17949 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17950 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17952 "TARGET_USE_FANCY_MATH_387
17953 && !(reload_completed || reload_in_progress)"
17958 if (memory_operand (operands[0], VOIDmode))
17959 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17962 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17963 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17968 [(set_attr "type" "fpspc")
17969 (set_attr "mode" "DI")])
17971 (define_insn "fistdi2"
17972 [(set (match_operand:DI 0 "memory_operand" "=m")
17973 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17975 (clobber (match_scratch:XF 2 "=&1f"))]
17976 "TARGET_USE_FANCY_MATH_387"
17977 "* return output_fix_trunc (insn, operands, 0);"
17978 [(set_attr "type" "fpspc")
17979 (set_attr "mode" "DI")])
17981 (define_insn "fistdi2_with_temp"
17982 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17983 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17985 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17986 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17987 "TARGET_USE_FANCY_MATH_387"
17989 [(set_attr "type" "fpspc")
17990 (set_attr "mode" "DI")])
17993 [(set (match_operand:DI 0 "register_operand" "")
17994 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17996 (clobber (match_operand:DI 2 "memory_operand" ""))
17997 (clobber (match_scratch 3 ""))]
17999 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18000 (clobber (match_dup 3))])
18001 (set (match_dup 0) (match_dup 2))]
18005 [(set (match_operand:DI 0 "memory_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 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18012 (clobber (match_dup 3))])]
18015 (define_insn_and_split "*fist<mode>2_1"
18016 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18017 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18019 "TARGET_USE_FANCY_MATH_387
18020 && !(reload_completed || reload_in_progress)"
18025 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18026 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18030 [(set_attr "type" "fpspc")
18031 (set_attr "mode" "<MODE>")])
18033 (define_insn "fist<mode>2"
18034 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18035 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18037 "TARGET_USE_FANCY_MATH_387"
18038 "* return output_fix_trunc (insn, operands, 0);"
18039 [(set_attr "type" "fpspc")
18040 (set_attr "mode" "<MODE>")])
18042 (define_insn "fist<mode>2_with_temp"
18043 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18044 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18046 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18047 "TARGET_USE_FANCY_MATH_387"
18049 [(set_attr "type" "fpspc")
18050 (set_attr "mode" "<MODE>")])
18053 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18056 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18058 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18059 (set (match_dup 0) (match_dup 2))]
18063 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18064 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18066 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18068 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18071 (define_expand "lrintxf<mode>2"
18072 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18073 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18075 "TARGET_USE_FANCY_MATH_387"
18078 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18079 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18080 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18081 UNSPEC_FIX_NOTRUNC))]
18082 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18083 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18086 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18087 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18088 (match_operand:MODEF 1 "register_operand" "")]
18089 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18090 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18091 && !flag_trapping_math && !flag_rounding_math"
18093 if (optimize_insn_for_size_p ())
18095 ix86_expand_lround (operand0, operand1);
18099 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18100 (define_insn_and_split "frndintxf2_floor"
18101 [(set (match_operand:XF 0 "register_operand" "")
18102 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18103 UNSPEC_FRNDINT_FLOOR))
18104 (clobber (reg:CC FLAGS_REG))]
18105 "TARGET_USE_FANCY_MATH_387
18106 && flag_unsafe_math_optimizations
18107 && !(reload_completed || reload_in_progress)"
18112 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18114 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18117 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18118 operands[2], operands[3]));
18121 [(set_attr "type" "frndint")
18122 (set_attr "i387_cw" "floor")
18123 (set_attr "mode" "XF")])
18125 (define_insn "frndintxf2_floor_i387"
18126 [(set (match_operand:XF 0 "register_operand" "=f")
18127 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18128 UNSPEC_FRNDINT_FLOOR))
18129 (use (match_operand:HI 2 "memory_operand" "m"))
18130 (use (match_operand:HI 3 "memory_operand" "m"))]
18131 "TARGET_USE_FANCY_MATH_387
18132 && flag_unsafe_math_optimizations"
18133 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18134 [(set_attr "type" "frndint")
18135 (set_attr "i387_cw" "floor")
18136 (set_attr "mode" "XF")])
18138 (define_expand "floorxf2"
18139 [(use (match_operand:XF 0 "register_operand" ""))
18140 (use (match_operand:XF 1 "register_operand" ""))]
18141 "TARGET_USE_FANCY_MATH_387
18142 && flag_unsafe_math_optimizations"
18144 if (optimize_insn_for_size_p ())
18146 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18150 (define_expand "floor<mode>2"
18151 [(use (match_operand:MODEF 0 "register_operand" ""))
18152 (use (match_operand:MODEF 1 "register_operand" ""))]
18153 "(TARGET_USE_FANCY_MATH_387
18154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18155 || TARGET_MIX_SSE_I387)
18156 && flag_unsafe_math_optimizations)
18157 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18158 && !flag_trapping_math)"
18160 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18161 && !flag_trapping_math
18162 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18164 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18167 emit_insn (gen_sse4_1_round<mode>2
18168 (operands[0], operands[1], GEN_INT (0x01)));
18169 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18170 ix86_expand_floorceil (operand0, operand1, true);
18172 ix86_expand_floorceildf_32 (operand0, operand1, true);
18178 if (optimize_insn_for_size_p ())
18181 op0 = gen_reg_rtx (XFmode);
18182 op1 = gen_reg_rtx (XFmode);
18183 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18184 emit_insn (gen_frndintxf2_floor (op0, op1));
18186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18191 (define_insn_and_split "*fist<mode>2_floor_1"
18192 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18193 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18194 UNSPEC_FIST_FLOOR))
18195 (clobber (reg:CC FLAGS_REG))]
18196 "TARGET_USE_FANCY_MATH_387
18197 && flag_unsafe_math_optimizations
18198 && !(reload_completed || reload_in_progress)"
18203 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18205 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18206 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18207 if (memory_operand (operands[0], VOIDmode))
18208 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18209 operands[2], operands[3]));
18212 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18213 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18214 operands[2], operands[3],
18219 [(set_attr "type" "fistp")
18220 (set_attr "i387_cw" "floor")
18221 (set_attr "mode" "<MODE>")])
18223 (define_insn "fistdi2_floor"
18224 [(set (match_operand:DI 0 "memory_operand" "=m")
18225 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18226 UNSPEC_FIST_FLOOR))
18227 (use (match_operand:HI 2 "memory_operand" "m"))
18228 (use (match_operand:HI 3 "memory_operand" "m"))
18229 (clobber (match_scratch:XF 4 "=&1f"))]
18230 "TARGET_USE_FANCY_MATH_387
18231 && flag_unsafe_math_optimizations"
18232 "* return output_fix_trunc (insn, operands, 0);"
18233 [(set_attr "type" "fistp")
18234 (set_attr "i387_cw" "floor")
18235 (set_attr "mode" "DI")])
18237 (define_insn "fistdi2_floor_with_temp"
18238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18239 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18240 UNSPEC_FIST_FLOOR))
18241 (use (match_operand:HI 2 "memory_operand" "m,m"))
18242 (use (match_operand:HI 3 "memory_operand" "m,m"))
18243 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18244 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18245 "TARGET_USE_FANCY_MATH_387
18246 && flag_unsafe_math_optimizations"
18248 [(set_attr "type" "fistp")
18249 (set_attr "i387_cw" "floor")
18250 (set_attr "mode" "DI")])
18253 [(set (match_operand:DI 0 "register_operand" "")
18254 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18255 UNSPEC_FIST_FLOOR))
18256 (use (match_operand:HI 2 "memory_operand" ""))
18257 (use (match_operand:HI 3 "memory_operand" ""))
18258 (clobber (match_operand:DI 4 "memory_operand" ""))
18259 (clobber (match_scratch 5 ""))]
18261 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18262 (use (match_dup 2))
18263 (use (match_dup 3))
18264 (clobber (match_dup 5))])
18265 (set (match_dup 0) (match_dup 4))]
18269 [(set (match_operand:DI 0 "memory_operand" "")
18270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18271 UNSPEC_FIST_FLOOR))
18272 (use (match_operand:HI 2 "memory_operand" ""))
18273 (use (match_operand:HI 3 "memory_operand" ""))
18274 (clobber (match_operand:DI 4 "memory_operand" ""))
18275 (clobber (match_scratch 5 ""))]
18277 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18278 (use (match_dup 2))
18279 (use (match_dup 3))
18280 (clobber (match_dup 5))])]
18283 (define_insn "fist<mode>2_floor"
18284 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18285 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18286 UNSPEC_FIST_FLOOR))
18287 (use (match_operand:HI 2 "memory_operand" "m"))
18288 (use (match_operand:HI 3 "memory_operand" "m"))]
18289 "TARGET_USE_FANCY_MATH_387
18290 && flag_unsafe_math_optimizations"
18291 "* return output_fix_trunc (insn, operands, 0);"
18292 [(set_attr "type" "fistp")
18293 (set_attr "i387_cw" "floor")
18294 (set_attr "mode" "<MODE>")])
18296 (define_insn "fist<mode>2_floor_with_temp"
18297 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18298 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18299 UNSPEC_FIST_FLOOR))
18300 (use (match_operand:HI 2 "memory_operand" "m,m"))
18301 (use (match_operand:HI 3 "memory_operand" "m,m"))
18302 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18303 "TARGET_USE_FANCY_MATH_387
18304 && flag_unsafe_math_optimizations"
18306 [(set_attr "type" "fistp")
18307 (set_attr "i387_cw" "floor")
18308 (set_attr "mode" "<MODE>")])
18311 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18312 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18313 UNSPEC_FIST_FLOOR))
18314 (use (match_operand:HI 2 "memory_operand" ""))
18315 (use (match_operand:HI 3 "memory_operand" ""))
18316 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18318 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18319 UNSPEC_FIST_FLOOR))
18320 (use (match_dup 2))
18321 (use (match_dup 3))])
18322 (set (match_dup 0) (match_dup 4))]
18326 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328 UNSPEC_FIST_FLOOR))
18329 (use (match_operand:HI 2 "memory_operand" ""))
18330 (use (match_operand:HI 3 "memory_operand" ""))
18331 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18333 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18334 UNSPEC_FIST_FLOOR))
18335 (use (match_dup 2))
18336 (use (match_dup 3))])]
18339 (define_expand "lfloorxf<mode>2"
18340 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18341 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18342 UNSPEC_FIST_FLOOR))
18343 (clobber (reg:CC FLAGS_REG))])]
18344 "TARGET_USE_FANCY_MATH_387
18345 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18346 && flag_unsafe_math_optimizations"
18349 (define_expand "lfloor<mode>di2"
18350 [(match_operand:DI 0 "nonimmediate_operand" "")
18351 (match_operand:MODEF 1 "register_operand" "")]
18352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18353 && !flag_trapping_math"
18355 if (optimize_insn_for_size_p ())
18357 ix86_expand_lfloorceil (operand0, operand1, true);
18361 (define_expand "lfloor<mode>si2"
18362 [(match_operand:SI 0 "nonimmediate_operand" "")
18363 (match_operand:MODEF 1 "register_operand" "")]
18364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18365 && !flag_trapping_math"
18367 if (optimize_insn_for_size_p () && TARGET_64BIT)
18369 ix86_expand_lfloorceil (operand0, operand1, true);
18373 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18374 (define_insn_and_split "frndintxf2_ceil"
18375 [(set (match_operand:XF 0 "register_operand" "")
18376 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18377 UNSPEC_FRNDINT_CEIL))
18378 (clobber (reg:CC FLAGS_REG))]
18379 "TARGET_USE_FANCY_MATH_387
18380 && flag_unsafe_math_optimizations
18381 && !(reload_completed || reload_in_progress)"
18386 ix86_optimize_mode_switching[I387_CEIL] = 1;
18388 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18389 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18391 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18392 operands[2], operands[3]));
18395 [(set_attr "type" "frndint")
18396 (set_attr "i387_cw" "ceil")
18397 (set_attr "mode" "XF")])
18399 (define_insn "frndintxf2_ceil_i387"
18400 [(set (match_operand:XF 0 "register_operand" "=f")
18401 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18402 UNSPEC_FRNDINT_CEIL))
18403 (use (match_operand:HI 2 "memory_operand" "m"))
18404 (use (match_operand:HI 3 "memory_operand" "m"))]
18405 "TARGET_USE_FANCY_MATH_387
18406 && flag_unsafe_math_optimizations"
18407 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18408 [(set_attr "type" "frndint")
18409 (set_attr "i387_cw" "ceil")
18410 (set_attr "mode" "XF")])
18412 (define_expand "ceilxf2"
18413 [(use (match_operand:XF 0 "register_operand" ""))
18414 (use (match_operand:XF 1 "register_operand" ""))]
18415 "TARGET_USE_FANCY_MATH_387
18416 && flag_unsafe_math_optimizations"
18418 if (optimize_insn_for_size_p ())
18420 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18424 (define_expand "ceil<mode>2"
18425 [(use (match_operand:MODEF 0 "register_operand" ""))
18426 (use (match_operand:MODEF 1 "register_operand" ""))]
18427 "(TARGET_USE_FANCY_MATH_387
18428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18429 || TARGET_MIX_SSE_I387)
18430 && flag_unsafe_math_optimizations)
18431 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18432 && !flag_trapping_math)"
18434 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18435 && !flag_trapping_math
18436 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18439 emit_insn (gen_sse4_1_round<mode>2
18440 (operands[0], operands[1], GEN_INT (0x02)));
18441 else if (optimize_insn_for_size_p ())
18443 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18444 ix86_expand_floorceil (operand0, operand1, false);
18446 ix86_expand_floorceildf_32 (operand0, operand1, false);
18452 if (optimize_insn_for_size_p ())
18455 op0 = gen_reg_rtx (XFmode);
18456 op1 = gen_reg_rtx (XFmode);
18457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18458 emit_insn (gen_frndintxf2_ceil (op0, op1));
18460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18465 (define_insn_and_split "*fist<mode>2_ceil_1"
18466 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18467 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18469 (clobber (reg:CC FLAGS_REG))]
18470 "TARGET_USE_FANCY_MATH_387
18471 && flag_unsafe_math_optimizations
18472 && !(reload_completed || reload_in_progress)"
18477 ix86_optimize_mode_switching[I387_CEIL] = 1;
18479 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18480 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18481 if (memory_operand (operands[0], VOIDmode))
18482 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18483 operands[2], operands[3]));
18486 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18487 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18488 operands[2], operands[3],
18493 [(set_attr "type" "fistp")
18494 (set_attr "i387_cw" "ceil")
18495 (set_attr "mode" "<MODE>")])
18497 (define_insn "fistdi2_ceil"
18498 [(set (match_operand:DI 0 "memory_operand" "=m")
18499 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18501 (use (match_operand:HI 2 "memory_operand" "m"))
18502 (use (match_operand:HI 3 "memory_operand" "m"))
18503 (clobber (match_scratch:XF 4 "=&1f"))]
18504 "TARGET_USE_FANCY_MATH_387
18505 && flag_unsafe_math_optimizations"
18506 "* return output_fix_trunc (insn, operands, 0);"
18507 [(set_attr "type" "fistp")
18508 (set_attr "i387_cw" "ceil")
18509 (set_attr "mode" "DI")])
18511 (define_insn "fistdi2_ceil_with_temp"
18512 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18513 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18515 (use (match_operand:HI 2 "memory_operand" "m,m"))
18516 (use (match_operand:HI 3 "memory_operand" "m,m"))
18517 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18518 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18519 "TARGET_USE_FANCY_MATH_387
18520 && flag_unsafe_math_optimizations"
18522 [(set_attr "type" "fistp")
18523 (set_attr "i387_cw" "ceil")
18524 (set_attr "mode" "DI")])
18527 [(set (match_operand:DI 0 "register_operand" "")
18528 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18530 (use (match_operand:HI 2 "memory_operand" ""))
18531 (use (match_operand:HI 3 "memory_operand" ""))
18532 (clobber (match_operand:DI 4 "memory_operand" ""))
18533 (clobber (match_scratch 5 ""))]
18535 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18536 (use (match_dup 2))
18537 (use (match_dup 3))
18538 (clobber (match_dup 5))])
18539 (set (match_dup 0) (match_dup 4))]
18543 [(set (match_operand:DI 0 "memory_operand" "")
18544 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18546 (use (match_operand:HI 2 "memory_operand" ""))
18547 (use (match_operand:HI 3 "memory_operand" ""))
18548 (clobber (match_operand:DI 4 "memory_operand" ""))
18549 (clobber (match_scratch 5 ""))]
18551 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18552 (use (match_dup 2))
18553 (use (match_dup 3))
18554 (clobber (match_dup 5))])]
18557 (define_insn "fist<mode>2_ceil"
18558 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18559 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18561 (use (match_operand:HI 2 "memory_operand" "m"))
18562 (use (match_operand:HI 3 "memory_operand" "m"))]
18563 "TARGET_USE_FANCY_MATH_387
18564 && flag_unsafe_math_optimizations"
18565 "* return output_fix_trunc (insn, operands, 0);"
18566 [(set_attr "type" "fistp")
18567 (set_attr "i387_cw" "ceil")
18568 (set_attr "mode" "<MODE>")])
18570 (define_insn "fist<mode>2_ceil_with_temp"
18571 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18572 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18574 (use (match_operand:HI 2 "memory_operand" "m,m"))
18575 (use (match_operand:HI 3 "memory_operand" "m,m"))
18576 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18577 "TARGET_USE_FANCY_MATH_387
18578 && flag_unsafe_math_optimizations"
18580 [(set_attr "type" "fistp")
18581 (set_attr "i387_cw" "ceil")
18582 (set_attr "mode" "<MODE>")])
18585 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18588 (use (match_operand:HI 2 "memory_operand" ""))
18589 (use (match_operand:HI 3 "memory_operand" ""))
18590 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18592 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18594 (use (match_dup 2))
18595 (use (match_dup 3))])
18596 (set (match_dup 0) (match_dup 4))]
18600 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18601 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18603 (use (match_operand:HI 2 "memory_operand" ""))
18604 (use (match_operand:HI 3 "memory_operand" ""))
18605 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18607 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18609 (use (match_dup 2))
18610 (use (match_dup 3))])]
18613 (define_expand "lceilxf<mode>2"
18614 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18615 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18617 (clobber (reg:CC FLAGS_REG))])]
18618 "TARGET_USE_FANCY_MATH_387
18619 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18620 && flag_unsafe_math_optimizations"
18623 (define_expand "lceil<mode>di2"
18624 [(match_operand:DI 0 "nonimmediate_operand" "")
18625 (match_operand:MODEF 1 "register_operand" "")]
18626 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18627 && !flag_trapping_math"
18629 ix86_expand_lfloorceil (operand0, operand1, false);
18633 (define_expand "lceil<mode>si2"
18634 [(match_operand:SI 0 "nonimmediate_operand" "")
18635 (match_operand:MODEF 1 "register_operand" "")]
18636 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18637 && !flag_trapping_math"
18639 ix86_expand_lfloorceil (operand0, operand1, false);
18643 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18644 (define_insn_and_split "frndintxf2_trunc"
18645 [(set (match_operand:XF 0 "register_operand" "")
18646 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18647 UNSPEC_FRNDINT_TRUNC))
18648 (clobber (reg:CC FLAGS_REG))]
18649 "TARGET_USE_FANCY_MATH_387
18650 && flag_unsafe_math_optimizations
18651 && !(reload_completed || reload_in_progress)"
18656 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18658 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18659 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18661 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18662 operands[2], operands[3]));
18665 [(set_attr "type" "frndint")
18666 (set_attr "i387_cw" "trunc")
18667 (set_attr "mode" "XF")])
18669 (define_insn "frndintxf2_trunc_i387"
18670 [(set (match_operand:XF 0 "register_operand" "=f")
18671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18672 UNSPEC_FRNDINT_TRUNC))
18673 (use (match_operand:HI 2 "memory_operand" "m"))
18674 (use (match_operand:HI 3 "memory_operand" "m"))]
18675 "TARGET_USE_FANCY_MATH_387
18676 && flag_unsafe_math_optimizations"
18677 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18678 [(set_attr "type" "frndint")
18679 (set_attr "i387_cw" "trunc")
18680 (set_attr "mode" "XF")])
18682 (define_expand "btruncxf2"
18683 [(use (match_operand:XF 0 "register_operand" ""))
18684 (use (match_operand:XF 1 "register_operand" ""))]
18685 "TARGET_USE_FANCY_MATH_387
18686 && flag_unsafe_math_optimizations"
18688 if (optimize_insn_for_size_p ())
18690 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18694 (define_expand "btrunc<mode>2"
18695 [(use (match_operand:MODEF 0 "register_operand" ""))
18696 (use (match_operand:MODEF 1 "register_operand" ""))]
18697 "(TARGET_USE_FANCY_MATH_387
18698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18699 || TARGET_MIX_SSE_I387)
18700 && flag_unsafe_math_optimizations)
18701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18702 && !flag_trapping_math)"
18704 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18705 && !flag_trapping_math
18706 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18709 emit_insn (gen_sse4_1_round<mode>2
18710 (operands[0], operands[1], GEN_INT (0x03)));
18711 else if (optimize_insn_for_size_p ())
18713 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18714 ix86_expand_trunc (operand0, operand1);
18716 ix86_expand_truncdf_32 (operand0, operand1);
18722 if (optimize_insn_for_size_p ())
18725 op0 = gen_reg_rtx (XFmode);
18726 op1 = gen_reg_rtx (XFmode);
18727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18728 emit_insn (gen_frndintxf2_trunc (op0, op1));
18730 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18735 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18736 (define_insn_and_split "frndintxf2_mask_pm"
18737 [(set (match_operand:XF 0 "register_operand" "")
18738 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18739 UNSPEC_FRNDINT_MASK_PM))
18740 (clobber (reg:CC FLAGS_REG))]
18741 "TARGET_USE_FANCY_MATH_387
18742 && flag_unsafe_math_optimizations
18743 && !(reload_completed || reload_in_progress)"
18748 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18750 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18751 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18753 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18754 operands[2], operands[3]));
18757 [(set_attr "type" "frndint")
18758 (set_attr "i387_cw" "mask_pm")
18759 (set_attr "mode" "XF")])
18761 (define_insn "frndintxf2_mask_pm_i387"
18762 [(set (match_operand:XF 0 "register_operand" "=f")
18763 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18764 UNSPEC_FRNDINT_MASK_PM))
18765 (use (match_operand:HI 2 "memory_operand" "m"))
18766 (use (match_operand:HI 3 "memory_operand" "m"))]
18767 "TARGET_USE_FANCY_MATH_387
18768 && flag_unsafe_math_optimizations"
18769 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18770 [(set_attr "type" "frndint")
18771 (set_attr "i387_cw" "mask_pm")
18772 (set_attr "mode" "XF")])
18774 (define_expand "nearbyintxf2"
18775 [(use (match_operand:XF 0 "register_operand" ""))
18776 (use (match_operand:XF 1 "register_operand" ""))]
18777 "TARGET_USE_FANCY_MATH_387
18778 && flag_unsafe_math_optimizations"
18780 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18785 (define_expand "nearbyint<mode>2"
18786 [(use (match_operand:MODEF 0 "register_operand" ""))
18787 (use (match_operand:MODEF 1 "register_operand" ""))]
18788 "TARGET_USE_FANCY_MATH_387
18789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18790 || TARGET_MIX_SSE_I387)
18791 && flag_unsafe_math_optimizations"
18793 rtx op0 = gen_reg_rtx (XFmode);
18794 rtx op1 = gen_reg_rtx (XFmode);
18796 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18797 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18803 (define_insn "fxam<mode>2_i387"
18804 [(set (match_operand:HI 0 "register_operand" "=a")
18806 [(match_operand:X87MODEF 1 "register_operand" "f")]
18808 "TARGET_USE_FANCY_MATH_387"
18809 "fxam\n\tfnstsw\t%0"
18810 [(set_attr "type" "multi")
18811 (set_attr "unit" "i387")
18812 (set_attr "mode" "<MODE>")])
18814 (define_expand "isinf<mode>2"
18815 [(use (match_operand:SI 0 "register_operand" ""))
18816 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18817 "TARGET_USE_FANCY_MATH_387
18818 && TARGET_C99_FUNCTIONS
18819 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18821 rtx mask = GEN_INT (0x45);
18822 rtx val = GEN_INT (0x05);
18826 rtx scratch = gen_reg_rtx (HImode);
18827 rtx res = gen_reg_rtx (QImode);
18829 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18830 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18831 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18832 cond = gen_rtx_fmt_ee (EQ, QImode,
18833 gen_rtx_REG (CCmode, FLAGS_REG),
18835 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18836 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18840 (define_expand "signbit<mode>2"
18841 [(use (match_operand:SI 0 "register_operand" ""))
18842 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18843 "TARGET_USE_FANCY_MATH_387
18844 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18846 rtx mask = GEN_INT (0x0200);
18848 rtx scratch = gen_reg_rtx (HImode);
18850 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18851 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18855 ;; Block operation instructions
18858 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18861 [(set_attr "length" "1")
18862 (set_attr "length_immediate" "0")
18863 (set_attr "modrm" "0")])
18865 (define_expand "movmemsi"
18866 [(use (match_operand:BLK 0 "memory_operand" ""))
18867 (use (match_operand:BLK 1 "memory_operand" ""))
18868 (use (match_operand:SI 2 "nonmemory_operand" ""))
18869 (use (match_operand:SI 3 "const_int_operand" ""))
18870 (use (match_operand:SI 4 "const_int_operand" ""))
18871 (use (match_operand:SI 5 "const_int_operand" ""))]
18874 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18875 operands[4], operands[5]))
18881 (define_expand "movmemdi"
18882 [(use (match_operand:BLK 0 "memory_operand" ""))
18883 (use (match_operand:BLK 1 "memory_operand" ""))
18884 (use (match_operand:DI 2 "nonmemory_operand" ""))
18885 (use (match_operand:DI 3 "const_int_operand" ""))
18886 (use (match_operand:SI 4 "const_int_operand" ""))
18887 (use (match_operand:SI 5 "const_int_operand" ""))]
18890 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18891 operands[4], operands[5]))
18897 ;; Most CPUs don't like single string operations
18898 ;; Handle this case here to simplify previous expander.
18900 (define_expand "strmov"
18901 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18902 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18903 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18904 (clobber (reg:CC FLAGS_REG))])
18905 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18906 (clobber (reg:CC FLAGS_REG))])]
18909 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18911 /* If .md ever supports :P for Pmode, these can be directly
18912 in the pattern above. */
18913 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18914 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18916 /* Can't use this if the user has appropriated esi or edi. */
18917 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18918 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18920 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18921 operands[2], operands[3],
18922 operands[5], operands[6]));
18926 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18929 (define_expand "strmov_singleop"
18930 [(parallel [(set (match_operand 1 "memory_operand" "")
18931 (match_operand 3 "memory_operand" ""))
18932 (set (match_operand 0 "register_operand" "")
18933 (match_operand 4 "" ""))
18934 (set (match_operand 2 "register_operand" "")
18935 (match_operand 5 "" ""))])]
18937 "ix86_current_function_needs_cld = 1;")
18939 (define_insn "*strmovdi_rex_1"
18940 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18941 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18942 (set (match_operand:DI 0 "register_operand" "=D")
18943 (plus:DI (match_dup 2)
18945 (set (match_operand:DI 1 "register_operand" "=S")
18946 (plus:DI (match_dup 3)
18950 [(set_attr "type" "str")
18951 (set_attr "mode" "DI")
18952 (set_attr "memory" "both")])
18954 (define_insn "*strmovsi_1"
18955 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18956 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18957 (set (match_operand:SI 0 "register_operand" "=D")
18958 (plus:SI (match_dup 2)
18960 (set (match_operand:SI 1 "register_operand" "=S")
18961 (plus:SI (match_dup 3)
18965 [(set_attr "type" "str")
18966 (set_attr "mode" "SI")
18967 (set_attr "memory" "both")])
18969 (define_insn "*strmovsi_rex_1"
18970 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18971 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18972 (set (match_operand:DI 0 "register_operand" "=D")
18973 (plus:DI (match_dup 2)
18975 (set (match_operand:DI 1 "register_operand" "=S")
18976 (plus:DI (match_dup 3)
18980 [(set_attr "type" "str")
18981 (set_attr "mode" "SI")
18982 (set_attr "memory" "both")])
18984 (define_insn "*strmovhi_1"
18985 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18986 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18987 (set (match_operand:SI 0 "register_operand" "=D")
18988 (plus:SI (match_dup 2)
18990 (set (match_operand:SI 1 "register_operand" "=S")
18991 (plus:SI (match_dup 3)
18995 [(set_attr "type" "str")
18996 (set_attr "memory" "both")
18997 (set_attr "mode" "HI")])
18999 (define_insn "*strmovhi_rex_1"
19000 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19001 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19002 (set (match_operand:DI 0 "register_operand" "=D")
19003 (plus:DI (match_dup 2)
19005 (set (match_operand:DI 1 "register_operand" "=S")
19006 (plus:DI (match_dup 3)
19010 [(set_attr "type" "str")
19011 (set_attr "memory" "both")
19012 (set_attr "mode" "HI")])
19014 (define_insn "*strmovqi_1"
19015 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19016 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19017 (set (match_operand:SI 0 "register_operand" "=D")
19018 (plus:SI (match_dup 2)
19020 (set (match_operand:SI 1 "register_operand" "=S")
19021 (plus:SI (match_dup 3)
19025 [(set_attr "type" "str")
19026 (set_attr "memory" "both")
19027 (set_attr "mode" "QI")])
19029 (define_insn "*strmovqi_rex_1"
19030 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19031 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19032 (set (match_operand:DI 0 "register_operand" "=D")
19033 (plus:DI (match_dup 2)
19035 (set (match_operand:DI 1 "register_operand" "=S")
19036 (plus:DI (match_dup 3)
19040 [(set_attr "type" "str")
19041 (set_attr "memory" "both")
19042 (set_attr "mode" "QI")])
19044 (define_expand "rep_mov"
19045 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19046 (set (match_operand 0 "register_operand" "")
19047 (match_operand 5 "" ""))
19048 (set (match_operand 2 "register_operand" "")
19049 (match_operand 6 "" ""))
19050 (set (match_operand 1 "memory_operand" "")
19051 (match_operand 3 "memory_operand" ""))
19052 (use (match_dup 4))])]
19054 "ix86_current_function_needs_cld = 1;")
19056 (define_insn "*rep_movdi_rex64"
19057 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19058 (set (match_operand:DI 0 "register_operand" "=D")
19059 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19061 (match_operand:DI 3 "register_operand" "0")))
19062 (set (match_operand:DI 1 "register_operand" "=S")
19063 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19064 (match_operand:DI 4 "register_operand" "1")))
19065 (set (mem:BLK (match_dup 3))
19066 (mem:BLK (match_dup 4)))
19067 (use (match_dup 5))]
19070 [(set_attr "type" "str")
19071 (set_attr "prefix_rep" "1")
19072 (set_attr "memory" "both")
19073 (set_attr "mode" "DI")])
19075 (define_insn "*rep_movsi"
19076 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19077 (set (match_operand:SI 0 "register_operand" "=D")
19078 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19080 (match_operand:SI 3 "register_operand" "0")))
19081 (set (match_operand:SI 1 "register_operand" "=S")
19082 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19083 (match_operand:SI 4 "register_operand" "1")))
19084 (set (mem:BLK (match_dup 3))
19085 (mem:BLK (match_dup 4)))
19086 (use (match_dup 5))]
19089 [(set_attr "type" "str")
19090 (set_attr "prefix_rep" "1")
19091 (set_attr "memory" "both")
19092 (set_attr "mode" "SI")])
19094 (define_insn "*rep_movsi_rex64"
19095 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19096 (set (match_operand:DI 0 "register_operand" "=D")
19097 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19099 (match_operand:DI 3 "register_operand" "0")))
19100 (set (match_operand:DI 1 "register_operand" "=S")
19101 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19102 (match_operand:DI 4 "register_operand" "1")))
19103 (set (mem:BLK (match_dup 3))
19104 (mem:BLK (match_dup 4)))
19105 (use (match_dup 5))]
19108 [(set_attr "type" "str")
19109 (set_attr "prefix_rep" "1")
19110 (set_attr "memory" "both")
19111 (set_attr "mode" "SI")])
19113 (define_insn "*rep_movqi"
19114 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19115 (set (match_operand:SI 0 "register_operand" "=D")
19116 (plus:SI (match_operand:SI 3 "register_operand" "0")
19117 (match_operand:SI 5 "register_operand" "2")))
19118 (set (match_operand:SI 1 "register_operand" "=S")
19119 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19120 (set (mem:BLK (match_dup 3))
19121 (mem:BLK (match_dup 4)))
19122 (use (match_dup 5))]
19125 [(set_attr "type" "str")
19126 (set_attr "prefix_rep" "1")
19127 (set_attr "memory" "both")
19128 (set_attr "mode" "SI")])
19130 (define_insn "*rep_movqi_rex64"
19131 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19132 (set (match_operand:DI 0 "register_operand" "=D")
19133 (plus:DI (match_operand:DI 3 "register_operand" "0")
19134 (match_operand:DI 5 "register_operand" "2")))
19135 (set (match_operand:DI 1 "register_operand" "=S")
19136 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19137 (set (mem:BLK (match_dup 3))
19138 (mem:BLK (match_dup 4)))
19139 (use (match_dup 5))]
19142 [(set_attr "type" "str")
19143 (set_attr "prefix_rep" "1")
19144 (set_attr "memory" "both")
19145 (set_attr "mode" "SI")])
19147 (define_expand "setmemsi"
19148 [(use (match_operand:BLK 0 "memory_operand" ""))
19149 (use (match_operand:SI 1 "nonmemory_operand" ""))
19150 (use (match_operand 2 "const_int_operand" ""))
19151 (use (match_operand 3 "const_int_operand" ""))
19152 (use (match_operand:SI 4 "const_int_operand" ""))
19153 (use (match_operand:SI 5 "const_int_operand" ""))]
19156 if (ix86_expand_setmem (operands[0], operands[1],
19157 operands[2], operands[3],
19158 operands[4], operands[5]))
19164 (define_expand "setmemdi"
19165 [(use (match_operand:BLK 0 "memory_operand" ""))
19166 (use (match_operand:DI 1 "nonmemory_operand" ""))
19167 (use (match_operand 2 "const_int_operand" ""))
19168 (use (match_operand 3 "const_int_operand" ""))
19169 (use (match_operand 4 "const_int_operand" ""))
19170 (use (match_operand 5 "const_int_operand" ""))]
19173 if (ix86_expand_setmem (operands[0], operands[1],
19174 operands[2], operands[3],
19175 operands[4], operands[5]))
19181 ;; Most CPUs don't like single string operations
19182 ;; Handle this case here to simplify previous expander.
19184 (define_expand "strset"
19185 [(set (match_operand 1 "memory_operand" "")
19186 (match_operand 2 "register_operand" ""))
19187 (parallel [(set (match_operand 0 "register_operand" "")
19189 (clobber (reg:CC FLAGS_REG))])]
19192 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19193 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19195 /* If .md ever supports :P for Pmode, this can be directly
19196 in the pattern above. */
19197 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19198 GEN_INT (GET_MODE_SIZE (GET_MODE
19200 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19202 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19208 (define_expand "strset_singleop"
19209 [(parallel [(set (match_operand 1 "memory_operand" "")
19210 (match_operand 2 "register_operand" ""))
19211 (set (match_operand 0 "register_operand" "")
19212 (match_operand 3 "" ""))])]
19214 "ix86_current_function_needs_cld = 1;")
19216 (define_insn "*strsetdi_rex_1"
19217 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19218 (match_operand:DI 2 "register_operand" "a"))
19219 (set (match_operand:DI 0 "register_operand" "=D")
19220 (plus:DI (match_dup 1)
19224 [(set_attr "type" "str")
19225 (set_attr "memory" "store")
19226 (set_attr "mode" "DI")])
19228 (define_insn "*strsetsi_1"
19229 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19230 (match_operand:SI 2 "register_operand" "a"))
19231 (set (match_operand:SI 0 "register_operand" "=D")
19232 (plus:SI (match_dup 1)
19236 [(set_attr "type" "str")
19237 (set_attr "memory" "store")
19238 (set_attr "mode" "SI")])
19240 (define_insn "*strsetsi_rex_1"
19241 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19242 (match_operand:SI 2 "register_operand" "a"))
19243 (set (match_operand:DI 0 "register_operand" "=D")
19244 (plus:DI (match_dup 1)
19248 [(set_attr "type" "str")
19249 (set_attr "memory" "store")
19250 (set_attr "mode" "SI")])
19252 (define_insn "*strsethi_1"
19253 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19254 (match_operand:HI 2 "register_operand" "a"))
19255 (set (match_operand:SI 0 "register_operand" "=D")
19256 (plus:SI (match_dup 1)
19260 [(set_attr "type" "str")
19261 (set_attr "memory" "store")
19262 (set_attr "mode" "HI")])
19264 (define_insn "*strsethi_rex_1"
19265 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19266 (match_operand:HI 2 "register_operand" "a"))
19267 (set (match_operand:DI 0 "register_operand" "=D")
19268 (plus:DI (match_dup 1)
19272 [(set_attr "type" "str")
19273 (set_attr "memory" "store")
19274 (set_attr "mode" "HI")])
19276 (define_insn "*strsetqi_1"
19277 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19278 (match_operand:QI 2 "register_operand" "a"))
19279 (set (match_operand:SI 0 "register_operand" "=D")
19280 (plus:SI (match_dup 1)
19284 [(set_attr "type" "str")
19285 (set_attr "memory" "store")
19286 (set_attr "mode" "QI")])
19288 (define_insn "*strsetqi_rex_1"
19289 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19290 (match_operand:QI 2 "register_operand" "a"))
19291 (set (match_operand:DI 0 "register_operand" "=D")
19292 (plus:DI (match_dup 1)
19296 [(set_attr "type" "str")
19297 (set_attr "memory" "store")
19298 (set_attr "mode" "QI")])
19300 (define_expand "rep_stos"
19301 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19302 (set (match_operand 0 "register_operand" "")
19303 (match_operand 4 "" ""))
19304 (set (match_operand 2 "memory_operand" "") (const_int 0))
19305 (use (match_operand 3 "register_operand" ""))
19306 (use (match_dup 1))])]
19308 "ix86_current_function_needs_cld = 1;")
19310 (define_insn "*rep_stosdi_rex64"
19311 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19312 (set (match_operand:DI 0 "register_operand" "=D")
19313 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19315 (match_operand:DI 3 "register_operand" "0")))
19316 (set (mem:BLK (match_dup 3))
19318 (use (match_operand:DI 2 "register_operand" "a"))
19319 (use (match_dup 4))]
19322 [(set_attr "type" "str")
19323 (set_attr "prefix_rep" "1")
19324 (set_attr "memory" "store")
19325 (set_attr "mode" "DI")])
19327 (define_insn "*rep_stossi"
19328 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19329 (set (match_operand:SI 0 "register_operand" "=D")
19330 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19332 (match_operand:SI 3 "register_operand" "0")))
19333 (set (mem:BLK (match_dup 3))
19335 (use (match_operand:SI 2 "register_operand" "a"))
19336 (use (match_dup 4))]
19339 [(set_attr "type" "str")
19340 (set_attr "prefix_rep" "1")
19341 (set_attr "memory" "store")
19342 (set_attr "mode" "SI")])
19344 (define_insn "*rep_stossi_rex64"
19345 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19346 (set (match_operand:DI 0 "register_operand" "=D")
19347 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19349 (match_operand:DI 3 "register_operand" "0")))
19350 (set (mem:BLK (match_dup 3))
19352 (use (match_operand:SI 2 "register_operand" "a"))
19353 (use (match_dup 4))]
19356 [(set_attr "type" "str")
19357 (set_attr "prefix_rep" "1")
19358 (set_attr "memory" "store")
19359 (set_attr "mode" "SI")])
19361 (define_insn "*rep_stosqi"
19362 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19363 (set (match_operand:SI 0 "register_operand" "=D")
19364 (plus:SI (match_operand:SI 3 "register_operand" "0")
19365 (match_operand:SI 4 "register_operand" "1")))
19366 (set (mem:BLK (match_dup 3))
19368 (use (match_operand:QI 2 "register_operand" "a"))
19369 (use (match_dup 4))]
19372 [(set_attr "type" "str")
19373 (set_attr "prefix_rep" "1")
19374 (set_attr "memory" "store")
19375 (set_attr "mode" "QI")])
19377 (define_insn "*rep_stosqi_rex64"
19378 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19379 (set (match_operand:DI 0 "register_operand" "=D")
19380 (plus:DI (match_operand:DI 3 "register_operand" "0")
19381 (match_operand:DI 4 "register_operand" "1")))
19382 (set (mem:BLK (match_dup 3))
19384 (use (match_operand:QI 2 "register_operand" "a"))
19385 (use (match_dup 4))]
19388 [(set_attr "type" "str")
19389 (set_attr "prefix_rep" "1")
19390 (set_attr "memory" "store")
19391 (set_attr "mode" "QI")])
19393 (define_expand "cmpstrnsi"
19394 [(set (match_operand:SI 0 "register_operand" "")
19395 (compare:SI (match_operand:BLK 1 "general_operand" "")
19396 (match_operand:BLK 2 "general_operand" "")))
19397 (use (match_operand 3 "general_operand" ""))
19398 (use (match_operand 4 "immediate_operand" ""))]
19401 rtx addr1, addr2, out, outlow, count, countreg, align;
19403 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19406 /* Can't use this if the user has appropriated esi or edi. */
19407 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19412 out = gen_reg_rtx (SImode);
19414 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19415 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19416 if (addr1 != XEXP (operands[1], 0))
19417 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19418 if (addr2 != XEXP (operands[2], 0))
19419 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19421 count = operands[3];
19422 countreg = ix86_zero_extend_to_Pmode (count);
19424 /* %%% Iff we are testing strict equality, we can use known alignment
19425 to good advantage. This may be possible with combine, particularly
19426 once cc0 is dead. */
19427 align = operands[4];
19429 if (CONST_INT_P (count))
19431 if (INTVAL (count) == 0)
19433 emit_move_insn (operands[0], const0_rtx);
19436 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19437 operands[1], operands[2]));
19442 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19444 emit_insn (gen_cmpsi_1 (countreg, countreg));
19445 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19446 operands[1], operands[2]));
19449 outlow = gen_lowpart (QImode, out);
19450 emit_insn (gen_cmpintqi (outlow));
19451 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19453 if (operands[0] != out)
19454 emit_move_insn (operands[0], out);
19459 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19461 (define_expand "cmpintqi"
19462 [(set (match_dup 1)
19463 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19465 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19466 (parallel [(set (match_operand:QI 0 "register_operand" "")
19467 (minus:QI (match_dup 1)
19469 (clobber (reg:CC FLAGS_REG))])]
19471 "operands[1] = gen_reg_rtx (QImode);
19472 operands[2] = gen_reg_rtx (QImode);")
19474 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19475 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19477 (define_expand "cmpstrnqi_nz_1"
19478 [(parallel [(set (reg:CC FLAGS_REG)
19479 (compare:CC (match_operand 4 "memory_operand" "")
19480 (match_operand 5 "memory_operand" "")))
19481 (use (match_operand 2 "register_operand" ""))
19482 (use (match_operand:SI 3 "immediate_operand" ""))
19483 (clobber (match_operand 0 "register_operand" ""))
19484 (clobber (match_operand 1 "register_operand" ""))
19485 (clobber (match_dup 2))])]
19487 "ix86_current_function_needs_cld = 1;")
19489 (define_insn "*cmpstrnqi_nz_1"
19490 [(set (reg:CC FLAGS_REG)
19491 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19492 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19493 (use (match_operand:SI 6 "register_operand" "2"))
19494 (use (match_operand:SI 3 "immediate_operand" "i"))
19495 (clobber (match_operand:SI 0 "register_operand" "=S"))
19496 (clobber (match_operand:SI 1 "register_operand" "=D"))
19497 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19500 [(set_attr "type" "str")
19501 (set_attr "mode" "QI")
19502 (set_attr "prefix_rep" "1")])
19504 (define_insn "*cmpstrnqi_nz_rex_1"
19505 [(set (reg:CC FLAGS_REG)
19506 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19507 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19508 (use (match_operand:DI 6 "register_operand" "2"))
19509 (use (match_operand:SI 3 "immediate_operand" "i"))
19510 (clobber (match_operand:DI 0 "register_operand" "=S"))
19511 (clobber (match_operand:DI 1 "register_operand" "=D"))
19512 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19515 [(set_attr "type" "str")
19516 (set_attr "mode" "QI")
19517 (set_attr "prefix_rep" "1")])
19519 ;; The same, but the count is not known to not be zero.
19521 (define_expand "cmpstrnqi_1"
19522 [(parallel [(set (reg:CC FLAGS_REG)
19523 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19525 (compare:CC (match_operand 4 "memory_operand" "")
19526 (match_operand 5 "memory_operand" ""))
19528 (use (match_operand:SI 3 "immediate_operand" ""))
19529 (use (reg:CC FLAGS_REG))
19530 (clobber (match_operand 0 "register_operand" ""))
19531 (clobber (match_operand 1 "register_operand" ""))
19532 (clobber (match_dup 2))])]
19534 "ix86_current_function_needs_cld = 1;")
19536 (define_insn "*cmpstrnqi_1"
19537 [(set (reg:CC FLAGS_REG)
19538 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19540 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19541 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19543 (use (match_operand:SI 3 "immediate_operand" "i"))
19544 (use (reg:CC FLAGS_REG))
19545 (clobber (match_operand:SI 0 "register_operand" "=S"))
19546 (clobber (match_operand:SI 1 "register_operand" "=D"))
19547 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19550 [(set_attr "type" "str")
19551 (set_attr "mode" "QI")
19552 (set_attr "prefix_rep" "1")])
19554 (define_insn "*cmpstrnqi_rex_1"
19555 [(set (reg:CC FLAGS_REG)
19556 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19558 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19559 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19561 (use (match_operand:SI 3 "immediate_operand" "i"))
19562 (use (reg:CC FLAGS_REG))
19563 (clobber (match_operand:DI 0 "register_operand" "=S"))
19564 (clobber (match_operand:DI 1 "register_operand" "=D"))
19565 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19568 [(set_attr "type" "str")
19569 (set_attr "mode" "QI")
19570 (set_attr "prefix_rep" "1")])
19572 (define_expand "strlensi"
19573 [(set (match_operand:SI 0 "register_operand" "")
19574 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19575 (match_operand:QI 2 "immediate_operand" "")
19576 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19579 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19585 (define_expand "strlendi"
19586 [(set (match_operand:DI 0 "register_operand" "")
19587 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19588 (match_operand:QI 2 "immediate_operand" "")
19589 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19592 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19598 (define_expand "strlenqi_1"
19599 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19600 (clobber (match_operand 1 "register_operand" ""))
19601 (clobber (reg:CC FLAGS_REG))])]
19603 "ix86_current_function_needs_cld = 1;")
19605 (define_insn "*strlenqi_1"
19606 [(set (match_operand:SI 0 "register_operand" "=&c")
19607 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19608 (match_operand:QI 2 "register_operand" "a")
19609 (match_operand:SI 3 "immediate_operand" "i")
19610 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19611 (clobber (match_operand:SI 1 "register_operand" "=D"))
19612 (clobber (reg:CC FLAGS_REG))]
19615 [(set_attr "type" "str")
19616 (set_attr "mode" "QI")
19617 (set_attr "prefix_rep" "1")])
19619 (define_insn "*strlenqi_rex_1"
19620 [(set (match_operand:DI 0 "register_operand" "=&c")
19621 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19622 (match_operand:QI 2 "register_operand" "a")
19623 (match_operand:DI 3 "immediate_operand" "i")
19624 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19625 (clobber (match_operand:DI 1 "register_operand" "=D"))
19626 (clobber (reg:CC FLAGS_REG))]
19629 [(set_attr "type" "str")
19630 (set_attr "mode" "QI")
19631 (set_attr "prefix_rep" "1")])
19633 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19634 ;; handled in combine, but it is not currently up to the task.
19635 ;; When used for their truth value, the cmpstrn* expanders generate
19644 ;; The intermediate three instructions are unnecessary.
19646 ;; This one handles cmpstrn*_nz_1...
19649 (set (reg:CC FLAGS_REG)
19650 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19651 (mem:BLK (match_operand 5 "register_operand" ""))))
19652 (use (match_operand 6 "register_operand" ""))
19653 (use (match_operand:SI 3 "immediate_operand" ""))
19654 (clobber (match_operand 0 "register_operand" ""))
19655 (clobber (match_operand 1 "register_operand" ""))
19656 (clobber (match_operand 2 "register_operand" ""))])
19657 (set (match_operand:QI 7 "register_operand" "")
19658 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19659 (set (match_operand:QI 8 "register_operand" "")
19660 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19661 (set (reg FLAGS_REG)
19662 (compare (match_dup 7) (match_dup 8)))
19664 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19666 (set (reg:CC FLAGS_REG)
19667 (compare:CC (mem:BLK (match_dup 4))
19668 (mem:BLK (match_dup 5))))
19669 (use (match_dup 6))
19670 (use (match_dup 3))
19671 (clobber (match_dup 0))
19672 (clobber (match_dup 1))
19673 (clobber (match_dup 2))])]
19676 ;; ...and this one handles cmpstrn*_1.
19679 (set (reg:CC FLAGS_REG)
19680 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19682 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19683 (mem:BLK (match_operand 5 "register_operand" "")))
19685 (use (match_operand:SI 3 "immediate_operand" ""))
19686 (use (reg:CC FLAGS_REG))
19687 (clobber (match_operand 0 "register_operand" ""))
19688 (clobber (match_operand 1 "register_operand" ""))
19689 (clobber (match_operand 2 "register_operand" ""))])
19690 (set (match_operand:QI 7 "register_operand" "")
19691 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19692 (set (match_operand:QI 8 "register_operand" "")
19693 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19694 (set (reg FLAGS_REG)
19695 (compare (match_dup 7) (match_dup 8)))
19697 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19699 (set (reg:CC FLAGS_REG)
19700 (if_then_else:CC (ne (match_dup 6)
19702 (compare:CC (mem:BLK (match_dup 4))
19703 (mem:BLK (match_dup 5)))
19705 (use (match_dup 3))
19706 (use (reg:CC FLAGS_REG))
19707 (clobber (match_dup 0))
19708 (clobber (match_dup 1))
19709 (clobber (match_dup 2))])]
19714 ;; Conditional move instructions.
19716 (define_expand "movdicc"
19717 [(set (match_operand:DI 0 "register_operand" "")
19718 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19719 (match_operand:DI 2 "general_operand" "")
19720 (match_operand:DI 3 "general_operand" "")))]
19722 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19724 (define_insn "x86_movdicc_0_m1_rex64"
19725 [(set (match_operand:DI 0 "register_operand" "=r")
19726 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19729 (clobber (reg:CC FLAGS_REG))]
19732 ; Since we don't have the proper number of operands for an alu insn,
19733 ; fill in all the blanks.
19734 [(set_attr "type" "alu")
19735 (set_attr "pent_pair" "pu")
19736 (set_attr "memory" "none")
19737 (set_attr "imm_disp" "false")
19738 (set_attr "mode" "DI")
19739 (set_attr "length_immediate" "0")])
19741 (define_insn "*x86_movdicc_0_m1_se"
19742 [(set (match_operand:DI 0 "register_operand" "=r")
19743 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19746 (clobber (reg:CC FLAGS_REG))]
19749 [(set_attr "type" "alu")
19750 (set_attr "pent_pair" "pu")
19751 (set_attr "memory" "none")
19752 (set_attr "imm_disp" "false")
19753 (set_attr "mode" "DI")
19754 (set_attr "length_immediate" "0")])
19756 (define_insn "*movdicc_c_rex64"
19757 [(set (match_operand:DI 0 "register_operand" "=r,r")
19758 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19759 [(reg FLAGS_REG) (const_int 0)])
19760 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19761 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19762 "TARGET_64BIT && TARGET_CMOVE
19763 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19765 cmov%O2%C1\t{%2, %0|%0, %2}
19766 cmov%O2%c1\t{%3, %0|%0, %3}"
19767 [(set_attr "type" "icmov")
19768 (set_attr "mode" "DI")])
19770 (define_expand "movsicc"
19771 [(set (match_operand:SI 0 "register_operand" "")
19772 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19773 (match_operand:SI 2 "general_operand" "")
19774 (match_operand:SI 3 "general_operand" "")))]
19776 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19778 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19779 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19780 ;; So just document what we're doing explicitly.
19782 (define_insn "x86_movsicc_0_m1"
19783 [(set (match_operand:SI 0 "register_operand" "=r")
19784 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19787 (clobber (reg:CC FLAGS_REG))]
19790 ; Since we don't have the proper number of operands for an alu insn,
19791 ; fill in all the blanks.
19792 [(set_attr "type" "alu")
19793 (set_attr "pent_pair" "pu")
19794 (set_attr "memory" "none")
19795 (set_attr "imm_disp" "false")
19796 (set_attr "mode" "SI")
19797 (set_attr "length_immediate" "0")])
19799 (define_insn "*x86_movsicc_0_m1_se"
19800 [(set (match_operand:SI 0 "register_operand" "=r")
19801 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19804 (clobber (reg:CC FLAGS_REG))]
19807 [(set_attr "type" "alu")
19808 (set_attr "pent_pair" "pu")
19809 (set_attr "memory" "none")
19810 (set_attr "imm_disp" "false")
19811 (set_attr "mode" "SI")
19812 (set_attr "length_immediate" "0")])
19814 (define_insn "*movsicc_noc"
19815 [(set (match_operand:SI 0 "register_operand" "=r,r")
19816 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19817 [(reg FLAGS_REG) (const_int 0)])
19818 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19819 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19821 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19823 cmov%O2%C1\t{%2, %0|%0, %2}
19824 cmov%O2%c1\t{%3, %0|%0, %3}"
19825 [(set_attr "type" "icmov")
19826 (set_attr "mode" "SI")])
19828 (define_expand "movhicc"
19829 [(set (match_operand:HI 0 "register_operand" "")
19830 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19831 (match_operand:HI 2 "general_operand" "")
19832 (match_operand:HI 3 "general_operand" "")))]
19833 "TARGET_HIMODE_MATH"
19834 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19836 (define_insn "*movhicc_noc"
19837 [(set (match_operand:HI 0 "register_operand" "=r,r")
19838 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19839 [(reg FLAGS_REG) (const_int 0)])
19840 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19841 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19843 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19845 cmov%O2%C1\t{%2, %0|%0, %2}
19846 cmov%O2%c1\t{%3, %0|%0, %3}"
19847 [(set_attr "type" "icmov")
19848 (set_attr "mode" "HI")])
19850 (define_expand "movqicc"
19851 [(set (match_operand:QI 0 "register_operand" "")
19852 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19853 (match_operand:QI 2 "general_operand" "")
19854 (match_operand:QI 3 "general_operand" "")))]
19855 "TARGET_QIMODE_MATH"
19856 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19858 (define_insn_and_split "*movqicc_noc"
19859 [(set (match_operand:QI 0 "register_operand" "=r,r")
19860 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19861 [(match_operand 4 "flags_reg_operand" "")
19863 (match_operand:QI 2 "register_operand" "r,0")
19864 (match_operand:QI 3 "register_operand" "0,r")))]
19865 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19867 "&& reload_completed"
19868 [(set (match_dup 0)
19869 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19872 "operands[0] = gen_lowpart (SImode, operands[0]);
19873 operands[2] = gen_lowpart (SImode, operands[2]);
19874 operands[3] = gen_lowpart (SImode, operands[3]);"
19875 [(set_attr "type" "icmov")
19876 (set_attr "mode" "SI")])
19878 (define_expand "mov<mode>cc"
19879 [(set (match_operand:X87MODEF 0 "register_operand" "")
19880 (if_then_else:X87MODEF
19881 (match_operand 1 "comparison_operator" "")
19882 (match_operand:X87MODEF 2 "register_operand" "")
19883 (match_operand:X87MODEF 3 "register_operand" "")))]
19884 "(TARGET_80387 && TARGET_CMOVE)
19885 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19886 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19888 (define_insn "*movsfcc_1_387"
19889 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19890 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19891 [(reg FLAGS_REG) (const_int 0)])
19892 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19893 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19894 "TARGET_80387 && TARGET_CMOVE
19895 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19897 fcmov%F1\t{%2, %0|%0, %2}
19898 fcmov%f1\t{%3, %0|%0, %3}
19899 cmov%O2%C1\t{%2, %0|%0, %2}
19900 cmov%O2%c1\t{%3, %0|%0, %3}"
19901 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19902 (set_attr "mode" "SF,SF,SI,SI")])
19904 (define_insn "*movdfcc_1"
19905 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19906 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19907 [(reg FLAGS_REG) (const_int 0)])
19908 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19909 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19910 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19911 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19913 fcmov%F1\t{%2, %0|%0, %2}
19914 fcmov%f1\t{%3, %0|%0, %3}
19917 [(set_attr "type" "fcmov,fcmov,multi,multi")
19918 (set_attr "mode" "DF")])
19920 (define_insn "*movdfcc_1_rex64"
19921 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19922 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19923 [(reg FLAGS_REG) (const_int 0)])
19924 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19925 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19926 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19927 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19929 fcmov%F1\t{%2, %0|%0, %2}
19930 fcmov%f1\t{%3, %0|%0, %3}
19931 cmov%O2%C1\t{%2, %0|%0, %2}
19932 cmov%O2%c1\t{%3, %0|%0, %3}"
19933 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19934 (set_attr "mode" "DF")])
19937 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19938 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19939 [(match_operand 4 "flags_reg_operand" "")
19941 (match_operand:DF 2 "nonimmediate_operand" "")
19942 (match_operand:DF 3 "nonimmediate_operand" "")))]
19943 "!TARGET_64BIT && reload_completed"
19944 [(set (match_dup 2)
19945 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19949 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19952 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19953 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19955 (define_insn "*movxfcc_1"
19956 [(set (match_operand:XF 0 "register_operand" "=f,f")
19957 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19958 [(reg FLAGS_REG) (const_int 0)])
19959 (match_operand:XF 2 "register_operand" "f,0")
19960 (match_operand:XF 3 "register_operand" "0,f")))]
19961 "TARGET_80387 && TARGET_CMOVE"
19963 fcmov%F1\t{%2, %0|%0, %2}
19964 fcmov%f1\t{%3, %0|%0, %3}"
19965 [(set_attr "type" "fcmov")
19966 (set_attr "mode" "XF")])
19968 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19969 ;; the scalar versions to have only XMM registers as operands.
19971 ;; SSE5 conditional move
19972 (define_insn "*sse5_pcmov_<mode>"
19973 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19974 (if_then_else:MODEF
19975 (match_operand:MODEF 1 "register_operand" "x,0")
19976 (match_operand:MODEF 2 "register_operand" "0,x")
19977 (match_operand:MODEF 3 "register_operand" "x,x")))]
19978 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19979 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19980 [(set_attr "type" "sse4arg")])
19982 ;; These versions of the min/max patterns are intentionally ignorant of
19983 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19984 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19985 ;; are undefined in this condition, we're certain this is correct.
19987 (define_insn "*avx_<code><mode>3"
19988 [(set (match_operand:MODEF 0 "register_operand" "=x")
19990 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19991 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19992 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19993 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19994 [(set_attr "type" "sseadd")
19995 (set_attr "prefix" "vex")
19996 (set_attr "mode" "<MODE>")])
19998 (define_insn "<code><mode>3"
19999 [(set (match_operand:MODEF 0 "register_operand" "=x")
20001 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20002 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20003 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20004 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20005 [(set_attr "type" "sseadd")
20006 (set_attr "mode" "<MODE>")])
20008 ;; These versions of the min/max patterns implement exactly the operations
20009 ;; min = (op1 < op2 ? op1 : op2)
20010 ;; max = (!(op1 < op2) ? op1 : op2)
20011 ;; Their operands are not commutative, and thus they may be used in the
20012 ;; presence of -0.0 and NaN.
20014 (define_insn "*avx_ieee_smin<mode>3"
20015 [(set (match_operand:MODEF 0 "register_operand" "=x")
20017 [(match_operand:MODEF 1 "register_operand" "x")
20018 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20020 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20021 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20022 [(set_attr "type" "sseadd")
20023 (set_attr "prefix" "vex")
20024 (set_attr "mode" "<MODE>")])
20026 (define_insn "*ieee_smin<mode>3"
20027 [(set (match_operand:MODEF 0 "register_operand" "=x")
20029 [(match_operand:MODEF 1 "register_operand" "0")
20030 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20032 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20033 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20034 [(set_attr "type" "sseadd")
20035 (set_attr "mode" "<MODE>")])
20037 (define_insn "*avx_ieee_smax<mode>3"
20038 [(set (match_operand:MODEF 0 "register_operand" "=x")
20040 [(match_operand:MODEF 1 "register_operand" "0")
20041 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20043 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20044 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20045 [(set_attr "type" "sseadd")
20046 (set_attr "prefix" "vex")
20047 (set_attr "mode" "<MODE>")])
20049 (define_insn "*ieee_smax<mode>3"
20050 [(set (match_operand:MODEF 0 "register_operand" "=x")
20052 [(match_operand:MODEF 1 "register_operand" "0")
20053 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20055 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20056 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20057 [(set_attr "type" "sseadd")
20058 (set_attr "mode" "<MODE>")])
20060 ;; Make two stack loads independent:
20062 ;; fld %st(0) -> fld bb
20063 ;; fmul bb fmul %st(1), %st
20065 ;; Actually we only match the last two instructions for simplicity.
20067 [(set (match_operand 0 "fp_register_operand" "")
20068 (match_operand 1 "fp_register_operand" ""))
20070 (match_operator 2 "binary_fp_operator"
20072 (match_operand 3 "memory_operand" "")]))]
20073 "REGNO (operands[0]) != REGNO (operands[1])"
20074 [(set (match_dup 0) (match_dup 3))
20075 (set (match_dup 0) (match_dup 4))]
20077 ;; The % modifier is not operational anymore in peephole2's, so we have to
20078 ;; swap the operands manually in the case of addition and multiplication.
20079 "if (COMMUTATIVE_ARITH_P (operands[2]))
20080 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20081 operands[0], operands[1]);
20083 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20084 operands[1], operands[0]);")
20086 ;; Conditional addition patterns
20087 (define_expand "add<mode>cc"
20088 [(match_operand:SWI 0 "register_operand" "")
20089 (match_operand 1 "comparison_operator" "")
20090 (match_operand:SWI 2 "register_operand" "")
20091 (match_operand:SWI 3 "const_int_operand" "")]
20093 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20096 ;; Misc patterns (?)
20098 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20099 ;; Otherwise there will be nothing to keep
20101 ;; [(set (reg ebp) (reg esp))]
20102 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20103 ;; (clobber (eflags)]
20104 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20106 ;; in proper program order.
20107 (define_insn "pro_epilogue_adjust_stack_1"
20108 [(set (match_operand:SI 0 "register_operand" "=r,r")
20109 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20110 (match_operand:SI 2 "immediate_operand" "i,i")))
20111 (clobber (reg:CC FLAGS_REG))
20112 (clobber (mem:BLK (scratch)))]
20115 switch (get_attr_type (insn))
20118 return "mov{l}\t{%1, %0|%0, %1}";
20121 if (CONST_INT_P (operands[2])
20122 && (INTVAL (operands[2]) == 128
20123 || (INTVAL (operands[2]) < 0
20124 && INTVAL (operands[2]) != -128)))
20126 operands[2] = GEN_INT (-INTVAL (operands[2]));
20127 return "sub{l}\t{%2, %0|%0, %2}";
20129 return "add{l}\t{%2, %0|%0, %2}";
20132 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20133 return "lea{l}\t{%a2, %0|%0, %a2}";
20136 gcc_unreachable ();
20139 [(set (attr "type")
20140 (cond [(eq_attr "alternative" "0")
20141 (const_string "alu")
20142 (match_operand:SI 2 "const0_operand" "")
20143 (const_string "imov")
20145 (const_string "lea")))
20146 (set_attr "mode" "SI")])
20148 (define_insn "pro_epilogue_adjust_stack_rex64"
20149 [(set (match_operand:DI 0 "register_operand" "=r,r")
20150 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20151 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20152 (clobber (reg:CC FLAGS_REG))
20153 (clobber (mem:BLK (scratch)))]
20156 switch (get_attr_type (insn))
20159 return "mov{q}\t{%1, %0|%0, %1}";
20162 if (CONST_INT_P (operands[2])
20163 /* Avoid overflows. */
20164 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20165 && (INTVAL (operands[2]) == 128
20166 || (INTVAL (operands[2]) < 0
20167 && INTVAL (operands[2]) != -128)))
20169 operands[2] = GEN_INT (-INTVAL (operands[2]));
20170 return "sub{q}\t{%2, %0|%0, %2}";
20172 return "add{q}\t{%2, %0|%0, %2}";
20175 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20176 return "lea{q}\t{%a2, %0|%0, %a2}";
20179 gcc_unreachable ();
20182 [(set (attr "type")
20183 (cond [(eq_attr "alternative" "0")
20184 (const_string "alu")
20185 (match_operand:DI 2 "const0_operand" "")
20186 (const_string "imov")
20188 (const_string "lea")))
20189 (set_attr "mode" "DI")])
20191 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20192 [(set (match_operand:DI 0 "register_operand" "=r,r")
20193 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20194 (match_operand:DI 3 "immediate_operand" "i,i")))
20195 (use (match_operand:DI 2 "register_operand" "r,r"))
20196 (clobber (reg:CC FLAGS_REG))
20197 (clobber (mem:BLK (scratch)))]
20200 switch (get_attr_type (insn))
20203 return "add{q}\t{%2, %0|%0, %2}";
20206 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20207 return "lea{q}\t{%a2, %0|%0, %a2}";
20210 gcc_unreachable ();
20213 [(set_attr "type" "alu,lea")
20214 (set_attr "mode" "DI")])
20216 (define_insn "allocate_stack_worker_32"
20217 [(set (match_operand:SI 0 "register_operand" "=a")
20218 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20219 UNSPECV_STACK_PROBE))
20220 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20221 (clobber (reg:CC FLAGS_REG))]
20222 "!TARGET_64BIT && TARGET_STACK_PROBE"
20224 [(set_attr "type" "multi")
20225 (set_attr "length" "5")])
20227 (define_insn "allocate_stack_worker_64"
20228 [(set (match_operand:DI 0 "register_operand" "=a")
20229 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20230 UNSPECV_STACK_PROBE))
20231 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20232 (clobber (reg:DI R10_REG))
20233 (clobber (reg:DI R11_REG))
20234 (clobber (reg:CC FLAGS_REG))]
20235 "TARGET_64BIT && TARGET_STACK_PROBE"
20237 [(set_attr "type" "multi")
20238 (set_attr "length" "5")])
20240 (define_expand "allocate_stack"
20241 [(match_operand 0 "register_operand" "")
20242 (match_operand 1 "general_operand" "")]
20243 "TARGET_STACK_PROBE"
20247 #ifndef CHECK_STACK_LIMIT
20248 #define CHECK_STACK_LIMIT 0
20251 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20252 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20254 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20255 stack_pointer_rtx, 0, OPTAB_DIRECT);
20256 if (x != stack_pointer_rtx)
20257 emit_move_insn (stack_pointer_rtx, x);
20261 x = copy_to_mode_reg (Pmode, operands[1]);
20263 x = gen_allocate_stack_worker_64 (x, x);
20265 x = gen_allocate_stack_worker_32 (x, x);
20269 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20273 (define_expand "builtin_setjmp_receiver"
20274 [(label_ref (match_operand 0 "" ""))]
20275 "!TARGET_64BIT && flag_pic"
20281 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20282 rtx label_rtx = gen_label_rtx ();
20283 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20284 xops[0] = xops[1] = picreg;
20285 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20286 ix86_expand_binary_operator (MINUS, SImode, xops);
20290 emit_insn (gen_set_got (pic_offset_table_rtx));
20294 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20297 [(set (match_operand 0 "register_operand" "")
20298 (match_operator 3 "promotable_binary_operator"
20299 [(match_operand 1 "register_operand" "")
20300 (match_operand 2 "aligned_operand" "")]))
20301 (clobber (reg:CC FLAGS_REG))]
20302 "! TARGET_PARTIAL_REG_STALL && reload_completed
20303 && ((GET_MODE (operands[0]) == HImode
20304 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20305 /* ??? next two lines just !satisfies_constraint_K (...) */
20306 || !CONST_INT_P (operands[2])
20307 || satisfies_constraint_K (operands[2])))
20308 || (GET_MODE (operands[0]) == QImode
20309 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20310 [(parallel [(set (match_dup 0)
20311 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20312 (clobber (reg:CC FLAGS_REG))])]
20313 "operands[0] = gen_lowpart (SImode, operands[0]);
20314 operands[1] = gen_lowpart (SImode, operands[1]);
20315 if (GET_CODE (operands[3]) != ASHIFT)
20316 operands[2] = gen_lowpart (SImode, operands[2]);
20317 PUT_MODE (operands[3], SImode);")
20319 ; Promote the QImode tests, as i386 has encoding of the AND
20320 ; instruction with 32-bit sign-extended immediate and thus the
20321 ; instruction size is unchanged, except in the %eax case for
20322 ; which it is increased by one byte, hence the ! optimize_size.
20324 [(set (match_operand 0 "flags_reg_operand" "")
20325 (match_operator 2 "compare_operator"
20326 [(and (match_operand 3 "aligned_operand" "")
20327 (match_operand 4 "const_int_operand" ""))
20329 (set (match_operand 1 "register_operand" "")
20330 (and (match_dup 3) (match_dup 4)))]
20331 "! TARGET_PARTIAL_REG_STALL && reload_completed
20332 && optimize_insn_for_speed_p ()
20333 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20334 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20335 /* Ensure that the operand will remain sign-extended immediate. */
20336 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20337 [(parallel [(set (match_dup 0)
20338 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20341 (and:SI (match_dup 3) (match_dup 4)))])]
20344 = gen_int_mode (INTVAL (operands[4])
20345 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20346 operands[1] = gen_lowpart (SImode, operands[1]);
20347 operands[3] = gen_lowpart (SImode, operands[3]);
20350 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20351 ; the TEST instruction with 32-bit sign-extended immediate and thus
20352 ; the instruction size would at least double, which is not what we
20353 ; want even with ! optimize_size.
20355 [(set (match_operand 0 "flags_reg_operand" "")
20356 (match_operator 1 "compare_operator"
20357 [(and (match_operand:HI 2 "aligned_operand" "")
20358 (match_operand:HI 3 "const_int_operand" ""))
20360 "! TARGET_PARTIAL_REG_STALL && reload_completed
20361 && ! TARGET_FAST_PREFIX
20362 && optimize_insn_for_speed_p ()
20363 /* Ensure that the operand will remain sign-extended immediate. */
20364 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20365 [(set (match_dup 0)
20366 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20370 = gen_int_mode (INTVAL (operands[3])
20371 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20372 operands[2] = gen_lowpart (SImode, operands[2]);
20376 [(set (match_operand 0 "register_operand" "")
20377 (neg (match_operand 1 "register_operand" "")))
20378 (clobber (reg:CC FLAGS_REG))]
20379 "! TARGET_PARTIAL_REG_STALL && reload_completed
20380 && (GET_MODE (operands[0]) == HImode
20381 || (GET_MODE (operands[0]) == QImode
20382 && (TARGET_PROMOTE_QImode
20383 || optimize_insn_for_size_p ())))"
20384 [(parallel [(set (match_dup 0)
20385 (neg:SI (match_dup 1)))
20386 (clobber (reg:CC FLAGS_REG))])]
20387 "operands[0] = gen_lowpart (SImode, operands[0]);
20388 operands[1] = gen_lowpart (SImode, operands[1]);")
20391 [(set (match_operand 0 "register_operand" "")
20392 (not (match_operand 1 "register_operand" "")))]
20393 "! TARGET_PARTIAL_REG_STALL && reload_completed
20394 && (GET_MODE (operands[0]) == HImode
20395 || (GET_MODE (operands[0]) == QImode
20396 && (TARGET_PROMOTE_QImode
20397 || optimize_insn_for_size_p ())))"
20398 [(set (match_dup 0)
20399 (not:SI (match_dup 1)))]
20400 "operands[0] = gen_lowpart (SImode, operands[0]);
20401 operands[1] = gen_lowpart (SImode, operands[1]);")
20404 [(set (match_operand 0 "register_operand" "")
20405 (if_then_else (match_operator 1 "comparison_operator"
20406 [(reg FLAGS_REG) (const_int 0)])
20407 (match_operand 2 "register_operand" "")
20408 (match_operand 3 "register_operand" "")))]
20409 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20410 && (GET_MODE (operands[0]) == HImode
20411 || (GET_MODE (operands[0]) == QImode
20412 && (TARGET_PROMOTE_QImode
20413 || optimize_insn_for_size_p ())))"
20414 [(set (match_dup 0)
20415 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20416 "operands[0] = gen_lowpart (SImode, operands[0]);
20417 operands[2] = gen_lowpart (SImode, operands[2]);
20418 operands[3] = gen_lowpart (SImode, operands[3]);")
20421 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20422 ;; transform a complex memory operation into two memory to register operations.
20424 ;; Don't push memory operands
20426 [(set (match_operand:SI 0 "push_operand" "")
20427 (match_operand:SI 1 "memory_operand" ""))
20428 (match_scratch:SI 2 "r")]
20429 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20430 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20431 [(set (match_dup 2) (match_dup 1))
20432 (set (match_dup 0) (match_dup 2))]
20436 [(set (match_operand:DI 0 "push_operand" "")
20437 (match_operand:DI 1 "memory_operand" ""))
20438 (match_scratch:DI 2 "r")]
20439 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20440 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20441 [(set (match_dup 2) (match_dup 1))
20442 (set (match_dup 0) (match_dup 2))]
20445 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20448 [(set (match_operand:SF 0 "push_operand" "")
20449 (match_operand:SF 1 "memory_operand" ""))
20450 (match_scratch:SF 2 "r")]
20451 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20452 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20453 [(set (match_dup 2) (match_dup 1))
20454 (set (match_dup 0) (match_dup 2))]
20458 [(set (match_operand:HI 0 "push_operand" "")
20459 (match_operand:HI 1 "memory_operand" ""))
20460 (match_scratch:HI 2 "r")]
20461 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20462 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20463 [(set (match_dup 2) (match_dup 1))
20464 (set (match_dup 0) (match_dup 2))]
20468 [(set (match_operand:QI 0 "push_operand" "")
20469 (match_operand:QI 1 "memory_operand" ""))
20470 (match_scratch:QI 2 "q")]
20471 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20472 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20473 [(set (match_dup 2) (match_dup 1))
20474 (set (match_dup 0) (match_dup 2))]
20477 ;; Don't move an immediate directly to memory when the instruction
20480 [(match_scratch:SI 1 "r")
20481 (set (match_operand:SI 0 "memory_operand" "")
20483 "optimize_insn_for_speed_p ()
20484 && ! TARGET_USE_MOV0
20485 && TARGET_SPLIT_LONG_MOVES
20486 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20487 && peep2_regno_dead_p (0, FLAGS_REG)"
20488 [(parallel [(set (match_dup 1) (const_int 0))
20489 (clobber (reg:CC FLAGS_REG))])
20490 (set (match_dup 0) (match_dup 1))]
20494 [(match_scratch:HI 1 "r")
20495 (set (match_operand:HI 0 "memory_operand" "")
20497 "optimize_insn_for_speed_p ()
20498 && ! TARGET_USE_MOV0
20499 && TARGET_SPLIT_LONG_MOVES
20500 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20501 && peep2_regno_dead_p (0, FLAGS_REG)"
20502 [(parallel [(set (match_dup 2) (const_int 0))
20503 (clobber (reg:CC FLAGS_REG))])
20504 (set (match_dup 0) (match_dup 1))]
20505 "operands[2] = gen_lowpart (SImode, operands[1]);")
20508 [(match_scratch:QI 1 "q")
20509 (set (match_operand:QI 0 "memory_operand" "")
20511 "optimize_insn_for_speed_p ()
20512 && ! TARGET_USE_MOV0
20513 && TARGET_SPLIT_LONG_MOVES
20514 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20515 && peep2_regno_dead_p (0, FLAGS_REG)"
20516 [(parallel [(set (match_dup 2) (const_int 0))
20517 (clobber (reg:CC FLAGS_REG))])
20518 (set (match_dup 0) (match_dup 1))]
20519 "operands[2] = gen_lowpart (SImode, operands[1]);")
20522 [(match_scratch:SI 2 "r")
20523 (set (match_operand:SI 0 "memory_operand" "")
20524 (match_operand:SI 1 "immediate_operand" ""))]
20525 "optimize_insn_for_speed_p ()
20526 && TARGET_SPLIT_LONG_MOVES
20527 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20528 [(set (match_dup 2) (match_dup 1))
20529 (set (match_dup 0) (match_dup 2))]
20533 [(match_scratch:HI 2 "r")
20534 (set (match_operand:HI 0 "memory_operand" "")
20535 (match_operand:HI 1 "immediate_operand" ""))]
20536 "optimize_insn_for_speed_p ()
20537 && TARGET_SPLIT_LONG_MOVES
20538 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20539 [(set (match_dup 2) (match_dup 1))
20540 (set (match_dup 0) (match_dup 2))]
20544 [(match_scratch:QI 2 "q")
20545 (set (match_operand:QI 0 "memory_operand" "")
20546 (match_operand:QI 1 "immediate_operand" ""))]
20547 "optimize_insn_for_speed_p ()
20548 && TARGET_SPLIT_LONG_MOVES
20549 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20550 [(set (match_dup 2) (match_dup 1))
20551 (set (match_dup 0) (match_dup 2))]
20554 ;; Don't compare memory with zero, load and use a test instead.
20556 [(set (match_operand 0 "flags_reg_operand" "")
20557 (match_operator 1 "compare_operator"
20558 [(match_operand:SI 2 "memory_operand" "")
20560 (match_scratch:SI 3 "r")]
20561 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20562 [(set (match_dup 3) (match_dup 2))
20563 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20566 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20567 ;; Don't split NOTs with a displacement operand, because resulting XOR
20568 ;; will not be pairable anyway.
20570 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20571 ;; represented using a modRM byte. The XOR replacement is long decoded,
20572 ;; so this split helps here as well.
20574 ;; Note: Can't do this as a regular split because we can't get proper
20575 ;; lifetime information then.
20578 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20579 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20580 "optimize_insn_for_speed_p ()
20581 && ((TARGET_NOT_UNPAIRABLE
20582 && (!MEM_P (operands[0])
20583 || !memory_displacement_operand (operands[0], SImode)))
20584 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20585 && peep2_regno_dead_p (0, FLAGS_REG)"
20586 [(parallel [(set (match_dup 0)
20587 (xor:SI (match_dup 1) (const_int -1)))
20588 (clobber (reg:CC FLAGS_REG))])]
20592 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20593 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20594 "optimize_insn_for_speed_p ()
20595 && ((TARGET_NOT_UNPAIRABLE
20596 && (!MEM_P (operands[0])
20597 || !memory_displacement_operand (operands[0], HImode)))
20598 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20599 && peep2_regno_dead_p (0, FLAGS_REG)"
20600 [(parallel [(set (match_dup 0)
20601 (xor:HI (match_dup 1) (const_int -1)))
20602 (clobber (reg:CC FLAGS_REG))])]
20606 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20607 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20608 "optimize_insn_for_speed_p ()
20609 && ((TARGET_NOT_UNPAIRABLE
20610 && (!MEM_P (operands[0])
20611 || !memory_displacement_operand (operands[0], QImode)))
20612 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20613 && peep2_regno_dead_p (0, FLAGS_REG)"
20614 [(parallel [(set (match_dup 0)
20615 (xor:QI (match_dup 1) (const_int -1)))
20616 (clobber (reg:CC FLAGS_REG))])]
20619 ;; Non pairable "test imm, reg" instructions can be translated to
20620 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20621 ;; byte opcode instead of two, have a short form for byte operands),
20622 ;; so do it for other CPUs as well. Given that the value was dead,
20623 ;; this should not create any new dependencies. Pass on the sub-word
20624 ;; versions if we're concerned about partial register stalls.
20627 [(set (match_operand 0 "flags_reg_operand" "")
20628 (match_operator 1 "compare_operator"
20629 [(and:SI (match_operand:SI 2 "register_operand" "")
20630 (match_operand:SI 3 "immediate_operand" ""))
20632 "ix86_match_ccmode (insn, CCNOmode)
20633 && (true_regnum (operands[2]) != AX_REG
20634 || satisfies_constraint_K (operands[3]))
20635 && peep2_reg_dead_p (1, operands[2])"
20637 [(set (match_dup 0)
20638 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20641 (and:SI (match_dup 2) (match_dup 3)))])]
20644 ;; We don't need to handle HImode case, because it will be promoted to SImode
20645 ;; on ! TARGET_PARTIAL_REG_STALL
20648 [(set (match_operand 0 "flags_reg_operand" "")
20649 (match_operator 1 "compare_operator"
20650 [(and:QI (match_operand:QI 2 "register_operand" "")
20651 (match_operand:QI 3 "immediate_operand" ""))
20653 "! TARGET_PARTIAL_REG_STALL
20654 && ix86_match_ccmode (insn, CCNOmode)
20655 && true_regnum (operands[2]) != AX_REG
20656 && peep2_reg_dead_p (1, operands[2])"
20658 [(set (match_dup 0)
20659 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20662 (and:QI (match_dup 2) (match_dup 3)))])]
20666 [(set (match_operand 0 "flags_reg_operand" "")
20667 (match_operator 1 "compare_operator"
20670 (match_operand 2 "ext_register_operand" "")
20673 (match_operand 3 "const_int_operand" ""))
20675 "! TARGET_PARTIAL_REG_STALL
20676 && ix86_match_ccmode (insn, CCNOmode)
20677 && true_regnum (operands[2]) != AX_REG
20678 && peep2_reg_dead_p (1, operands[2])"
20679 [(parallel [(set (match_dup 0)
20688 (set (zero_extract:SI (match_dup 2)
20699 ;; Don't do logical operations with memory inputs.
20701 [(match_scratch:SI 2 "r")
20702 (parallel [(set (match_operand:SI 0 "register_operand" "")
20703 (match_operator:SI 3 "arith_or_logical_operator"
20705 (match_operand:SI 1 "memory_operand" "")]))
20706 (clobber (reg:CC FLAGS_REG))])]
20707 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20708 [(set (match_dup 2) (match_dup 1))
20709 (parallel [(set (match_dup 0)
20710 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20711 (clobber (reg:CC FLAGS_REG))])]
20715 [(match_scratch:SI 2 "r")
20716 (parallel [(set (match_operand:SI 0 "register_operand" "")
20717 (match_operator:SI 3 "arith_or_logical_operator"
20718 [(match_operand:SI 1 "memory_operand" "")
20720 (clobber (reg:CC FLAGS_REG))])]
20721 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20722 [(set (match_dup 2) (match_dup 1))
20723 (parallel [(set (match_dup 0)
20724 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20725 (clobber (reg:CC FLAGS_REG))])]
20728 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20729 ;; refers to the destination of the load!
20732 [(set (match_operand:SI 0 "register_operand" "")
20733 (match_operand:SI 1 "register_operand" ""))
20734 (parallel [(set (match_dup 0)
20735 (match_operator:SI 3 "commutative_operator"
20737 (match_operand:SI 2 "memory_operand" "")]))
20738 (clobber (reg:CC FLAGS_REG))])]
20739 "operands[0] != operands[1]
20740 && GENERAL_REGNO_P (REGNO (operands[0]))
20741 && GENERAL_REGNO_P (REGNO (operands[1]))"
20742 [(set (match_dup 0) (match_dup 4))
20743 (parallel [(set (match_dup 0)
20744 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20745 (clobber (reg:CC FLAGS_REG))])]
20746 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20749 [(set (match_operand 0 "register_operand" "")
20750 (match_operand 1 "register_operand" ""))
20752 (match_operator 3 "commutative_operator"
20754 (match_operand 2 "memory_operand" "")]))]
20755 "operands[0] != operands[1]
20756 && (MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
20757 [(set (match_dup 0) (match_dup 2))
20759 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20762 ; Don't do logical operations with memory outputs
20764 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20765 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20766 ; the same decoder scheduling characteristics as the original.
20769 [(match_scratch:SI 2 "r")
20770 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20771 (match_operator:SI 3 "arith_or_logical_operator"
20773 (match_operand:SI 1 "nonmemory_operand" "")]))
20774 (clobber (reg:CC FLAGS_REG))])]
20775 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20776 [(set (match_dup 2) (match_dup 0))
20777 (parallel [(set (match_dup 2)
20778 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20779 (clobber (reg:CC FLAGS_REG))])
20780 (set (match_dup 0) (match_dup 2))]
20784 [(match_scratch:SI 2 "r")
20785 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20786 (match_operator:SI 3 "arith_or_logical_operator"
20787 [(match_operand:SI 1 "nonmemory_operand" "")
20789 (clobber (reg:CC FLAGS_REG))])]
20790 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20791 [(set (match_dup 2) (match_dup 0))
20792 (parallel [(set (match_dup 2)
20793 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20794 (clobber (reg:CC FLAGS_REG))])
20795 (set (match_dup 0) (match_dup 2))]
20798 ;; Attempt to always use XOR for zeroing registers.
20800 [(set (match_operand 0 "register_operand" "")
20801 (match_operand 1 "const0_operand" ""))]
20802 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20803 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20804 && GENERAL_REG_P (operands[0])
20805 && peep2_regno_dead_p (0, FLAGS_REG)"
20806 [(parallel [(set (match_dup 0) (const_int 0))
20807 (clobber (reg:CC FLAGS_REG))])]
20809 operands[0] = gen_lowpart (word_mode, operands[0]);
20813 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20815 "(GET_MODE (operands[0]) == QImode
20816 || GET_MODE (operands[0]) == HImode)
20817 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20818 && peep2_regno_dead_p (0, FLAGS_REG)"
20819 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20820 (clobber (reg:CC FLAGS_REG))])])
20822 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20824 [(set (match_operand 0 "register_operand" "")
20826 "(GET_MODE (operands[0]) == HImode
20827 || GET_MODE (operands[0]) == SImode
20828 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20829 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20830 && peep2_regno_dead_p (0, FLAGS_REG)"
20831 [(parallel [(set (match_dup 0) (const_int -1))
20832 (clobber (reg:CC FLAGS_REG))])]
20833 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20836 ;; Attempt to convert simple leas to adds. These can be created by
20839 [(set (match_operand:SI 0 "register_operand" "")
20840 (plus:SI (match_dup 0)
20841 (match_operand:SI 1 "nonmemory_operand" "")))]
20842 "peep2_regno_dead_p (0, FLAGS_REG)"
20843 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20844 (clobber (reg:CC FLAGS_REG))])]
20848 [(set (match_operand:SI 0 "register_operand" "")
20849 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20850 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20851 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20852 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20853 (clobber (reg:CC FLAGS_REG))])]
20854 "operands[2] = gen_lowpart (SImode, operands[2]);")
20857 [(set (match_operand:DI 0 "register_operand" "")
20858 (plus:DI (match_dup 0)
20859 (match_operand:DI 1 "x86_64_general_operand" "")))]
20860 "peep2_regno_dead_p (0, FLAGS_REG)"
20861 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20862 (clobber (reg:CC FLAGS_REG))])]
20866 [(set (match_operand:SI 0 "register_operand" "")
20867 (mult:SI (match_dup 0)
20868 (match_operand:SI 1 "const_int_operand" "")))]
20869 "exact_log2 (INTVAL (operands[1])) >= 0
20870 && peep2_regno_dead_p (0, FLAGS_REG)"
20871 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20872 (clobber (reg:CC FLAGS_REG))])]
20873 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20876 [(set (match_operand:DI 0 "register_operand" "")
20877 (mult:DI (match_dup 0)
20878 (match_operand:DI 1 "const_int_operand" "")))]
20879 "exact_log2 (INTVAL (operands[1])) >= 0
20880 && peep2_regno_dead_p (0, FLAGS_REG)"
20881 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20882 (clobber (reg:CC FLAGS_REG))])]
20883 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20886 [(set (match_operand:SI 0 "register_operand" "")
20887 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20888 (match_operand:DI 2 "const_int_operand" "")) 0))]
20889 "exact_log2 (INTVAL (operands[2])) >= 0
20890 && REGNO (operands[0]) == REGNO (operands[1])
20891 && peep2_regno_dead_p (0, FLAGS_REG)"
20892 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20893 (clobber (reg:CC FLAGS_REG))])]
20894 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20896 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20897 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20898 ;; many CPUs it is also faster, since special hardware to avoid esp
20899 ;; dependencies is present.
20901 ;; While some of these conversions may be done using splitters, we use peepholes
20902 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20904 ;; Convert prologue esp subtractions to push.
20905 ;; We need register to push. In order to keep verify_flow_info happy we have
20907 ;; - use scratch and clobber it in order to avoid dependencies
20908 ;; - use already live register
20909 ;; We can't use the second way right now, since there is no reliable way how to
20910 ;; verify that given register is live. First choice will also most likely in
20911 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20912 ;; call clobbered registers are dead. We may want to use base pointer as an
20913 ;; alternative when no register is available later.
20916 [(match_scratch:SI 0 "r")
20917 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20918 (clobber (reg:CC FLAGS_REG))
20919 (clobber (mem:BLK (scratch)))])]
20920 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20921 [(clobber (match_dup 0))
20922 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20923 (clobber (mem:BLK (scratch)))])])
20926 [(match_scratch:SI 0 "r")
20927 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20928 (clobber (reg:CC FLAGS_REG))
20929 (clobber (mem:BLK (scratch)))])]
20930 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20931 [(clobber (match_dup 0))
20932 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20933 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20934 (clobber (mem:BLK (scratch)))])])
20936 ;; Convert esp subtractions to push.
20938 [(match_scratch:SI 0 "r")
20939 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20940 (clobber (reg:CC FLAGS_REG))])]
20941 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20942 [(clobber (match_dup 0))
20943 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20946 [(match_scratch:SI 0 "r")
20947 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20948 (clobber (reg:CC FLAGS_REG))])]
20949 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20950 [(clobber (match_dup 0))
20951 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20952 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20954 ;; Convert epilogue deallocator to pop.
20956 [(match_scratch:SI 0 "r")
20957 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20958 (clobber (reg:CC FLAGS_REG))
20959 (clobber (mem:BLK (scratch)))])]
20960 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20961 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20963 (clobber (mem:BLK (scratch)))])]
20966 ;; Two pops case is tricky, since pop causes dependency on destination register.
20967 ;; We use two registers if available.
20969 [(match_scratch:SI 0 "r")
20970 (match_scratch:SI 1 "r")
20971 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20972 (clobber (reg:CC FLAGS_REG))
20973 (clobber (mem:BLK (scratch)))])]
20974 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20975 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20976 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20977 (clobber (mem:BLK (scratch)))])
20978 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20979 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20983 [(match_scratch:SI 0 "r")
20984 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20985 (clobber (reg:CC FLAGS_REG))
20986 (clobber (mem:BLK (scratch)))])]
20987 "optimize_insn_for_size_p ()"
20988 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20989 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20990 (clobber (mem:BLK (scratch)))])
20991 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20992 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20995 ;; Convert esp additions to pop.
20997 [(match_scratch:SI 0 "r")
20998 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20999 (clobber (reg:CC FLAGS_REG))])]
21001 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21002 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21005 ;; Two pops case is tricky, since pop causes dependency on destination register.
21006 ;; We use two registers if available.
21008 [(match_scratch:SI 0 "r")
21009 (match_scratch:SI 1 "r")
21010 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21011 (clobber (reg:CC FLAGS_REG))])]
21013 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21014 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21015 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21016 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21020 [(match_scratch:SI 0 "r")
21021 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21022 (clobber (reg:CC FLAGS_REG))])]
21023 "optimize_insn_for_size_p ()"
21024 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21025 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21026 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21027 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21030 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21031 ;; required and register dies. Similarly for 128 to -128.
21033 [(set (match_operand 0 "flags_reg_operand" "")
21034 (match_operator 1 "compare_operator"
21035 [(match_operand 2 "register_operand" "")
21036 (match_operand 3 "const_int_operand" "")]))]
21037 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21038 && incdec_operand (operands[3], GET_MODE (operands[3])))
21039 || (!TARGET_FUSE_CMP_AND_BRANCH
21040 && INTVAL (operands[3]) == 128))
21041 && ix86_match_ccmode (insn, CCGCmode)
21042 && peep2_reg_dead_p (1, operands[2])"
21043 [(parallel [(set (match_dup 0)
21044 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21045 (clobber (match_dup 2))])]
21049 [(match_scratch:DI 0 "r")
21050 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21051 (clobber (reg:CC FLAGS_REG))
21052 (clobber (mem:BLK (scratch)))])]
21053 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21054 [(clobber (match_dup 0))
21055 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21056 (clobber (mem:BLK (scratch)))])])
21059 [(match_scratch:DI 0 "r")
21060 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21061 (clobber (reg:CC FLAGS_REG))
21062 (clobber (mem:BLK (scratch)))])]
21063 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21064 [(clobber (match_dup 0))
21065 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21066 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21067 (clobber (mem:BLK (scratch)))])])
21069 ;; Convert esp subtractions to push.
21071 [(match_scratch:DI 0 "r")
21072 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21073 (clobber (reg:CC FLAGS_REG))])]
21074 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21075 [(clobber (match_dup 0))
21076 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21079 [(match_scratch:DI 0 "r")
21080 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21081 (clobber (reg:CC FLAGS_REG))])]
21082 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21083 [(clobber (match_dup 0))
21084 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21085 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21087 ;; Convert epilogue deallocator to pop.
21089 [(match_scratch:DI 0 "r")
21090 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21091 (clobber (reg:CC FLAGS_REG))
21092 (clobber (mem:BLK (scratch)))])]
21093 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21094 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21095 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21096 (clobber (mem:BLK (scratch)))])]
21099 ;; Two pops case is tricky, since pop causes dependency on destination register.
21100 ;; We use two registers if available.
21102 [(match_scratch:DI 0 "r")
21103 (match_scratch:DI 1 "r")
21104 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21105 (clobber (reg:CC FLAGS_REG))
21106 (clobber (mem:BLK (scratch)))])]
21107 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21108 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21109 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21110 (clobber (mem:BLK (scratch)))])
21111 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21112 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21116 [(match_scratch:DI 0 "r")
21117 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21118 (clobber (reg:CC FLAGS_REG))
21119 (clobber (mem:BLK (scratch)))])]
21120 "optimize_insn_for_size_p ()"
21121 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21122 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21123 (clobber (mem:BLK (scratch)))])
21124 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21125 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21128 ;; Convert esp additions to pop.
21130 [(match_scratch:DI 0 "r")
21131 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21132 (clobber (reg:CC FLAGS_REG))])]
21134 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21135 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21138 ;; Two pops case is tricky, since pop causes dependency on destination register.
21139 ;; We use two registers if available.
21141 [(match_scratch:DI 0 "r")
21142 (match_scratch:DI 1 "r")
21143 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21144 (clobber (reg:CC FLAGS_REG))])]
21146 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21147 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21148 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21149 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21153 [(match_scratch:DI 0 "r")
21154 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21155 (clobber (reg:CC FLAGS_REG))])]
21156 "optimize_insn_for_size_p ()"
21157 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21158 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21159 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21160 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21163 ;; Convert imul by three, five and nine into lea
21166 [(set (match_operand:SI 0 "register_operand" "")
21167 (mult:SI (match_operand:SI 1 "register_operand" "")
21168 (match_operand:SI 2 "const_int_operand" "")))
21169 (clobber (reg:CC FLAGS_REG))])]
21170 "INTVAL (operands[2]) == 3
21171 || INTVAL (operands[2]) == 5
21172 || INTVAL (operands[2]) == 9"
21173 [(set (match_dup 0)
21174 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21176 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21180 [(set (match_operand:SI 0 "register_operand" "")
21181 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21182 (match_operand:SI 2 "const_int_operand" "")))
21183 (clobber (reg:CC FLAGS_REG))])]
21184 "optimize_insn_for_speed_p ()
21185 && (INTVAL (operands[2]) == 3
21186 || INTVAL (operands[2]) == 5
21187 || INTVAL (operands[2]) == 9)"
21188 [(set (match_dup 0) (match_dup 1))
21190 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21192 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21196 [(set (match_operand:DI 0 "register_operand" "")
21197 (mult:DI (match_operand:DI 1 "register_operand" "")
21198 (match_operand:DI 2 "const_int_operand" "")))
21199 (clobber (reg:CC FLAGS_REG))])]
21201 && (INTVAL (operands[2]) == 3
21202 || INTVAL (operands[2]) == 5
21203 || INTVAL (operands[2]) == 9)"
21204 [(set (match_dup 0)
21205 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21207 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21211 [(set (match_operand:DI 0 "register_operand" "")
21212 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21213 (match_operand:DI 2 "const_int_operand" "")))
21214 (clobber (reg:CC FLAGS_REG))])]
21216 && optimize_insn_for_speed_p ()
21217 && (INTVAL (operands[2]) == 3
21218 || INTVAL (operands[2]) == 5
21219 || INTVAL (operands[2]) == 9)"
21220 [(set (match_dup 0) (match_dup 1))
21222 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21224 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21226 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21227 ;; imul $32bit_imm, reg, reg is direct decoded.
21229 [(match_scratch:DI 3 "r")
21230 (parallel [(set (match_operand:DI 0 "register_operand" "")
21231 (mult:DI (match_operand:DI 1 "memory_operand" "")
21232 (match_operand:DI 2 "immediate_operand" "")))
21233 (clobber (reg:CC FLAGS_REG))])]
21234 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21235 && !satisfies_constraint_K (operands[2])"
21236 [(set (match_dup 3) (match_dup 1))
21237 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21238 (clobber (reg:CC FLAGS_REG))])]
21242 [(match_scratch:SI 3 "r")
21243 (parallel [(set (match_operand:SI 0 "register_operand" "")
21244 (mult:SI (match_operand:SI 1 "memory_operand" "")
21245 (match_operand:SI 2 "immediate_operand" "")))
21246 (clobber (reg:CC FLAGS_REG))])]
21247 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21248 && !satisfies_constraint_K (operands[2])"
21249 [(set (match_dup 3) (match_dup 1))
21250 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21251 (clobber (reg:CC FLAGS_REG))])]
21255 [(match_scratch:SI 3 "r")
21256 (parallel [(set (match_operand:DI 0 "register_operand" "")
21258 (mult:SI (match_operand:SI 1 "memory_operand" "")
21259 (match_operand:SI 2 "immediate_operand" ""))))
21260 (clobber (reg:CC FLAGS_REG))])]
21261 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21262 && !satisfies_constraint_K (operands[2])"
21263 [(set (match_dup 3) (match_dup 1))
21264 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21265 (clobber (reg:CC FLAGS_REG))])]
21268 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21269 ;; Convert it into imul reg, reg
21270 ;; It would be better to force assembler to encode instruction using long
21271 ;; immediate, but there is apparently no way to do so.
21273 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21274 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21275 (match_operand:DI 2 "const_int_operand" "")))
21276 (clobber (reg:CC FLAGS_REG))])
21277 (match_scratch:DI 3 "r")]
21278 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21279 && satisfies_constraint_K (operands[2])"
21280 [(set (match_dup 3) (match_dup 2))
21281 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21282 (clobber (reg:CC FLAGS_REG))])]
21284 if (!rtx_equal_p (operands[0], operands[1]))
21285 emit_move_insn (operands[0], operands[1]);
21289 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21290 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21291 (match_operand:SI 2 "const_int_operand" "")))
21292 (clobber (reg:CC FLAGS_REG))])
21293 (match_scratch:SI 3 "r")]
21294 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21295 && satisfies_constraint_K (operands[2])"
21296 [(set (match_dup 3) (match_dup 2))
21297 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21298 (clobber (reg:CC FLAGS_REG))])]
21300 if (!rtx_equal_p (operands[0], operands[1]))
21301 emit_move_insn (operands[0], operands[1]);
21305 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21306 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21307 (match_operand:HI 2 "immediate_operand" "")))
21308 (clobber (reg:CC FLAGS_REG))])
21309 (match_scratch:HI 3 "r")]
21310 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21311 [(set (match_dup 3) (match_dup 2))
21312 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21313 (clobber (reg:CC FLAGS_REG))])]
21315 if (!rtx_equal_p (operands[0], operands[1]))
21316 emit_move_insn (operands[0], operands[1]);
21319 ;; After splitting up read-modify operations, array accesses with memory
21320 ;; operands might end up in form:
21322 ;; movl 4(%esp), %edx
21324 ;; instead of pre-splitting:
21326 ;; addl 4(%esp), %eax
21328 ;; movl 4(%esp), %edx
21329 ;; leal (%edx,%eax,4), %eax
21332 [(parallel [(set (match_operand 0 "register_operand" "")
21333 (ashift (match_operand 1 "register_operand" "")
21334 (match_operand 2 "const_int_operand" "")))
21335 (clobber (reg:CC FLAGS_REG))])
21336 (set (match_operand 3 "register_operand")
21337 (match_operand 4 "x86_64_general_operand" ""))
21338 (parallel [(set (match_operand 5 "register_operand" "")
21339 (plus (match_operand 6 "register_operand" "")
21340 (match_operand 7 "register_operand" "")))
21341 (clobber (reg:CC FLAGS_REG))])]
21342 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21343 /* Validate MODE for lea. */
21344 && ((!TARGET_PARTIAL_REG_STALL
21345 && (GET_MODE (operands[0]) == QImode
21346 || GET_MODE (operands[0]) == HImode))
21347 || GET_MODE (operands[0]) == SImode
21348 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21349 /* We reorder load and the shift. */
21350 && !rtx_equal_p (operands[1], operands[3])
21351 && !reg_overlap_mentioned_p (operands[0], operands[4])
21352 /* Last PLUS must consist of operand 0 and 3. */
21353 && !rtx_equal_p (operands[0], operands[3])
21354 && (rtx_equal_p (operands[3], operands[6])
21355 || rtx_equal_p (operands[3], operands[7]))
21356 && (rtx_equal_p (operands[0], operands[6])
21357 || rtx_equal_p (operands[0], operands[7]))
21358 /* The intermediate operand 0 must die or be same as output. */
21359 && (rtx_equal_p (operands[0], operands[5])
21360 || peep2_reg_dead_p (3, operands[0]))"
21361 [(set (match_dup 3) (match_dup 4))
21362 (set (match_dup 0) (match_dup 1))]
21364 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21365 int scale = 1 << INTVAL (operands[2]);
21366 rtx index = gen_lowpart (Pmode, operands[1]);
21367 rtx base = gen_lowpart (Pmode, operands[3]);
21368 rtx dest = gen_lowpart (mode, operands[5]);
21370 operands[1] = gen_rtx_PLUS (Pmode, base,
21371 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21373 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21374 operands[0] = dest;
21377 ;; Call-value patterns last so that the wildcard operand does not
21378 ;; disrupt insn-recog's switch tables.
21380 (define_insn "*call_value_pop_0"
21381 [(set (match_operand 0 "" "")
21382 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21383 (match_operand:SI 2 "" "")))
21384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21385 (match_operand:SI 3 "immediate_operand" "")))]
21388 if (SIBLING_CALL_P (insn))
21391 return "call\t%P1";
21393 [(set_attr "type" "callv")])
21395 (define_insn "*call_value_pop_1"
21396 [(set (match_operand 0 "" "")
21397 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21398 (match_operand:SI 2 "" "")))
21399 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21400 (match_operand:SI 3 "immediate_operand" "i")))]
21403 if (constant_call_address_operand (operands[1], Pmode))
21405 if (SIBLING_CALL_P (insn))
21408 return "call\t%P1";
21410 if (SIBLING_CALL_P (insn))
21413 return "call\t%A1";
21415 [(set_attr "type" "callv")])
21417 (define_insn "*call_value_0"
21418 [(set (match_operand 0 "" "")
21419 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21420 (match_operand:SI 2 "" "")))]
21423 if (SIBLING_CALL_P (insn))
21426 return "call\t%P1";
21428 [(set_attr "type" "callv")])
21430 (define_insn "*call_value_0_rex64"
21431 [(set (match_operand 0 "" "")
21432 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21433 (match_operand:DI 2 "const_int_operand" "")))]
21436 if (SIBLING_CALL_P (insn))
21439 return "call\t%P1";
21441 [(set_attr "type" "callv")])
21443 (define_insn "*call_value_0_rex64_ms_sysv"
21444 [(set (match_operand 0 "" "")
21445 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21446 (match_operand:DI 2 "const_int_operand" "")))
21447 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21448 (clobber (reg:TI 27))
21449 (clobber (reg:TI 28))
21450 (clobber (reg:TI 45))
21451 (clobber (reg:TI 46))
21452 (clobber (reg:TI 47))
21453 (clobber (reg:TI 48))
21454 (clobber (reg:TI 49))
21455 (clobber (reg:TI 50))
21456 (clobber (reg:TI 51))
21457 (clobber (reg:TI 52))
21458 (clobber (reg:DI SI_REG))
21459 (clobber (reg:DI DI_REG))]
21460 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21462 if (SIBLING_CALL_P (insn))
21465 return "call\t%P1";
21467 [(set_attr "type" "callv")])
21469 (define_insn "*call_value_1"
21470 [(set (match_operand 0 "" "")
21471 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21472 (match_operand:SI 2 "" "")))]
21473 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21475 if (constant_call_address_operand (operands[1], Pmode))
21476 return "call\t%P1";
21477 return "call\t%A1";
21479 [(set_attr "type" "callv")])
21481 (define_insn "*sibcall_value_1"
21482 [(set (match_operand 0 "" "")
21483 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21484 (match_operand:SI 2 "" "")))]
21485 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21487 if (constant_call_address_operand (operands[1], Pmode))
21491 [(set_attr "type" "callv")])
21493 (define_insn "*call_value_1_rex64"
21494 [(set (match_operand 0 "" "")
21495 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21496 (match_operand:DI 2 "" "")))]
21497 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21498 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21500 if (constant_call_address_operand (operands[1], Pmode))
21501 return "call\t%P1";
21502 return "call\t%A1";
21504 [(set_attr "type" "callv")])
21506 (define_insn "*call_value_1_rex64_ms_sysv"
21507 [(set (match_operand 0 "" "")
21508 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21509 (match_operand:DI 2 "" "")))
21510 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21511 (clobber (reg:TI 27))
21512 (clobber (reg:TI 28))
21513 (clobber (reg:TI 45))
21514 (clobber (reg:TI 46))
21515 (clobber (reg:TI 47))
21516 (clobber (reg:TI 48))
21517 (clobber (reg:TI 49))
21518 (clobber (reg:TI 50))
21519 (clobber (reg:TI 51))
21520 (clobber (reg:TI 52))
21521 (clobber (reg:DI SI_REG))
21522 (clobber (reg:DI DI_REG))]
21523 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21525 if (constant_call_address_operand (operands[1], Pmode))
21526 return "call\t%P1";
21527 return "call\t%A1";
21529 [(set_attr "type" "callv")])
21531 (define_insn "*call_value_1_rex64_large"
21532 [(set (match_operand 0 "" "")
21533 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21534 (match_operand:DI 2 "" "")))]
21535 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21537 [(set_attr "type" "callv")])
21539 (define_insn "*sibcall_value_1_rex64"
21540 [(set (match_operand 0 "" "")
21541 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21542 (match_operand:DI 2 "" "")))]
21543 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21545 [(set_attr "type" "callv")])
21547 (define_insn "*sibcall_value_1_rex64_v"
21548 [(set (match_operand 0 "" "")
21549 (call (mem:QI (reg:DI R11_REG))
21550 (match_operand:DI 1 "" "")))]
21551 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21553 [(set_attr "type" "callv")])
21555 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21556 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21557 ;; caught for use by garbage collectors and the like. Using an insn that
21558 ;; maps to SIGILL makes it more likely the program will rightfully die.
21559 ;; Keeping with tradition, "6" is in honor of #UD.
21560 (define_insn "trap"
21561 [(trap_if (const_int 1) (const_int 6))]
21563 { return ASM_SHORT "0x0b0f"; }
21564 [(set_attr "length" "2")])
21566 (define_expand "sse_prologue_save"
21567 [(parallel [(set (match_operand:BLK 0 "" "")
21568 (unspec:BLK [(reg:DI 21)
21575 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21576 (use (match_operand:DI 1 "register_operand" ""))
21577 (use (match_operand:DI 2 "immediate_operand" ""))
21578 (use (label_ref:DI (match_operand 3 "" "")))])]
21582 (define_insn "*sse_prologue_save_insn"
21583 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21584 (match_operand:DI 4 "const_int_operand" "n")))
21585 (unspec:BLK [(reg:DI 21)
21592 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21593 (use (match_operand:DI 1 "register_operand" "r"))
21594 (use (match_operand:DI 2 "const_int_operand" "i"))
21595 (use (label_ref:DI (match_operand 3 "" "X")))]
21597 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21598 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21601 operands[0] = gen_rtx_MEM (Pmode,
21602 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21603 /* VEX instruction with a REX prefix will #UD. */
21604 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21605 gcc_unreachable ();
21607 output_asm_insn ("jmp\t%A1", operands);
21608 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21610 operands[4] = adjust_address (operands[0], DImode, i*16);
21611 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21612 PUT_MODE (operands[4], TImode);
21613 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21614 output_asm_insn ("rex", operands);
21615 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21617 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21618 CODE_LABEL_NUMBER (operands[3]));
21621 [(set_attr "type" "other")
21622 (set_attr "length_immediate" "0")
21623 (set_attr "length_address" "0")
21624 (set (attr "length")
21626 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21627 (const_string "34")
21628 (const_string "42")))
21629 (set_attr "memory" "store")
21630 (set_attr "modrm" "0")
21631 (set_attr "prefix" "maybe_vex")
21632 (set_attr "mode" "DI")])
21634 (define_expand "prefetch"
21635 [(prefetch (match_operand 0 "address_operand" "")
21636 (match_operand:SI 1 "const_int_operand" "")
21637 (match_operand:SI 2 "const_int_operand" ""))]
21638 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21640 int rw = INTVAL (operands[1]);
21641 int locality = INTVAL (operands[2]);
21643 gcc_assert (rw == 0 || rw == 1);
21644 gcc_assert (locality >= 0 && locality <= 3);
21645 gcc_assert (GET_MODE (operands[0]) == Pmode
21646 || GET_MODE (operands[0]) == VOIDmode);
21648 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21649 supported by SSE counterpart or the SSE prefetch is not available
21650 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21652 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21653 operands[2] = GEN_INT (3);
21655 operands[1] = const0_rtx;
21658 (define_insn "*prefetch_sse"
21659 [(prefetch (match_operand:SI 0 "address_operand" "p")
21661 (match_operand:SI 1 "const_int_operand" ""))]
21662 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21664 static const char * const patterns[4] = {
21665 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21668 int locality = INTVAL (operands[1]);
21669 gcc_assert (locality >= 0 && locality <= 3);
21671 return patterns[locality];
21673 [(set_attr "type" "sse")
21674 (set_attr "memory" "none")])
21676 (define_insn "*prefetch_sse_rex"
21677 [(prefetch (match_operand:DI 0 "address_operand" "p")
21679 (match_operand:SI 1 "const_int_operand" ""))]
21680 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21682 static const char * const patterns[4] = {
21683 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21686 int locality = INTVAL (operands[1]);
21687 gcc_assert (locality >= 0 && locality <= 3);
21689 return patterns[locality];
21691 [(set_attr "type" "sse")
21692 (set_attr "memory" "none")])
21694 (define_insn "*prefetch_3dnow"
21695 [(prefetch (match_operand:SI 0 "address_operand" "p")
21696 (match_operand:SI 1 "const_int_operand" "n")
21698 "TARGET_3DNOW && !TARGET_64BIT"
21700 if (INTVAL (operands[1]) == 0)
21701 return "prefetch\t%a0";
21703 return "prefetchw\t%a0";
21705 [(set_attr "type" "mmx")
21706 (set_attr "memory" "none")])
21708 (define_insn "*prefetch_3dnow_rex"
21709 [(prefetch (match_operand:DI 0 "address_operand" "p")
21710 (match_operand:SI 1 "const_int_operand" "n")
21712 "TARGET_3DNOW && TARGET_64BIT"
21714 if (INTVAL (operands[1]) == 0)
21715 return "prefetch\t%a0";
21717 return "prefetchw\t%a0";
21719 [(set_attr "type" "mmx")
21720 (set_attr "memory" "none")])
21722 (define_expand "stack_protect_set"
21723 [(match_operand 0 "memory_operand" "")
21724 (match_operand 1 "memory_operand" "")]
21727 #ifdef TARGET_THREAD_SSP_OFFSET
21729 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21730 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21732 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21733 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21736 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21738 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21743 (define_insn "stack_protect_set_si"
21744 [(set (match_operand:SI 0 "memory_operand" "=m")
21745 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21746 (set (match_scratch:SI 2 "=&r") (const_int 0))
21747 (clobber (reg:CC FLAGS_REG))]
21749 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21750 [(set_attr "type" "multi")])
21752 (define_insn "stack_protect_set_di"
21753 [(set (match_operand:DI 0 "memory_operand" "=m")
21754 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21755 (set (match_scratch:DI 2 "=&r") (const_int 0))
21756 (clobber (reg:CC FLAGS_REG))]
21758 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21759 [(set_attr "type" "multi")])
21761 (define_insn "stack_tls_protect_set_si"
21762 [(set (match_operand:SI 0 "memory_operand" "=m")
21763 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21764 (set (match_scratch:SI 2 "=&r") (const_int 0))
21765 (clobber (reg:CC FLAGS_REG))]
21767 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21768 [(set_attr "type" "multi")])
21770 (define_insn "stack_tls_protect_set_di"
21771 [(set (match_operand:DI 0 "memory_operand" "=m")
21772 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21773 (set (match_scratch:DI 2 "=&r") (const_int 0))
21774 (clobber (reg:CC FLAGS_REG))]
21777 /* The kernel uses a different segment register for performance reasons; a
21778 system call would not have to trash the userspace segment register,
21779 which would be expensive */
21780 if (ix86_cmodel != CM_KERNEL)
21781 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21783 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21785 [(set_attr "type" "multi")])
21787 (define_expand "stack_protect_test"
21788 [(match_operand 0 "memory_operand" "")
21789 (match_operand 1 "memory_operand" "")
21790 (match_operand 2 "" "")]
21793 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21794 ix86_compare_op0 = operands[0];
21795 ix86_compare_op1 = operands[1];
21796 ix86_compare_emitted = flags;
21798 #ifdef TARGET_THREAD_SSP_OFFSET
21800 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21801 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21803 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21804 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21807 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21809 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21811 emit_jump_insn (gen_beq (operands[2]));
21815 (define_insn "stack_protect_test_si"
21816 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21817 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21818 (match_operand:SI 2 "memory_operand" "m")]
21820 (clobber (match_scratch:SI 3 "=&r"))]
21822 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21823 [(set_attr "type" "multi")])
21825 (define_insn "stack_protect_test_di"
21826 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21827 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21828 (match_operand:DI 2 "memory_operand" "m")]
21830 (clobber (match_scratch:DI 3 "=&r"))]
21832 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21833 [(set_attr "type" "multi")])
21835 (define_insn "stack_tls_protect_test_si"
21836 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21837 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21838 (match_operand:SI 2 "const_int_operand" "i")]
21839 UNSPEC_SP_TLS_TEST))
21840 (clobber (match_scratch:SI 3 "=r"))]
21842 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21843 [(set_attr "type" "multi")])
21845 (define_insn "stack_tls_protect_test_di"
21846 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21847 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21848 (match_operand:DI 2 "const_int_operand" "i")]
21849 UNSPEC_SP_TLS_TEST))
21850 (clobber (match_scratch:DI 3 "=r"))]
21853 /* The kernel uses a different segment register for performance reasons; a
21854 system call would not have to trash the userspace segment register,
21855 which would be expensive */
21856 if (ix86_cmodel != CM_KERNEL)
21857 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21859 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21861 [(set_attr "type" "multi")])
21863 (define_mode_iterator CRC32MODE [QI HI SI])
21864 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21865 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21867 (define_insn "sse4_2_crc32<mode>"
21868 [(set (match_operand:SI 0 "register_operand" "=r")
21870 [(match_operand:SI 1 "register_operand" "0")
21871 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21874 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21875 [(set_attr "type" "sselog1")
21876 (set_attr "prefix_rep" "1")
21877 (set_attr "prefix_extra" "1")
21878 (set_attr "mode" "SI")])
21880 (define_insn "sse4_2_crc32di"
21881 [(set (match_operand:DI 0 "register_operand" "=r")
21883 [(match_operand:DI 1 "register_operand" "0")
21884 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21886 "TARGET_SSE4_2 && TARGET_64BIT"
21887 "crc32q\t{%2, %0|%0, %2}"
21888 [(set_attr "type" "sselog1")
21889 (set_attr "prefix_rep" "1")
21890 (set_attr "prefix_extra" "1")
21891 (set_attr "mode" "DI")])
21895 (include "sync.md")