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
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)
75 (UNSPEC_TLS_LD_BASE 20)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
186 (UNSPEC_CVTPH2PS 155)
187 (UNSPEC_CVTPS2PH 156)
191 (UNSPEC_AESENCLAST 160)
193 (UNSPEC_AESDECLAST 162)
195 (UNSPEC_AESKEYGENASSIST 164)
203 (UNSPEC_VPERMIL2 168)
204 (UNSPEC_VPERMIL2F128 169)
205 (UNSPEC_MASKLOAD 170)
206 (UNSPEC_MASKSTORE 171)
212 [(UNSPECV_BLOCKAGE 0)
213 (UNSPECV_STACK_PROBE 1)
222 (UNSPECV_CMPXCHG_1 10)
223 (UNSPECV_CMPXCHG_2 11)
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 up to SImode.
656 (define_mode_iterator SWI32 [QI HI SI])
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 "mmxadd")
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 "mmxadd")
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_large"
15044 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15045 (match_operand 1 "" ""))]
15046 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15048 [(set_attr "type" "call")])
15050 (define_insn "*sibcall_1_rex64"
15051 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15052 (match_operand 1 "" ""))]
15053 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15055 [(set_attr "type" "call")])
15057 (define_insn "*sibcall_1_rex64_v"
15058 [(call (mem:QI (reg:DI R11_REG))
15059 (match_operand 0 "" ""))]
15060 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15062 [(set_attr "type" "call")])
15065 ;; Call subroutine, returning value in operand 0
15067 (define_expand "call_value_pop"
15068 [(parallel [(set (match_operand 0 "" "")
15069 (call (match_operand:QI 1 "" "")
15070 (match_operand:SI 2 "" "")))
15071 (set (reg:SI SP_REG)
15072 (plus:SI (reg:SI SP_REG)
15073 (match_operand:SI 4 "" "")))])]
15076 ix86_expand_call (operands[0], operands[1], operands[2],
15077 operands[3], operands[4], 0);
15081 (define_expand "call_value"
15082 [(set (match_operand 0 "" "")
15083 (call (match_operand:QI 1 "" "")
15084 (match_operand:SI 2 "" "")))
15085 (use (match_operand:SI 3 "" ""))]
15086 ;; Operand 2 not used on the i386.
15089 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15093 (define_expand "sibcall_value"
15094 [(set (match_operand 0 "" "")
15095 (call (match_operand:QI 1 "" "")
15096 (match_operand:SI 2 "" "")))
15097 (use (match_operand:SI 3 "" ""))]
15098 ;; Operand 2 not used on the i386.
15101 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15105 ;; Call subroutine returning any type.
15107 (define_expand "untyped_call"
15108 [(parallel [(call (match_operand 0 "" "")
15110 (match_operand 1 "" "")
15111 (match_operand 2 "" "")])]
15116 /* In order to give reg-stack an easier job in validating two
15117 coprocessor registers as containing a possible return value,
15118 simply pretend the untyped call returns a complex long double
15121 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15122 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15123 operands[0], const0_rtx,
15124 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15125 : X64_SSE_REGPARM_MAX)
15129 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15131 rtx set = XVECEXP (operands[2], 0, i);
15132 emit_move_insn (SET_DEST (set), SET_SRC (set));
15135 /* The optimizer does not know that the call sets the function value
15136 registers we stored in the result block. We avoid problems by
15137 claiming that all hard registers are used and clobbered at this
15139 emit_insn (gen_blockage ());
15144 ;; Prologue and epilogue instructions
15146 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15147 ;; all of memory. This blocks insns from being moved across this point.
15149 (define_insn "blockage"
15150 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15153 [(set_attr "length" "0")])
15155 ;; As USE insns aren't meaningful after reload, this is used instead
15156 ;; to prevent deleting instructions setting registers for PIC code
15157 (define_insn "prologue_use"
15158 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15161 [(set_attr "length" "0")])
15163 ;; Insn emitted into the body of a function to return from a function.
15164 ;; This is only done if the function's epilogue is known to be simple.
15165 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15167 (define_expand "return"
15169 "ix86_can_use_return_insn_p ()"
15171 if (crtl->args.pops_args)
15173 rtx popc = GEN_INT (crtl->args.pops_args);
15174 emit_jump_insn (gen_return_pop_internal (popc));
15179 (define_insn "return_internal"
15183 [(set_attr "length" "1")
15184 (set_attr "length_immediate" "0")
15185 (set_attr "modrm" "0")])
15187 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15188 ;; instruction Athlon and K8 have.
15190 (define_insn "return_internal_long"
15192 (unspec [(const_int 0)] UNSPEC_REP)]
15195 [(set_attr "length" "1")
15196 (set_attr "length_immediate" "0")
15197 (set_attr "prefix_rep" "1")
15198 (set_attr "modrm" "0")])
15200 (define_insn "return_pop_internal"
15202 (use (match_operand:SI 0 "const_int_operand" ""))]
15205 [(set_attr "length" "3")
15206 (set_attr "length_immediate" "2")
15207 (set_attr "modrm" "0")])
15209 (define_insn "return_indirect_internal"
15211 (use (match_operand:SI 0 "register_operand" "r"))]
15214 [(set_attr "type" "ibr")
15215 (set_attr "length_immediate" "0")])
15221 [(set_attr "length" "1")
15222 (set_attr "length_immediate" "0")
15223 (set_attr "modrm" "0")])
15225 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15226 ;; branch prediction penalty for the third jump in a 16-byte
15229 (define_insn "align"
15230 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15233 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15234 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15236 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15237 The align insn is used to avoid 3 jump instructions in the row to improve
15238 branch prediction and the benefits hardly outweigh the cost of extra 8
15239 nops on the average inserted by full alignment pseudo operation. */
15243 [(set_attr "length" "16")])
15245 (define_expand "prologue"
15248 "ix86_expand_prologue (); DONE;")
15250 (define_insn "set_got"
15251 [(set (match_operand:SI 0 "register_operand" "=r")
15252 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15253 (clobber (reg:CC FLAGS_REG))]
15255 { return output_set_got (operands[0], NULL_RTX); }
15256 [(set_attr "type" "multi")
15257 (set_attr "length" "12")])
15259 (define_insn "set_got_labelled"
15260 [(set (match_operand:SI 0 "register_operand" "=r")
15261 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15263 (clobber (reg:CC FLAGS_REG))]
15265 { return output_set_got (operands[0], operands[1]); }
15266 [(set_attr "type" "multi")
15267 (set_attr "length" "12")])
15269 (define_insn "set_got_rex64"
15270 [(set (match_operand:DI 0 "register_operand" "=r")
15271 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15273 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15274 [(set_attr "type" "lea")
15275 (set_attr "length" "6")])
15277 (define_insn "set_rip_rex64"
15278 [(set (match_operand:DI 0 "register_operand" "=r")
15279 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15281 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15282 [(set_attr "type" "lea")
15283 (set_attr "length" "6")])
15285 (define_insn "set_got_offset_rex64"
15286 [(set (match_operand:DI 0 "register_operand" "=r")
15287 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15289 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15290 [(set_attr "type" "imov")
15291 (set_attr "length" "11")])
15293 (define_expand "epilogue"
15296 "ix86_expand_epilogue (1); DONE;")
15298 (define_expand "sibcall_epilogue"
15301 "ix86_expand_epilogue (0); DONE;")
15303 (define_expand "eh_return"
15304 [(use (match_operand 0 "register_operand" ""))]
15307 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15309 /* Tricky bit: we write the address of the handler to which we will
15310 be returning into someone else's stack frame, one word below the
15311 stack address we wish to restore. */
15312 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15313 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15314 tmp = gen_rtx_MEM (Pmode, tmp);
15315 emit_move_insn (tmp, ra);
15317 if (Pmode == SImode)
15318 emit_jump_insn (gen_eh_return_si (sa));
15320 emit_jump_insn (gen_eh_return_di (sa));
15325 (define_insn_and_split "eh_return_<mode>"
15327 (unspec [(match_operand:P 0 "register_operand" "c")]
15328 UNSPEC_EH_RETURN))]
15333 "ix86_expand_epilogue (2); DONE;")
15335 (define_insn "leave"
15336 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15337 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15338 (clobber (mem:BLK (scratch)))]
15341 [(set_attr "type" "leave")])
15343 (define_insn "leave_rex64"
15344 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15345 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15346 (clobber (mem:BLK (scratch)))]
15349 [(set_attr "type" "leave")])
15351 (define_expand "ffssi2"
15353 [(set (match_operand:SI 0 "register_operand" "")
15354 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15355 (clobber (match_scratch:SI 2 ""))
15356 (clobber (reg:CC FLAGS_REG))])]
15361 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15366 (define_expand "ffs_cmove"
15367 [(set (match_dup 2) (const_int -1))
15368 (parallel [(set (reg:CCZ FLAGS_REG)
15369 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15371 (set (match_operand:SI 0 "nonimmediate_operand" "")
15372 (ctz:SI (match_dup 1)))])
15373 (set (match_dup 0) (if_then_else:SI
15374 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15377 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15378 (clobber (reg:CC FLAGS_REG))])]
15380 "operands[2] = gen_reg_rtx (SImode);")
15382 (define_insn_and_split "*ffs_no_cmove"
15383 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15384 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15385 (clobber (match_scratch:SI 2 "=&q"))
15386 (clobber (reg:CC FLAGS_REG))]
15389 "&& reload_completed"
15390 [(parallel [(set (reg:CCZ FLAGS_REG)
15391 (compare:CCZ (match_dup 1) (const_int 0)))
15392 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15393 (set (strict_low_part (match_dup 3))
15394 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15395 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15396 (clobber (reg:CC FLAGS_REG))])
15397 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15398 (clobber (reg:CC FLAGS_REG))])
15399 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15400 (clobber (reg:CC FLAGS_REG))])]
15402 operands[3] = gen_lowpart (QImode, operands[2]);
15403 ix86_expand_clear (operands[2]);
15406 (define_insn "*ffssi_1"
15407 [(set (reg:CCZ FLAGS_REG)
15408 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15410 (set (match_operand:SI 0 "register_operand" "=r")
15411 (ctz:SI (match_dup 1)))]
15413 "bsf{l}\t{%1, %0|%0, %1}"
15414 [(set_attr "prefix_0f" "1")])
15416 (define_expand "ffsdi2"
15417 [(set (match_dup 2) (const_int -1))
15418 (parallel [(set (reg:CCZ FLAGS_REG)
15419 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15421 (set (match_operand:DI 0 "nonimmediate_operand" "")
15422 (ctz:DI (match_dup 1)))])
15423 (set (match_dup 0) (if_then_else:DI
15424 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15427 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15428 (clobber (reg:CC FLAGS_REG))])]
15430 "operands[2] = gen_reg_rtx (DImode);")
15432 (define_insn "*ffsdi_1"
15433 [(set (reg:CCZ FLAGS_REG)
15434 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15436 (set (match_operand:DI 0 "register_operand" "=r")
15437 (ctz:DI (match_dup 1)))]
15439 "bsf{q}\t{%1, %0|%0, %1}"
15440 [(set_attr "prefix_0f" "1")])
15442 (define_insn "ctzsi2"
15443 [(set (match_operand:SI 0 "register_operand" "=r")
15444 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15445 (clobber (reg:CC FLAGS_REG))]
15447 "bsf{l}\t{%1, %0|%0, %1}"
15448 [(set_attr "prefix_0f" "1")])
15450 (define_insn "ctzdi2"
15451 [(set (match_operand:DI 0 "register_operand" "=r")
15452 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15453 (clobber (reg:CC FLAGS_REG))]
15455 "bsf{q}\t{%1, %0|%0, %1}"
15456 [(set_attr "prefix_0f" "1")])
15458 (define_expand "clzsi2"
15460 [(set (match_operand:SI 0 "register_operand" "")
15461 (minus:SI (const_int 31)
15462 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15463 (clobber (reg:CC FLAGS_REG))])
15465 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15466 (clobber (reg:CC FLAGS_REG))])]
15471 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15476 (define_insn "clzsi2_abm"
15477 [(set (match_operand:SI 0 "register_operand" "=r")
15478 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15479 (clobber (reg:CC FLAGS_REG))]
15481 "lzcnt{l}\t{%1, %0|%0, %1}"
15482 [(set_attr "prefix_rep" "1")
15483 (set_attr "type" "bitmanip")
15484 (set_attr "mode" "SI")])
15486 (define_insn "*bsr"
15487 [(set (match_operand:SI 0 "register_operand" "=r")
15488 (minus:SI (const_int 31)
15489 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15490 (clobber (reg:CC FLAGS_REG))]
15492 "bsr{l}\t{%1, %0|%0, %1}"
15493 [(set_attr "prefix_0f" "1")
15494 (set_attr "mode" "SI")])
15496 (define_insn "popcountsi2"
15497 [(set (match_operand:SI 0 "register_operand" "=r")
15498 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15499 (clobber (reg:CC FLAGS_REG))]
15501 "popcnt{l}\t{%1, %0|%0, %1}"
15502 [(set_attr "prefix_rep" "1")
15503 (set_attr "type" "bitmanip")
15504 (set_attr "mode" "SI")])
15506 (define_insn "*popcountsi2_cmp"
15507 [(set (reg FLAGS_REG)
15509 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15511 (set (match_operand:SI 0 "register_operand" "=r")
15512 (popcount:SI (match_dup 1)))]
15513 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15514 "popcnt{l}\t{%1, %0|%0, %1}"
15515 [(set_attr "prefix_rep" "1")
15516 (set_attr "type" "bitmanip")
15517 (set_attr "mode" "SI")])
15519 (define_insn "*popcountsi2_cmp_zext"
15520 [(set (reg FLAGS_REG)
15522 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15524 (set (match_operand:DI 0 "register_operand" "=r")
15525 (zero_extend:DI(popcount:SI (match_dup 1))))]
15526 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15527 "popcnt{l}\t{%1, %0|%0, %1}"
15528 [(set_attr "prefix_rep" "1")
15529 (set_attr "type" "bitmanip")
15530 (set_attr "mode" "SI")])
15532 (define_expand "bswapsi2"
15533 [(set (match_operand:SI 0 "register_operand" "")
15534 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15539 rtx x = operands[0];
15541 emit_move_insn (x, operands[1]);
15542 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15543 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15544 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15549 (define_insn "*bswapsi_1"
15550 [(set (match_operand:SI 0 "register_operand" "=r")
15551 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15554 [(set_attr "prefix_0f" "1")
15555 (set_attr "length" "2")])
15557 (define_insn "*bswaphi_lowpart_1"
15558 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15559 (bswap:HI (match_dup 0)))
15560 (clobber (reg:CC FLAGS_REG))]
15561 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15563 xchg{b}\t{%h0, %b0|%b0, %h0}
15564 rol{w}\t{$8, %0|%0, 8}"
15565 [(set_attr "length" "2,4")
15566 (set_attr "mode" "QI,HI")])
15568 (define_insn "bswaphi_lowpart"
15569 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15570 (bswap:HI (match_dup 0)))
15571 (clobber (reg:CC FLAGS_REG))]
15573 "rol{w}\t{$8, %0|%0, 8}"
15574 [(set_attr "length" "4")
15575 (set_attr "mode" "HI")])
15577 (define_insn "bswapdi2"
15578 [(set (match_operand:DI 0 "register_operand" "=r")
15579 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15582 [(set_attr "prefix_0f" "1")
15583 (set_attr "length" "3")])
15585 (define_expand "clzdi2"
15587 [(set (match_operand:DI 0 "register_operand" "")
15588 (minus:DI (const_int 63)
15589 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15590 (clobber (reg:CC FLAGS_REG))])
15592 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15593 (clobber (reg:CC FLAGS_REG))])]
15598 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15603 (define_insn "clzdi2_abm"
15604 [(set (match_operand:DI 0 "register_operand" "=r")
15605 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15606 (clobber (reg:CC FLAGS_REG))]
15607 "TARGET_64BIT && TARGET_ABM"
15608 "lzcnt{q}\t{%1, %0|%0, %1}"
15609 [(set_attr "prefix_rep" "1")
15610 (set_attr "type" "bitmanip")
15611 (set_attr "mode" "DI")])
15613 (define_insn "*bsr_rex64"
15614 [(set (match_operand:DI 0 "register_operand" "=r")
15615 (minus:DI (const_int 63)
15616 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15617 (clobber (reg:CC FLAGS_REG))]
15619 "bsr{q}\t{%1, %0|%0, %1}"
15620 [(set_attr "prefix_0f" "1")
15621 (set_attr "mode" "DI")])
15623 (define_insn "popcountdi2"
15624 [(set (match_operand:DI 0 "register_operand" "=r")
15625 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15626 (clobber (reg:CC FLAGS_REG))]
15627 "TARGET_64BIT && TARGET_POPCNT"
15628 "popcnt{q}\t{%1, %0|%0, %1}"
15629 [(set_attr "prefix_rep" "1")
15630 (set_attr "type" "bitmanip")
15631 (set_attr "mode" "DI")])
15633 (define_insn "*popcountdi2_cmp"
15634 [(set (reg FLAGS_REG)
15636 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15638 (set (match_operand:DI 0 "register_operand" "=r")
15639 (popcount:DI (match_dup 1)))]
15640 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15641 "popcnt{q}\t{%1, %0|%0, %1}"
15642 [(set_attr "prefix_rep" "1")
15643 (set_attr "type" "bitmanip")
15644 (set_attr "mode" "DI")])
15646 (define_expand "clzhi2"
15648 [(set (match_operand:HI 0 "register_operand" "")
15649 (minus:HI (const_int 15)
15650 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15651 (clobber (reg:CC FLAGS_REG))])
15653 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15654 (clobber (reg:CC FLAGS_REG))])]
15659 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15664 (define_insn "clzhi2_abm"
15665 [(set (match_operand:HI 0 "register_operand" "=r")
15666 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15667 (clobber (reg:CC FLAGS_REG))]
15669 "lzcnt{w}\t{%1, %0|%0, %1}"
15670 [(set_attr "prefix_rep" "1")
15671 (set_attr "type" "bitmanip")
15672 (set_attr "mode" "HI")])
15674 (define_insn "*bsrhi"
15675 [(set (match_operand:HI 0 "register_operand" "=r")
15676 (minus:HI (const_int 15)
15677 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15678 (clobber (reg:CC FLAGS_REG))]
15680 "bsr{w}\t{%1, %0|%0, %1}"
15681 [(set_attr "prefix_0f" "1")
15682 (set_attr "mode" "HI")])
15684 (define_insn "popcounthi2"
15685 [(set (match_operand:HI 0 "register_operand" "=r")
15686 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15687 (clobber (reg:CC FLAGS_REG))]
15689 "popcnt{w}\t{%1, %0|%0, %1}"
15690 [(set_attr "prefix_rep" "1")
15691 (set_attr "type" "bitmanip")
15692 (set_attr "mode" "HI")])
15694 (define_insn "*popcounthi2_cmp"
15695 [(set (reg FLAGS_REG)
15697 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15699 (set (match_operand:HI 0 "register_operand" "=r")
15700 (popcount:HI (match_dup 1)))]
15701 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15702 "popcnt{w}\t{%1, %0|%0, %1}"
15703 [(set_attr "prefix_rep" "1")
15704 (set_attr "type" "bitmanip")
15705 (set_attr "mode" "HI")])
15707 (define_expand "paritydi2"
15708 [(set (match_operand:DI 0 "register_operand" "")
15709 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15712 rtx scratch = gen_reg_rtx (QImode);
15715 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15716 NULL_RTX, operands[1]));
15718 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15719 gen_rtx_REG (CCmode, FLAGS_REG),
15721 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15724 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15727 rtx tmp = gen_reg_rtx (SImode);
15729 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15730 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15735 (define_insn_and_split "paritydi2_cmp"
15736 [(set (reg:CC FLAGS_REG)
15737 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15738 (clobber (match_scratch:DI 0 "=r"))
15739 (clobber (match_scratch:SI 1 "=&r"))
15740 (clobber (match_scratch:HI 2 "=Q"))]
15743 "&& reload_completed"
15745 [(set (match_dup 1)
15746 (xor:SI (match_dup 1) (match_dup 4)))
15747 (clobber (reg:CC FLAGS_REG))])
15749 [(set (reg:CC FLAGS_REG)
15750 (parity:CC (match_dup 1)))
15751 (clobber (match_dup 1))
15752 (clobber (match_dup 2))])]
15754 operands[4] = gen_lowpart (SImode, operands[3]);
15758 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15759 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15762 operands[1] = gen_highpart (SImode, operands[3]);
15765 (define_expand "paritysi2"
15766 [(set (match_operand:SI 0 "register_operand" "")
15767 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15770 rtx scratch = gen_reg_rtx (QImode);
15773 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15775 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15776 gen_rtx_REG (CCmode, FLAGS_REG),
15778 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15780 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15784 (define_insn_and_split "paritysi2_cmp"
15785 [(set (reg:CC FLAGS_REG)
15786 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15787 (clobber (match_scratch:SI 0 "=r"))
15788 (clobber (match_scratch:HI 1 "=&Q"))]
15791 "&& reload_completed"
15793 [(set (match_dup 1)
15794 (xor:HI (match_dup 1) (match_dup 3)))
15795 (clobber (reg:CC FLAGS_REG))])
15797 [(set (reg:CC FLAGS_REG)
15798 (parity:CC (match_dup 1)))
15799 (clobber (match_dup 1))])]
15801 operands[3] = gen_lowpart (HImode, operands[2]);
15803 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15804 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15807 (define_insn "*parityhi2_cmp"
15808 [(set (reg:CC FLAGS_REG)
15809 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15810 (clobber (match_scratch:HI 0 "=Q"))]
15812 "xor{b}\t{%h0, %b0|%b0, %h0}"
15813 [(set_attr "length" "2")
15814 (set_attr "mode" "HI")])
15816 (define_insn "*parityqi2_cmp"
15817 [(set (reg:CC FLAGS_REG)
15818 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15821 [(set_attr "length" "2")
15822 (set_attr "mode" "QI")])
15824 ;; Thread-local storage patterns for ELF.
15826 ;; Note that these code sequences must appear exactly as shown
15827 ;; in order to allow linker relaxation.
15829 (define_insn "*tls_global_dynamic_32_gnu"
15830 [(set (match_operand:SI 0 "register_operand" "=a")
15831 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15832 (match_operand:SI 2 "tls_symbolic_operand" "")
15833 (match_operand:SI 3 "call_insn_operand" "")]
15835 (clobber (match_scratch:SI 4 "=d"))
15836 (clobber (match_scratch:SI 5 "=c"))
15837 (clobber (reg:CC FLAGS_REG))]
15838 "!TARGET_64BIT && TARGET_GNU_TLS"
15839 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15840 [(set_attr "type" "multi")
15841 (set_attr "length" "12")])
15843 (define_insn "*tls_global_dynamic_32_sun"
15844 [(set (match_operand:SI 0 "register_operand" "=a")
15845 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15846 (match_operand:SI 2 "tls_symbolic_operand" "")
15847 (match_operand:SI 3 "call_insn_operand" "")]
15849 (clobber (match_scratch:SI 4 "=d"))
15850 (clobber (match_scratch:SI 5 "=c"))
15851 (clobber (reg:CC FLAGS_REG))]
15852 "!TARGET_64BIT && TARGET_SUN_TLS"
15853 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15854 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15855 [(set_attr "type" "multi")
15856 (set_attr "length" "14")])
15858 (define_expand "tls_global_dynamic_32"
15859 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15862 (match_operand:SI 1 "tls_symbolic_operand" "")
15865 (clobber (match_scratch:SI 4 ""))
15866 (clobber (match_scratch:SI 5 ""))
15867 (clobber (reg:CC FLAGS_REG))])]
15871 operands[2] = pic_offset_table_rtx;
15874 operands[2] = gen_reg_rtx (Pmode);
15875 emit_insn (gen_set_got (operands[2]));
15877 if (TARGET_GNU2_TLS)
15879 emit_insn (gen_tls_dynamic_gnu2_32
15880 (operands[0], operands[1], operands[2]));
15883 operands[3] = ix86_tls_get_addr ();
15886 (define_insn "*tls_global_dynamic_64"
15887 [(set (match_operand:DI 0 "register_operand" "=a")
15888 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15889 (match_operand:DI 3 "" "")))
15890 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15893 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15894 [(set_attr "type" "multi")
15895 (set_attr "length" "16")])
15897 (define_expand "tls_global_dynamic_64"
15898 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15899 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15900 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15904 if (TARGET_GNU2_TLS)
15906 emit_insn (gen_tls_dynamic_gnu2_64
15907 (operands[0], operands[1]));
15910 operands[2] = ix86_tls_get_addr ();
15913 (define_insn "*tls_local_dynamic_base_32_gnu"
15914 [(set (match_operand:SI 0 "register_operand" "=a")
15915 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916 (match_operand:SI 2 "call_insn_operand" "")]
15917 UNSPEC_TLS_LD_BASE))
15918 (clobber (match_scratch:SI 3 "=d"))
15919 (clobber (match_scratch:SI 4 "=c"))
15920 (clobber (reg:CC FLAGS_REG))]
15921 "!TARGET_64BIT && TARGET_GNU_TLS"
15922 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15923 [(set_attr "type" "multi")
15924 (set_attr "length" "11")])
15926 (define_insn "*tls_local_dynamic_base_32_sun"
15927 [(set (match_operand:SI 0 "register_operand" "=a")
15928 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15929 (match_operand:SI 2 "call_insn_operand" "")]
15930 UNSPEC_TLS_LD_BASE))
15931 (clobber (match_scratch:SI 3 "=d"))
15932 (clobber (match_scratch:SI 4 "=c"))
15933 (clobber (reg:CC FLAGS_REG))]
15934 "!TARGET_64BIT && TARGET_SUN_TLS"
15935 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15936 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15937 [(set_attr "type" "multi")
15938 (set_attr "length" "13")])
15940 (define_expand "tls_local_dynamic_base_32"
15941 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15942 (unspec:SI [(match_dup 1) (match_dup 2)]
15943 UNSPEC_TLS_LD_BASE))
15944 (clobber (match_scratch:SI 3 ""))
15945 (clobber (match_scratch:SI 4 ""))
15946 (clobber (reg:CC FLAGS_REG))])]
15950 operands[1] = pic_offset_table_rtx;
15953 operands[1] = gen_reg_rtx (Pmode);
15954 emit_insn (gen_set_got (operands[1]));
15956 if (TARGET_GNU2_TLS)
15958 emit_insn (gen_tls_dynamic_gnu2_32
15959 (operands[0], ix86_tls_module_base (), operands[1]));
15962 operands[2] = ix86_tls_get_addr ();
15965 (define_insn "*tls_local_dynamic_base_64"
15966 [(set (match_operand:DI 0 "register_operand" "=a")
15967 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15968 (match_operand:DI 2 "" "")))
15969 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15971 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15972 [(set_attr "type" "multi")
15973 (set_attr "length" "12")])
15975 (define_expand "tls_local_dynamic_base_64"
15976 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15977 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15978 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15981 if (TARGET_GNU2_TLS)
15983 emit_insn (gen_tls_dynamic_gnu2_64
15984 (operands[0], ix86_tls_module_base ()));
15987 operands[1] = ix86_tls_get_addr ();
15990 ;; Local dynamic of a single variable is a lose. Show combine how
15991 ;; to convert that back to global dynamic.
15993 (define_insn_and_split "*tls_local_dynamic_32_once"
15994 [(set (match_operand:SI 0 "register_operand" "=a")
15995 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15996 (match_operand:SI 2 "call_insn_operand" "")]
15997 UNSPEC_TLS_LD_BASE)
15998 (const:SI (unspec:SI
15999 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16001 (clobber (match_scratch:SI 4 "=d"))
16002 (clobber (match_scratch:SI 5 "=c"))
16003 (clobber (reg:CC FLAGS_REG))]
16007 [(parallel [(set (match_dup 0)
16008 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16010 (clobber (match_dup 4))
16011 (clobber (match_dup 5))
16012 (clobber (reg:CC FLAGS_REG))])]
16015 ;; Load and add the thread base pointer from %gs:0.
16017 (define_insn "*load_tp_si"
16018 [(set (match_operand:SI 0 "register_operand" "=r")
16019 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16021 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16022 [(set_attr "type" "imov")
16023 (set_attr "modrm" "0")
16024 (set_attr "length" "7")
16025 (set_attr "memory" "load")
16026 (set_attr "imm_disp" "false")])
16028 (define_insn "*add_tp_si"
16029 [(set (match_operand:SI 0 "register_operand" "=r")
16030 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16031 (match_operand:SI 1 "register_operand" "0")))
16032 (clobber (reg:CC FLAGS_REG))]
16034 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16035 [(set_attr "type" "alu")
16036 (set_attr "modrm" "0")
16037 (set_attr "length" "7")
16038 (set_attr "memory" "load")
16039 (set_attr "imm_disp" "false")])
16041 (define_insn "*load_tp_di"
16042 [(set (match_operand:DI 0 "register_operand" "=r")
16043 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16045 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16046 [(set_attr "type" "imov")
16047 (set_attr "modrm" "0")
16048 (set_attr "length" "7")
16049 (set_attr "memory" "load")
16050 (set_attr "imm_disp" "false")])
16052 (define_insn "*add_tp_di"
16053 [(set (match_operand:DI 0 "register_operand" "=r")
16054 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16055 (match_operand:DI 1 "register_operand" "0")))
16056 (clobber (reg:CC FLAGS_REG))]
16058 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16059 [(set_attr "type" "alu")
16060 (set_attr "modrm" "0")
16061 (set_attr "length" "7")
16062 (set_attr "memory" "load")
16063 (set_attr "imm_disp" "false")])
16065 ;; GNU2 TLS patterns can be split.
16067 (define_expand "tls_dynamic_gnu2_32"
16068 [(set (match_dup 3)
16069 (plus:SI (match_operand:SI 2 "register_operand" "")
16071 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16074 [(set (match_operand:SI 0 "register_operand" "")
16075 (unspec:SI [(match_dup 1) (match_dup 3)
16076 (match_dup 2) (reg:SI SP_REG)]
16078 (clobber (reg:CC FLAGS_REG))])]
16079 "!TARGET_64BIT && TARGET_GNU2_TLS"
16081 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16082 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16085 (define_insn "*tls_dynamic_lea_32"
16086 [(set (match_operand:SI 0 "register_operand" "=r")
16087 (plus:SI (match_operand:SI 1 "register_operand" "b")
16089 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16090 UNSPEC_TLSDESC))))]
16091 "!TARGET_64BIT && TARGET_GNU2_TLS"
16092 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16093 [(set_attr "type" "lea")
16094 (set_attr "mode" "SI")
16095 (set_attr "length" "6")
16096 (set_attr "length_address" "4")])
16098 (define_insn "*tls_dynamic_call_32"
16099 [(set (match_operand:SI 0 "register_operand" "=a")
16100 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16101 (match_operand:SI 2 "register_operand" "0")
16102 ;; we have to make sure %ebx still points to the GOT
16103 (match_operand:SI 3 "register_operand" "b")
16106 (clobber (reg:CC FLAGS_REG))]
16107 "!TARGET_64BIT && TARGET_GNU2_TLS"
16108 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16109 [(set_attr "type" "call")
16110 (set_attr "length" "2")
16111 (set_attr "length_address" "0")])
16113 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16114 [(set (match_operand:SI 0 "register_operand" "=&a")
16116 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16117 (match_operand:SI 4 "" "")
16118 (match_operand:SI 2 "register_operand" "b")
16121 (const:SI (unspec:SI
16122 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16124 (clobber (reg:CC FLAGS_REG))]
16125 "!TARGET_64BIT && TARGET_GNU2_TLS"
16128 [(set (match_dup 0) (match_dup 5))]
16130 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16131 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16134 (define_expand "tls_dynamic_gnu2_64"
16135 [(set (match_dup 2)
16136 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16139 [(set (match_operand:DI 0 "register_operand" "")
16140 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16142 (clobber (reg:CC FLAGS_REG))])]
16143 "TARGET_64BIT && TARGET_GNU2_TLS"
16145 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16146 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16149 (define_insn "*tls_dynamic_lea_64"
16150 [(set (match_operand:DI 0 "register_operand" "=r")
16151 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16153 "TARGET_64BIT && TARGET_GNU2_TLS"
16154 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16155 [(set_attr "type" "lea")
16156 (set_attr "mode" "DI")
16157 (set_attr "length" "7")
16158 (set_attr "length_address" "4")])
16160 (define_insn "*tls_dynamic_call_64"
16161 [(set (match_operand:DI 0 "register_operand" "=a")
16162 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16163 (match_operand:DI 2 "register_operand" "0")
16166 (clobber (reg:CC FLAGS_REG))]
16167 "TARGET_64BIT && TARGET_GNU2_TLS"
16168 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16169 [(set_attr "type" "call")
16170 (set_attr "length" "2")
16171 (set_attr "length_address" "0")])
16173 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16174 [(set (match_operand:DI 0 "register_operand" "=&a")
16176 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16177 (match_operand:DI 3 "" "")
16180 (const:DI (unspec:DI
16181 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16183 (clobber (reg:CC FLAGS_REG))]
16184 "TARGET_64BIT && TARGET_GNU2_TLS"
16187 [(set (match_dup 0) (match_dup 4))]
16189 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16190 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16195 ;; These patterns match the binary 387 instructions for addM3, subM3,
16196 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16197 ;; SFmode. The first is the normal insn, the second the same insn but
16198 ;; with one operand a conversion, and the third the same insn but with
16199 ;; the other operand a conversion. The conversion may be SFmode or
16200 ;; SImode if the target mode DFmode, but only SImode if the target mode
16203 ;; Gcc is slightly more smart about handling normal two address instructions
16204 ;; so use special patterns for add and mull.
16206 (define_insn "*fop_<mode>_comm_mixed_avx"
16207 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16208 (match_operator:MODEF 3 "binary_fp_operator"
16209 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16210 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16211 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16212 && COMMUTATIVE_ARITH_P (operands[3])
16213 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16214 "* return output_387_binary_op (insn, operands);"
16215 [(set (attr "type")
16216 (if_then_else (eq_attr "alternative" "1")
16217 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16218 (const_string "ssemul")
16219 (const_string "sseadd"))
16220 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16221 (const_string "fmul")
16222 (const_string "fop"))))
16223 (set_attr "prefix" "orig,maybe_vex")
16224 (set_attr "mode" "<MODE>")])
16226 (define_insn "*fop_<mode>_comm_mixed"
16227 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16228 (match_operator:MODEF 3 "binary_fp_operator"
16229 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16230 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16232 && COMMUTATIVE_ARITH_P (operands[3])
16233 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16234 "* return output_387_binary_op (insn, operands);"
16235 [(set (attr "type")
16236 (if_then_else (eq_attr "alternative" "1")
16237 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16238 (const_string "ssemul")
16239 (const_string "sseadd"))
16240 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16241 (const_string "fmul")
16242 (const_string "fop"))))
16243 (set_attr "mode" "<MODE>")])
16245 (define_insn "*fop_<mode>_comm_avx"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x")
16247 (match_operator:MODEF 3 "binary_fp_operator"
16248 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16250 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16251 && COMMUTATIVE_ARITH_P (operands[3])
16252 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16253 "* return output_387_binary_op (insn, operands);"
16254 [(set (attr "type")
16255 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16256 (const_string "ssemul")
16257 (const_string "sseadd")))
16258 (set_attr "prefix" "vex")
16259 (set_attr "mode" "<MODE>")])
16261 (define_insn "*fop_<mode>_comm_sse"
16262 [(set (match_operand:MODEF 0 "register_operand" "=x")
16263 (match_operator:MODEF 3 "binary_fp_operator"
16264 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16265 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16266 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16267 && COMMUTATIVE_ARITH_P (operands[3])
16268 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16269 "* return output_387_binary_op (insn, operands);"
16270 [(set (attr "type")
16271 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16272 (const_string "ssemul")
16273 (const_string "sseadd")))
16274 (set_attr "mode" "<MODE>")])
16276 (define_insn "*fop_<mode>_comm_i387"
16277 [(set (match_operand:MODEF 0 "register_operand" "=f")
16278 (match_operator:MODEF 3 "binary_fp_operator"
16279 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16280 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16282 && COMMUTATIVE_ARITH_P (operands[3])
16283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16284 "* return output_387_binary_op (insn, operands);"
16285 [(set (attr "type")
16286 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16287 (const_string "fmul")
16288 (const_string "fop")))
16289 (set_attr "mode" "<MODE>")])
16291 (define_insn "*fop_<mode>_1_mixed_avx"
16292 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16293 (match_operator:MODEF 3 "binary_fp_operator"
16294 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16295 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16296 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16297 && !COMMUTATIVE_ARITH_P (operands[3])
16298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299 "* return output_387_binary_op (insn, operands);"
16300 [(set (attr "type")
16301 (cond [(and (eq_attr "alternative" "2")
16302 (match_operand:MODEF 3 "mult_operator" ""))
16303 (const_string "ssemul")
16304 (and (eq_attr "alternative" "2")
16305 (match_operand:MODEF 3 "div_operator" ""))
16306 (const_string "ssediv")
16307 (eq_attr "alternative" "2")
16308 (const_string "sseadd")
16309 (match_operand:MODEF 3 "mult_operator" "")
16310 (const_string "fmul")
16311 (match_operand:MODEF 3 "div_operator" "")
16312 (const_string "fdiv")
16314 (const_string "fop")))
16315 (set_attr "prefix" "orig,orig,maybe_vex")
16316 (set_attr "mode" "<MODE>")])
16318 (define_insn "*fop_<mode>_1_mixed"
16319 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16320 (match_operator:MODEF 3 "binary_fp_operator"
16321 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16322 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16324 && !COMMUTATIVE_ARITH_P (operands[3])
16325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16326 "* return output_387_binary_op (insn, operands);"
16327 [(set (attr "type")
16328 (cond [(and (eq_attr "alternative" "2")
16329 (match_operand:MODEF 3 "mult_operator" ""))
16330 (const_string "ssemul")
16331 (and (eq_attr "alternative" "2")
16332 (match_operand:MODEF 3 "div_operator" ""))
16333 (const_string "ssediv")
16334 (eq_attr "alternative" "2")
16335 (const_string "sseadd")
16336 (match_operand:MODEF 3 "mult_operator" "")
16337 (const_string "fmul")
16338 (match_operand:MODEF 3 "div_operator" "")
16339 (const_string "fdiv")
16341 (const_string "fop")))
16342 (set_attr "mode" "<MODE>")])
16344 (define_insn "*rcpsf2_sse"
16345 [(set (match_operand:SF 0 "register_operand" "=x")
16346 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16349 "%vrcpss\t{%1, %d0|%d0, %1}"
16350 [(set_attr "type" "sse")
16351 (set_attr "prefix" "maybe_vex")
16352 (set_attr "mode" "SF")])
16354 (define_insn "*fop_<mode>_1_avx"
16355 [(set (match_operand:MODEF 0 "register_operand" "=x")
16356 (match_operator:MODEF 3 "binary_fp_operator"
16357 [(match_operand:MODEF 1 "register_operand" "x")
16358 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16359 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16360 && !COMMUTATIVE_ARITH_P (operands[3])"
16361 "* return output_387_binary_op (insn, operands);"
16362 [(set (attr "type")
16363 (cond [(match_operand:MODEF 3 "mult_operator" "")
16364 (const_string "ssemul")
16365 (match_operand:MODEF 3 "div_operator" "")
16366 (const_string "ssediv")
16368 (const_string "sseadd")))
16369 (set_attr "prefix" "vex")
16370 (set_attr "mode" "<MODE>")])
16372 (define_insn "*fop_<mode>_1_sse"
16373 [(set (match_operand:MODEF 0 "register_operand" "=x")
16374 (match_operator:MODEF 3 "binary_fp_operator"
16375 [(match_operand:MODEF 1 "register_operand" "0")
16376 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16377 "SSE_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 "mode" "<MODE>")])
16389 ;; This pattern is not fully shadowed by the pattern above.
16390 (define_insn "*fop_<mode>_1_i387"
16391 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16392 (match_operator:MODEF 3 "binary_fp_operator"
16393 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16394 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16395 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396 && !COMMUTATIVE_ARITH_P (operands[3])
16397 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16398 "* return output_387_binary_op (insn, operands);"
16399 [(set (attr "type")
16400 (cond [(match_operand:MODEF 3 "mult_operator" "")
16401 (const_string "fmul")
16402 (match_operand:MODEF 3 "div_operator" "")
16403 (const_string "fdiv")
16405 (const_string "fop")))
16406 (set_attr "mode" "<MODE>")])
16408 ;; ??? Add SSE splitters for these!
16409 (define_insn "*fop_<MODEF:mode>_2_i387"
16410 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16411 (match_operator:MODEF 3 "binary_fp_operator"
16413 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16414 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16415 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16416 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16417 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16418 [(set (attr "type")
16419 (cond [(match_operand:MODEF 3 "mult_operator" "")
16420 (const_string "fmul")
16421 (match_operand:MODEF 3 "div_operator" "")
16422 (const_string "fdiv")
16424 (const_string "fop")))
16425 (set_attr "fp_int_src" "true")
16426 (set_attr "mode" "<X87MODEI12:MODE>")])
16428 (define_insn "*fop_<MODEF:mode>_3_i387"
16429 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16430 (match_operator:MODEF 3 "binary_fp_operator"
16431 [(match_operand:MODEF 1 "register_operand" "0,0")
16433 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16434 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16435 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16436 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16437 [(set (attr "type")
16438 (cond [(match_operand:MODEF 3 "mult_operator" "")
16439 (const_string "fmul")
16440 (match_operand:MODEF 3 "div_operator" "")
16441 (const_string "fdiv")
16443 (const_string "fop")))
16444 (set_attr "fp_int_src" "true")
16445 (set_attr "mode" "<MODE>")])
16447 (define_insn "*fop_df_4_i387"
16448 [(set (match_operand:DF 0 "register_operand" "=f,f")
16449 (match_operator:DF 3 "binary_fp_operator"
16451 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16452 (match_operand:DF 2 "register_operand" "0,f")]))]
16453 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16454 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16455 "* return output_387_binary_op (insn, operands);"
16456 [(set (attr "type")
16457 (cond [(match_operand:DF 3 "mult_operator" "")
16458 (const_string "fmul")
16459 (match_operand:DF 3 "div_operator" "")
16460 (const_string "fdiv")
16462 (const_string "fop")))
16463 (set_attr "mode" "SF")])
16465 (define_insn "*fop_df_5_i387"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f")
16467 (match_operator:DF 3 "binary_fp_operator"
16468 [(match_operand:DF 1 "register_operand" "0,f")
16470 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16471 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16472 "* return output_387_binary_op (insn, operands);"
16473 [(set (attr "type")
16474 (cond [(match_operand:DF 3 "mult_operator" "")
16475 (const_string "fmul")
16476 (match_operand:DF 3 "div_operator" "")
16477 (const_string "fdiv")
16479 (const_string "fop")))
16480 (set_attr "mode" "SF")])
16482 (define_insn "*fop_df_6_i387"
16483 [(set (match_operand:DF 0 "register_operand" "=f,f")
16484 (match_operator:DF 3 "binary_fp_operator"
16486 (match_operand:SF 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_xf_comm_i387"
16501 [(set (match_operand:XF 0 "register_operand" "=f")
16502 (match_operator:XF 3 "binary_fp_operator"
16503 [(match_operand:XF 1 "register_operand" "%0")
16504 (match_operand:XF 2 "register_operand" "f")]))]
16506 && COMMUTATIVE_ARITH_P (operands[3])"
16507 "* return output_387_binary_op (insn, operands);"
16508 [(set (attr "type")
16509 (if_then_else (match_operand:XF 3 "mult_operator" "")
16510 (const_string "fmul")
16511 (const_string "fop")))
16512 (set_attr "mode" "XF")])
16514 (define_insn "*fop_xf_1_i387"
16515 [(set (match_operand:XF 0 "register_operand" "=f,f")
16516 (match_operator:XF 3 "binary_fp_operator"
16517 [(match_operand:XF 1 "register_operand" "0,f")
16518 (match_operand:XF 2 "register_operand" "f,0")]))]
16520 && !COMMUTATIVE_ARITH_P (operands[3])"
16521 "* return output_387_binary_op (insn, operands);"
16522 [(set (attr "type")
16523 (cond [(match_operand:XF 3 "mult_operator" "")
16524 (const_string "fmul")
16525 (match_operand:XF 3 "div_operator" "")
16526 (const_string "fdiv")
16528 (const_string "fop")))
16529 (set_attr "mode" "XF")])
16531 (define_insn "*fop_xf_2_i387"
16532 [(set (match_operand:XF 0 "register_operand" "=f,f")
16533 (match_operator:XF 3 "binary_fp_operator"
16535 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16536 (match_operand:XF 2 "register_operand" "0,0")]))]
16537 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16538 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16539 [(set (attr "type")
16540 (cond [(match_operand:XF 3 "mult_operator" "")
16541 (const_string "fmul")
16542 (match_operand:XF 3 "div_operator" "")
16543 (const_string "fdiv")
16545 (const_string "fop")))
16546 (set_attr "fp_int_src" "true")
16547 (set_attr "mode" "<MODE>")])
16549 (define_insn "*fop_xf_3_i387"
16550 [(set (match_operand:XF 0 "register_operand" "=f,f")
16551 (match_operator:XF 3 "binary_fp_operator"
16552 [(match_operand:XF 1 "register_operand" "0,0")
16554 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_4_i387"
16568 [(set (match_operand:XF 0 "register_operand" "=f,f")
16569 (match_operator:XF 3 "binary_fp_operator"
16571 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16572 (match_operand:XF 2 "register_operand" "0,f")]))]
16574 "* return 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 "mode" "<MODE>")])
16584 (define_insn "*fop_xf_5_i387"
16585 [(set (match_operand:XF 0 "register_operand" "=f,f")
16586 (match_operator:XF 3 "binary_fp_operator"
16587 [(match_operand:XF 1 "register_operand" "0,f")
16589 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16591 "* return output_387_binary_op (insn, operands);"
16592 [(set (attr "type")
16593 (cond [(match_operand:XF 3 "mult_operator" "")
16594 (const_string "fmul")
16595 (match_operand:XF 3 "div_operator" "")
16596 (const_string "fdiv")
16598 (const_string "fop")))
16599 (set_attr "mode" "<MODE>")])
16601 (define_insn "*fop_xf_6_i387"
16602 [(set (match_operand:XF 0 "register_operand" "=f,f")
16603 (match_operator:XF 3 "binary_fp_operator"
16605 (match_operand:MODEF 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>")])
16620 [(set (match_operand 0 "register_operand" "")
16621 (match_operator 3 "binary_fp_operator"
16622 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16623 (match_operand 2 "register_operand" "")]))]
16625 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16628 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16629 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16630 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16631 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16632 GET_MODE (operands[3]),
16635 ix86_free_from_memory (GET_MODE (operands[1]));
16640 [(set (match_operand 0 "register_operand" "")
16641 (match_operator 3 "binary_fp_operator"
16642 [(match_operand 1 "register_operand" "")
16643 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16645 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16648 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16649 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16650 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16651 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16652 GET_MODE (operands[3]),
16655 ix86_free_from_memory (GET_MODE (operands[2]));
16659 ;; FPU special functions.
16661 ;; This pattern implements a no-op XFmode truncation for
16662 ;; all fancy i386 XFmode math functions.
16664 (define_insn "truncxf<mode>2_i387_noop_unspec"
16665 [(set (match_operand:MODEF 0 "register_operand" "=f")
16666 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16667 UNSPEC_TRUNC_NOOP))]
16668 "TARGET_USE_FANCY_MATH_387"
16669 "* return output_387_reg_move (insn, operands);"
16670 [(set_attr "type" "fmov")
16671 (set_attr "mode" "<MODE>")])
16673 (define_insn "sqrtxf2"
16674 [(set (match_operand:XF 0 "register_operand" "=f")
16675 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16676 "TARGET_USE_FANCY_MATH_387"
16678 [(set_attr "type" "fpspc")
16679 (set_attr "mode" "XF")
16680 (set_attr "athlon_decode" "direct")
16681 (set_attr "amdfam10_decode" "direct")])
16683 (define_insn "sqrt_extend<mode>xf2_i387"
16684 [(set (match_operand:XF 0 "register_operand" "=f")
16687 (match_operand:MODEF 1 "register_operand" "0"))))]
16688 "TARGET_USE_FANCY_MATH_387"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")
16692 (set_attr "athlon_decode" "direct")
16693 (set_attr "amdfam10_decode" "direct")])
16695 (define_insn "*rsqrtsf2_sse"
16696 [(set (match_operand:SF 0 "register_operand" "=x")
16697 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16700 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16701 [(set_attr "type" "sse")
16702 (set_attr "prefix" "maybe_vex")
16703 (set_attr "mode" "SF")])
16705 (define_expand "rsqrtsf2"
16706 [(set (match_operand:SF 0 "register_operand" "")
16707 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16711 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16715 (define_insn "*sqrt<mode>2_sse"
16716 [(set (match_operand:MODEF 0 "register_operand" "=x")
16718 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16719 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16720 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16721 [(set_attr "type" "sse")
16722 (set_attr "prefix" "maybe_vex")
16723 (set_attr "mode" "<MODE>")
16724 (set_attr "athlon_decode" "*")
16725 (set_attr "amdfam10_decode" "*")])
16727 (define_expand "sqrt<mode>2"
16728 [(set (match_operand:MODEF 0 "register_operand" "")
16730 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16731 "TARGET_USE_FANCY_MATH_387
16732 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16734 if (<MODE>mode == SFmode
16735 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16736 && flag_finite_math_only && !flag_trapping_math
16737 && flag_unsafe_math_optimizations)
16739 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16743 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16745 rtx op0 = gen_reg_rtx (XFmode);
16746 rtx op1 = force_reg (<MODE>mode, operands[1]);
16748 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16749 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16754 (define_insn "fpremxf4_i387"
16755 [(set (match_operand:XF 0 "register_operand" "=f")
16756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16757 (match_operand:XF 3 "register_operand" "1")]
16759 (set (match_operand:XF 1 "register_operand" "=u")
16760 (unspec:XF [(match_dup 2) (match_dup 3)]
16762 (set (reg:CCFP FPSR_REG)
16763 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16765 "TARGET_USE_FANCY_MATH_387"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16770 (define_expand "fmodxf3"
16771 [(use (match_operand:XF 0 "register_operand" ""))
16772 (use (match_operand:XF 1 "general_operand" ""))
16773 (use (match_operand:XF 2 "general_operand" ""))]
16774 "TARGET_USE_FANCY_MATH_387"
16776 rtx label = gen_label_rtx ();
16778 rtx op1 = gen_reg_rtx (XFmode);
16779 rtx op2 = gen_reg_rtx (XFmode);
16781 emit_move_insn (op2, operands[2]);
16782 emit_move_insn (op1, operands[1]);
16784 emit_label (label);
16785 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16786 ix86_emit_fp_unordered_jump (label);
16787 LABEL_NUSES (label) = 1;
16789 emit_move_insn (operands[0], op1);
16793 (define_expand "fmod<mode>3"
16794 [(use (match_operand:MODEF 0 "register_operand" ""))
16795 (use (match_operand:MODEF 1 "general_operand" ""))
16796 (use (match_operand:MODEF 2 "general_operand" ""))]
16797 "TARGET_USE_FANCY_MATH_387"
16799 rtx label = gen_label_rtx ();
16801 rtx op1 = gen_reg_rtx (XFmode);
16802 rtx op2 = gen_reg_rtx (XFmode);
16804 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16805 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16807 emit_label (label);
16808 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16809 ix86_emit_fp_unordered_jump (label);
16810 LABEL_NUSES (label) = 1;
16812 /* Truncate the result properly for strict SSE math. */
16813 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16814 && !TARGET_MIX_SSE_I387)
16815 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16817 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16822 (define_insn "fprem1xf4_i387"
16823 [(set (match_operand:XF 0 "register_operand" "=f")
16824 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16825 (match_operand:XF 3 "register_operand" "1")]
16827 (set (match_operand:XF 1 "register_operand" "=u")
16828 (unspec:XF [(match_dup 2) (match_dup 3)]
16830 (set (reg:CCFP FPSR_REG)
16831 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16833 "TARGET_USE_FANCY_MATH_387"
16835 [(set_attr "type" "fpspc")
16836 (set_attr "mode" "XF")])
16838 (define_expand "remainderxf3"
16839 [(use (match_operand:XF 0 "register_operand" ""))
16840 (use (match_operand:XF 1 "general_operand" ""))
16841 (use (match_operand:XF 2 "general_operand" ""))]
16842 "TARGET_USE_FANCY_MATH_387"
16844 rtx label = gen_label_rtx ();
16846 rtx op1 = gen_reg_rtx (XFmode);
16847 rtx op2 = gen_reg_rtx (XFmode);
16849 emit_move_insn (op2, operands[2]);
16850 emit_move_insn (op1, operands[1]);
16852 emit_label (label);
16853 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16854 ix86_emit_fp_unordered_jump (label);
16855 LABEL_NUSES (label) = 1;
16857 emit_move_insn (operands[0], op1);
16861 (define_expand "remainder<mode>3"
16862 [(use (match_operand:MODEF 0 "register_operand" ""))
16863 (use (match_operand:MODEF 1 "general_operand" ""))
16864 (use (match_operand:MODEF 2 "general_operand" ""))]
16865 "TARGET_USE_FANCY_MATH_387"
16867 rtx label = gen_label_rtx ();
16869 rtx op1 = gen_reg_rtx (XFmode);
16870 rtx op2 = gen_reg_rtx (XFmode);
16872 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16875 emit_label (label);
16877 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16878 ix86_emit_fp_unordered_jump (label);
16879 LABEL_NUSES (label) = 1;
16881 /* Truncate the result properly for strict SSE math. */
16882 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16883 && !TARGET_MIX_SSE_I387)
16884 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16886 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16891 (define_insn "*sinxf2_i387"
16892 [(set (match_operand:XF 0 "register_operand" "=f")
16893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16900 (define_insn "*sin_extend<mode>xf2_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(float_extend:XF
16903 (match_operand:MODEF 1 "register_operand" "0"))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16907 || TARGET_MIX_SSE_I387)
16908 && flag_unsafe_math_optimizations"
16910 [(set_attr "type" "fpspc")
16911 (set_attr "mode" "XF")])
16913 (define_insn "*cosxf2_i387"
16914 [(set (match_operand:XF 0 "register_operand" "=f")
16915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && flag_unsafe_math_optimizations"
16919 [(set_attr "type" "fpspc")
16920 (set_attr "mode" "XF")])
16922 (define_insn "*cos_extend<mode>xf2_i387"
16923 [(set (match_operand:XF 0 "register_operand" "=f")
16924 (unspec:XF [(float_extend:XF
16925 (match_operand:MODEF 1 "register_operand" "0"))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929 || TARGET_MIX_SSE_I387)
16930 && flag_unsafe_math_optimizations"
16932 [(set_attr "type" "fpspc")
16933 (set_attr "mode" "XF")])
16935 ;; When sincos pattern is defined, sin and cos builtin functions will be
16936 ;; expanded to sincos pattern with one of its outputs left unused.
16937 ;; CSE pass will figure out if two sincos patterns can be combined,
16938 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16939 ;; depending on the unused output.
16941 (define_insn "sincosxf3"
16942 [(set (match_operand:XF 0 "register_operand" "=f")
16943 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16944 UNSPEC_SINCOS_COS))
16945 (set (match_operand:XF 1 "register_operand" "=u")
16946 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16947 "TARGET_USE_FANCY_MATH_387
16948 && flag_unsafe_math_optimizations"
16950 [(set_attr "type" "fpspc")
16951 (set_attr "mode" "XF")])
16954 [(set (match_operand:XF 0 "register_operand" "")
16955 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16956 UNSPEC_SINCOS_COS))
16957 (set (match_operand:XF 1 "register_operand" "")
16958 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16960 && !(reload_completed || reload_in_progress)"
16961 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16965 [(set (match_operand:XF 0 "register_operand" "")
16966 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16967 UNSPEC_SINCOS_COS))
16968 (set (match_operand:XF 1 "register_operand" "")
16969 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16971 && !(reload_completed || reload_in_progress)"
16972 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16975 (define_insn "sincos_extend<mode>xf3_i387"
16976 [(set (match_operand:XF 0 "register_operand" "=f")
16977 (unspec:XF [(float_extend:XF
16978 (match_operand:MODEF 2 "register_operand" "0"))]
16979 UNSPEC_SINCOS_COS))
16980 (set (match_operand:XF 1 "register_operand" "=u")
16981 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16982 "TARGET_USE_FANCY_MATH_387
16983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16984 || TARGET_MIX_SSE_I387)
16985 && flag_unsafe_math_optimizations"
16987 [(set_attr "type" "fpspc")
16988 (set_attr "mode" "XF")])
16991 [(set (match_operand:XF 0 "register_operand" "")
16992 (unspec:XF [(float_extend:XF
16993 (match_operand:MODEF 2 "register_operand" ""))]
16994 UNSPEC_SINCOS_COS))
16995 (set (match_operand:XF 1 "register_operand" "")
16996 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16997 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16998 && !(reload_completed || reload_in_progress)"
16999 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17003 [(set (match_operand:XF 0 "register_operand" "")
17004 (unspec:XF [(float_extend:XF
17005 (match_operand:MODEF 2 "register_operand" ""))]
17006 UNSPEC_SINCOS_COS))
17007 (set (match_operand:XF 1 "register_operand" "")
17008 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17009 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17010 && !(reload_completed || reload_in_progress)"
17011 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17014 (define_expand "sincos<mode>3"
17015 [(use (match_operand:MODEF 0 "register_operand" ""))
17016 (use (match_operand:MODEF 1 "register_operand" ""))
17017 (use (match_operand:MODEF 2 "register_operand" ""))]
17018 "TARGET_USE_FANCY_MATH_387
17019 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17020 || TARGET_MIX_SSE_I387)
17021 && flag_unsafe_math_optimizations"
17023 rtx op0 = gen_reg_rtx (XFmode);
17024 rtx op1 = gen_reg_rtx (XFmode);
17026 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17028 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17032 (define_insn "fptanxf4_i387"
17033 [(set (match_operand:XF 0 "register_operand" "=f")
17034 (match_operand:XF 3 "const_double_operand" "F"))
17035 (set (match_operand:XF 1 "register_operand" "=u")
17036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17038 "TARGET_USE_FANCY_MATH_387
17039 && flag_unsafe_math_optimizations
17040 && standard_80387_constant_p (operands[3]) == 2"
17042 [(set_attr "type" "fpspc")
17043 (set_attr "mode" "XF")])
17045 (define_insn "fptan_extend<mode>xf4_i387"
17046 [(set (match_operand:MODEF 0 "register_operand" "=f")
17047 (match_operand:MODEF 3 "const_double_operand" "F"))
17048 (set (match_operand:XF 1 "register_operand" "=u")
17049 (unspec:XF [(float_extend:XF
17050 (match_operand:MODEF 2 "register_operand" "0"))]
17052 "TARGET_USE_FANCY_MATH_387
17053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17054 || TARGET_MIX_SSE_I387)
17055 && flag_unsafe_math_optimizations
17056 && standard_80387_constant_p (operands[3]) == 2"
17058 [(set_attr "type" "fpspc")
17059 (set_attr "mode" "XF")])
17061 (define_expand "tanxf2"
17062 [(use (match_operand:XF 0 "register_operand" ""))
17063 (use (match_operand:XF 1 "register_operand" ""))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && flag_unsafe_math_optimizations"
17067 rtx one = gen_reg_rtx (XFmode);
17068 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17070 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17074 (define_expand "tan<mode>2"
17075 [(use (match_operand:MODEF 0 "register_operand" ""))
17076 (use (match_operand:MODEF 1 "register_operand" ""))]
17077 "TARGET_USE_FANCY_MATH_387
17078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17079 || TARGET_MIX_SSE_I387)
17080 && flag_unsafe_math_optimizations"
17082 rtx op0 = gen_reg_rtx (XFmode);
17084 rtx one = gen_reg_rtx (<MODE>mode);
17085 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17087 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17088 operands[1], op2));
17089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17093 (define_insn "*fpatanxf3_i387"
17094 [(set (match_operand:XF 0 "register_operand" "=f")
17095 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17096 (match_operand:XF 2 "register_operand" "u")]
17098 (clobber (match_scratch:XF 3 "=2"))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && flag_unsafe_math_optimizations"
17102 [(set_attr "type" "fpspc")
17103 (set_attr "mode" "XF")])
17105 (define_insn "fpatan_extend<mode>xf3_i387"
17106 [(set (match_operand:XF 0 "register_operand" "=f")
17107 (unspec:XF [(float_extend:XF
17108 (match_operand:MODEF 1 "register_operand" "0"))
17110 (match_operand:MODEF 2 "register_operand" "u"))]
17112 (clobber (match_scratch:XF 3 "=2"))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17115 || TARGET_MIX_SSE_I387)
17116 && flag_unsafe_math_optimizations"
17118 [(set_attr "type" "fpspc")
17119 (set_attr "mode" "XF")])
17121 (define_expand "atan2xf3"
17122 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17123 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17124 (match_operand:XF 1 "register_operand" "")]
17126 (clobber (match_scratch:XF 3 ""))])]
17127 "TARGET_USE_FANCY_MATH_387
17128 && flag_unsafe_math_optimizations"
17131 (define_expand "atan2<mode>3"
17132 [(use (match_operand:MODEF 0 "register_operand" ""))
17133 (use (match_operand:MODEF 1 "register_operand" ""))
17134 (use (match_operand:MODEF 2 "register_operand" ""))]
17135 "TARGET_USE_FANCY_MATH_387
17136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17137 || TARGET_MIX_SSE_I387)
17138 && flag_unsafe_math_optimizations"
17140 rtx op0 = gen_reg_rtx (XFmode);
17142 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17143 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17147 (define_expand "atanxf2"
17148 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17149 (unspec:XF [(match_dup 2)
17150 (match_operand:XF 1 "register_operand" "")]
17152 (clobber (match_scratch:XF 3 ""))])]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations"
17156 operands[2] = gen_reg_rtx (XFmode);
17157 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17160 (define_expand "atan<mode>2"
17161 [(use (match_operand:MODEF 0 "register_operand" ""))
17162 (use (match_operand:MODEF 1 "register_operand" ""))]
17163 "TARGET_USE_FANCY_MATH_387
17164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17165 || TARGET_MIX_SSE_I387)
17166 && flag_unsafe_math_optimizations"
17168 rtx op0 = gen_reg_rtx (XFmode);
17170 rtx op2 = gen_reg_rtx (<MODE>mode);
17171 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17173 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17178 (define_expand "asinxf2"
17179 [(set (match_dup 2)
17180 (mult:XF (match_operand:XF 1 "register_operand" "")
17182 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17183 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17184 (parallel [(set (match_operand:XF 0 "register_operand" "")
17185 (unspec:XF [(match_dup 5) (match_dup 1)]
17187 (clobber (match_scratch:XF 6 ""))])]
17188 "TARGET_USE_FANCY_MATH_387
17189 && flag_unsafe_math_optimizations"
17193 if (optimize_insn_for_size_p ())
17196 for (i = 2; i < 6; i++)
17197 operands[i] = gen_reg_rtx (XFmode);
17199 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17202 (define_expand "asin<mode>2"
17203 [(use (match_operand:MODEF 0 "register_operand" ""))
17204 (use (match_operand:MODEF 1 "general_operand" ""))]
17205 "TARGET_USE_FANCY_MATH_387
17206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17207 || TARGET_MIX_SSE_I387)
17208 && flag_unsafe_math_optimizations"
17210 rtx op0 = gen_reg_rtx (XFmode);
17211 rtx op1 = gen_reg_rtx (XFmode);
17213 if (optimize_insn_for_size_p ())
17216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17217 emit_insn (gen_asinxf2 (op0, op1));
17218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17222 (define_expand "acosxf2"
17223 [(set (match_dup 2)
17224 (mult:XF (match_operand:XF 1 "register_operand" "")
17226 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17227 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17228 (parallel [(set (match_operand:XF 0 "register_operand" "")
17229 (unspec:XF [(match_dup 1) (match_dup 5)]
17231 (clobber (match_scratch:XF 6 ""))])]
17232 "TARGET_USE_FANCY_MATH_387
17233 && flag_unsafe_math_optimizations"
17237 if (optimize_insn_for_size_p ())
17240 for (i = 2; i < 6; i++)
17241 operands[i] = gen_reg_rtx (XFmode);
17243 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17246 (define_expand "acos<mode>2"
17247 [(use (match_operand:MODEF 0 "register_operand" ""))
17248 (use (match_operand:MODEF 1 "general_operand" ""))]
17249 "TARGET_USE_FANCY_MATH_387
17250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17251 || TARGET_MIX_SSE_I387)
17252 && flag_unsafe_math_optimizations"
17254 rtx op0 = gen_reg_rtx (XFmode);
17255 rtx op1 = gen_reg_rtx (XFmode);
17257 if (optimize_insn_for_size_p ())
17260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17261 emit_insn (gen_acosxf2 (op0, op1));
17262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17266 (define_insn "fyl2xxf3_i387"
17267 [(set (match_operand:XF 0 "register_operand" "=f")
17268 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17269 (match_operand:XF 2 "register_operand" "u")]
17271 (clobber (match_scratch:XF 3 "=2"))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations"
17275 [(set_attr "type" "fpspc")
17276 (set_attr "mode" "XF")])
17278 (define_insn "fyl2x_extend<mode>xf3_i387"
17279 [(set (match_operand:XF 0 "register_operand" "=f")
17280 (unspec:XF [(float_extend:XF
17281 (match_operand:MODEF 1 "register_operand" "0"))
17282 (match_operand:XF 2 "register_operand" "u")]
17284 (clobber (match_scratch:XF 3 "=2"))]
17285 "TARGET_USE_FANCY_MATH_387
17286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287 || TARGET_MIX_SSE_I387)
17288 && flag_unsafe_math_optimizations"
17290 [(set_attr "type" "fpspc")
17291 (set_attr "mode" "XF")])
17293 (define_expand "logxf2"
17294 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17295 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17296 (match_dup 2)] UNSPEC_FYL2X))
17297 (clobber (match_scratch:XF 3 ""))])]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations"
17301 operands[2] = gen_reg_rtx (XFmode);
17302 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17305 (define_expand "log<mode>2"
17306 [(use (match_operand:MODEF 0 "register_operand" ""))
17307 (use (match_operand:MODEF 1 "register_operand" ""))]
17308 "TARGET_USE_FANCY_MATH_387
17309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17310 || TARGET_MIX_SSE_I387)
17311 && flag_unsafe_math_optimizations"
17313 rtx op0 = gen_reg_rtx (XFmode);
17315 rtx op2 = gen_reg_rtx (XFmode);
17316 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17318 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17319 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17323 (define_expand "log10xf2"
17324 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17325 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17326 (match_dup 2)] UNSPEC_FYL2X))
17327 (clobber (match_scratch:XF 3 ""))])]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17331 operands[2] = gen_reg_rtx (XFmode);
17332 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17335 (define_expand "log10<mode>2"
17336 [(use (match_operand:MODEF 0 "register_operand" ""))
17337 (use (match_operand:MODEF 1 "register_operand" ""))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340 || TARGET_MIX_SSE_I387)
17341 && flag_unsafe_math_optimizations"
17343 rtx op0 = gen_reg_rtx (XFmode);
17345 rtx op2 = gen_reg_rtx (XFmode);
17346 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17348 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353 (define_expand "log2xf2"
17354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17355 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356 (match_dup 2)] UNSPEC_FYL2X))
17357 (clobber (match_scratch:XF 3 ""))])]
17358 "TARGET_USE_FANCY_MATH_387
17359 && flag_unsafe_math_optimizations"
17361 operands[2] = gen_reg_rtx (XFmode);
17362 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17365 (define_expand "log2<mode>2"
17366 [(use (match_operand:MODEF 0 "register_operand" ""))
17367 (use (match_operand:MODEF 1 "register_operand" ""))]
17368 "TARGET_USE_FANCY_MATH_387
17369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370 || TARGET_MIX_SSE_I387)
17371 && flag_unsafe_math_optimizations"
17373 rtx op0 = gen_reg_rtx (XFmode);
17375 rtx op2 = gen_reg_rtx (XFmode);
17376 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17378 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17383 (define_insn "fyl2xp1xf3_i387"
17384 [(set (match_operand:XF 0 "register_operand" "=f")
17385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17386 (match_operand:XF 2 "register_operand" "u")]
17388 (clobber (match_scratch:XF 3 "=2"))]
17389 "TARGET_USE_FANCY_MATH_387
17390 && flag_unsafe_math_optimizations"
17392 [(set_attr "type" "fpspc")
17393 (set_attr "mode" "XF")])
17395 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17396 [(set (match_operand:XF 0 "register_operand" "=f")
17397 (unspec:XF [(float_extend:XF
17398 (match_operand:MODEF 1 "register_operand" "0"))
17399 (match_operand:XF 2 "register_operand" "u")]
17401 (clobber (match_scratch:XF 3 "=2"))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17404 || TARGET_MIX_SSE_I387)
17405 && flag_unsafe_math_optimizations"
17407 [(set_attr "type" "fpspc")
17408 (set_attr "mode" "XF")])
17410 (define_expand "log1pxf2"
17411 [(use (match_operand:XF 0 "register_operand" ""))
17412 (use (match_operand:XF 1 "register_operand" ""))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17416 if (optimize_insn_for_size_p ())
17419 ix86_emit_i387_log1p (operands[0], operands[1]);
17423 (define_expand "log1p<mode>2"
17424 [(use (match_operand:MODEF 0 "register_operand" ""))
17425 (use (match_operand:MODEF 1 "register_operand" ""))]
17426 "TARGET_USE_FANCY_MATH_387
17427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17428 || TARGET_MIX_SSE_I387)
17429 && flag_unsafe_math_optimizations"
17433 if (optimize_insn_for_size_p ())
17436 op0 = gen_reg_rtx (XFmode);
17438 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17440 ix86_emit_i387_log1p (op0, operands[1]);
17441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17445 (define_insn "fxtractxf3_i387"
17446 [(set (match_operand:XF 0 "register_operand" "=f")
17447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17448 UNSPEC_XTRACT_FRACT))
17449 (set (match_operand:XF 1 "register_operand" "=u")
17450 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17451 "TARGET_USE_FANCY_MATH_387
17452 && flag_unsafe_math_optimizations"
17454 [(set_attr "type" "fpspc")
17455 (set_attr "mode" "XF")])
17457 (define_insn "fxtract_extend<mode>xf3_i387"
17458 [(set (match_operand:XF 0 "register_operand" "=f")
17459 (unspec:XF [(float_extend:XF
17460 (match_operand:MODEF 2 "register_operand" "0"))]
17461 UNSPEC_XTRACT_FRACT))
17462 (set (match_operand:XF 1 "register_operand" "=u")
17463 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17464 "TARGET_USE_FANCY_MATH_387
17465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17466 || TARGET_MIX_SSE_I387)
17467 && flag_unsafe_math_optimizations"
17469 [(set_attr "type" "fpspc")
17470 (set_attr "mode" "XF")])
17472 (define_expand "logbxf2"
17473 [(parallel [(set (match_dup 2)
17474 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17475 UNSPEC_XTRACT_FRACT))
17476 (set (match_operand:XF 0 "register_operand" "")
17477 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17478 "TARGET_USE_FANCY_MATH_387
17479 && flag_unsafe_math_optimizations"
17481 operands[2] = gen_reg_rtx (XFmode);
17484 (define_expand "logb<mode>2"
17485 [(use (match_operand:MODEF 0 "register_operand" ""))
17486 (use (match_operand:MODEF 1 "register_operand" ""))]
17487 "TARGET_USE_FANCY_MATH_387
17488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17489 || TARGET_MIX_SSE_I387)
17490 && flag_unsafe_math_optimizations"
17492 rtx op0 = gen_reg_rtx (XFmode);
17493 rtx op1 = gen_reg_rtx (XFmode);
17495 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17496 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17500 (define_expand "ilogbxf2"
17501 [(use (match_operand:SI 0 "register_operand" ""))
17502 (use (match_operand:XF 1 "register_operand" ""))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17508 if (optimize_insn_for_size_p ())
17511 op0 = gen_reg_rtx (XFmode);
17512 op1 = gen_reg_rtx (XFmode);
17514 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17515 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17519 (define_expand "ilogb<mode>2"
17520 [(use (match_operand:SI 0 "register_operand" ""))
17521 (use (match_operand:MODEF 1 "register_operand" ""))]
17522 "TARGET_USE_FANCY_MATH_387
17523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17524 || TARGET_MIX_SSE_I387)
17525 && flag_unsafe_math_optimizations"
17529 if (optimize_insn_for_size_p ())
17532 op0 = gen_reg_rtx (XFmode);
17533 op1 = gen_reg_rtx (XFmode);
17535 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17536 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17540 (define_insn "*f2xm1xf2_i387"
17541 [(set (match_operand:XF 0 "register_operand" "=f")
17542 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17544 "TARGET_USE_FANCY_MATH_387
17545 && flag_unsafe_math_optimizations"
17547 [(set_attr "type" "fpspc")
17548 (set_attr "mode" "XF")])
17550 (define_insn "*fscalexf4_i387"
17551 [(set (match_operand:XF 0 "register_operand" "=f")
17552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17553 (match_operand:XF 3 "register_operand" "1")]
17554 UNSPEC_FSCALE_FRACT))
17555 (set (match_operand:XF 1 "register_operand" "=u")
17556 (unspec:XF [(match_dup 2) (match_dup 3)]
17557 UNSPEC_FSCALE_EXP))]
17558 "TARGET_USE_FANCY_MATH_387
17559 && flag_unsafe_math_optimizations"
17561 [(set_attr "type" "fpspc")
17562 (set_attr "mode" "XF")])
17564 (define_expand "expNcorexf3"
17565 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17566 (match_operand:XF 2 "register_operand" "")))
17567 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17568 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17569 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17570 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17571 (parallel [(set (match_operand:XF 0 "register_operand" "")
17572 (unspec:XF [(match_dup 8) (match_dup 4)]
17573 UNSPEC_FSCALE_FRACT))
17575 (unspec:XF [(match_dup 8) (match_dup 4)]
17576 UNSPEC_FSCALE_EXP))])]
17577 "TARGET_USE_FANCY_MATH_387
17578 && flag_unsafe_math_optimizations"
17582 if (optimize_insn_for_size_p ())
17585 for (i = 3; i < 10; i++)
17586 operands[i] = gen_reg_rtx (XFmode);
17588 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17591 (define_expand "expxf2"
17592 [(use (match_operand:XF 0 "register_operand" ""))
17593 (use (match_operand:XF 1 "register_operand" ""))]
17594 "TARGET_USE_FANCY_MATH_387
17595 && flag_unsafe_math_optimizations"
17599 if (optimize_insn_for_size_p ())
17602 op2 = gen_reg_rtx (XFmode);
17603 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17605 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17609 (define_expand "exp<mode>2"
17610 [(use (match_operand:MODEF 0 "register_operand" ""))
17611 (use (match_operand:MODEF 1 "general_operand" ""))]
17612 "TARGET_USE_FANCY_MATH_387
17613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614 || TARGET_MIX_SSE_I387)
17615 && flag_unsafe_math_optimizations"
17619 if (optimize_insn_for_size_p ())
17622 op0 = gen_reg_rtx (XFmode);
17623 op1 = gen_reg_rtx (XFmode);
17625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17626 emit_insn (gen_expxf2 (op0, op1));
17627 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17631 (define_expand "exp10xf2"
17632 [(use (match_operand:XF 0 "register_operand" ""))
17633 (use (match_operand:XF 1 "register_operand" ""))]
17634 "TARGET_USE_FANCY_MATH_387
17635 && flag_unsafe_math_optimizations"
17639 if (optimize_insn_for_size_p ())
17642 op2 = gen_reg_rtx (XFmode);
17643 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17645 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17649 (define_expand "exp10<mode>2"
17650 [(use (match_operand:MODEF 0 "register_operand" ""))
17651 (use (match_operand:MODEF 1 "general_operand" ""))]
17652 "TARGET_USE_FANCY_MATH_387
17653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17654 || TARGET_MIX_SSE_I387)
17655 && flag_unsafe_math_optimizations"
17659 if (optimize_insn_for_size_p ())
17662 op0 = gen_reg_rtx (XFmode);
17663 op1 = gen_reg_rtx (XFmode);
17665 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17666 emit_insn (gen_exp10xf2 (op0, op1));
17667 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17671 (define_expand "exp2xf2"
17672 [(use (match_operand:XF 0 "register_operand" ""))
17673 (use (match_operand:XF 1 "register_operand" ""))]
17674 "TARGET_USE_FANCY_MATH_387
17675 && flag_unsafe_math_optimizations"
17679 if (optimize_insn_for_size_p ())
17682 op2 = gen_reg_rtx (XFmode);
17683 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17685 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17689 (define_expand "exp2<mode>2"
17690 [(use (match_operand:MODEF 0 "register_operand" ""))
17691 (use (match_operand:MODEF 1 "general_operand" ""))]
17692 "TARGET_USE_FANCY_MATH_387
17693 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17694 || TARGET_MIX_SSE_I387)
17695 && flag_unsafe_math_optimizations"
17699 if (optimize_insn_for_size_p ())
17702 op0 = gen_reg_rtx (XFmode);
17703 op1 = gen_reg_rtx (XFmode);
17705 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17706 emit_insn (gen_exp2xf2 (op0, op1));
17707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17711 (define_expand "expm1xf2"
17712 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17714 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17715 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17716 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17717 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17718 (parallel [(set (match_dup 7)
17719 (unspec:XF [(match_dup 6) (match_dup 4)]
17720 UNSPEC_FSCALE_FRACT))
17722 (unspec:XF [(match_dup 6) (match_dup 4)]
17723 UNSPEC_FSCALE_EXP))])
17724 (parallel [(set (match_dup 10)
17725 (unspec:XF [(match_dup 9) (match_dup 8)]
17726 UNSPEC_FSCALE_FRACT))
17727 (set (match_dup 11)
17728 (unspec:XF [(match_dup 9) (match_dup 8)]
17729 UNSPEC_FSCALE_EXP))])
17730 (set (match_dup 12) (minus:XF (match_dup 10)
17731 (float_extend:XF (match_dup 13))))
17732 (set (match_operand:XF 0 "register_operand" "")
17733 (plus:XF (match_dup 12) (match_dup 7)))]
17734 "TARGET_USE_FANCY_MATH_387
17735 && flag_unsafe_math_optimizations"
17739 if (optimize_insn_for_size_p ())
17742 for (i = 2; i < 13; i++)
17743 operands[i] = gen_reg_rtx (XFmode);
17746 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17748 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17751 (define_expand "expm1<mode>2"
17752 [(use (match_operand:MODEF 0 "register_operand" ""))
17753 (use (match_operand:MODEF 1 "general_operand" ""))]
17754 "TARGET_USE_FANCY_MATH_387
17755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17756 || TARGET_MIX_SSE_I387)
17757 && flag_unsafe_math_optimizations"
17761 if (optimize_insn_for_size_p ())
17764 op0 = gen_reg_rtx (XFmode);
17765 op1 = gen_reg_rtx (XFmode);
17767 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17768 emit_insn (gen_expm1xf2 (op0, op1));
17769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17773 (define_expand "ldexpxf3"
17774 [(set (match_dup 3)
17775 (float:XF (match_operand:SI 2 "register_operand" "")))
17776 (parallel [(set (match_operand:XF 0 " register_operand" "")
17777 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17779 UNSPEC_FSCALE_FRACT))
17781 (unspec:XF [(match_dup 1) (match_dup 3)]
17782 UNSPEC_FSCALE_EXP))])]
17783 "TARGET_USE_FANCY_MATH_387
17784 && flag_unsafe_math_optimizations"
17786 if (optimize_insn_for_size_p ())
17789 operands[3] = gen_reg_rtx (XFmode);
17790 operands[4] = gen_reg_rtx (XFmode);
17793 (define_expand "ldexp<mode>3"
17794 [(use (match_operand:MODEF 0 "register_operand" ""))
17795 (use (match_operand:MODEF 1 "general_operand" ""))
17796 (use (match_operand:SI 2 "register_operand" ""))]
17797 "TARGET_USE_FANCY_MATH_387
17798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17799 || TARGET_MIX_SSE_I387)
17800 && flag_unsafe_math_optimizations"
17804 if (optimize_insn_for_size_p ())
17807 op0 = gen_reg_rtx (XFmode);
17808 op1 = gen_reg_rtx (XFmode);
17810 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17816 (define_expand "scalbxf3"
17817 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17818 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17819 (match_operand:XF 2 "register_operand" "")]
17820 UNSPEC_FSCALE_FRACT))
17822 (unspec:XF [(match_dup 1) (match_dup 2)]
17823 UNSPEC_FSCALE_EXP))])]
17824 "TARGET_USE_FANCY_MATH_387
17825 && flag_unsafe_math_optimizations"
17827 if (optimize_insn_for_size_p ())
17830 operands[3] = gen_reg_rtx (XFmode);
17833 (define_expand "scalb<mode>3"
17834 [(use (match_operand:MODEF 0 "register_operand" ""))
17835 (use (match_operand:MODEF 1 "general_operand" ""))
17836 (use (match_operand:MODEF 2 "register_operand" ""))]
17837 "TARGET_USE_FANCY_MATH_387
17838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17839 || TARGET_MIX_SSE_I387)
17840 && flag_unsafe_math_optimizations"
17844 if (optimize_insn_for_size_p ())
17847 op0 = gen_reg_rtx (XFmode);
17848 op1 = gen_reg_rtx (XFmode);
17849 op2 = gen_reg_rtx (XFmode);
17851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17852 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17853 emit_insn (gen_scalbxf3 (op0, op1, op2));
17854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17859 (define_insn "sse4_1_round<mode>2"
17860 [(set (match_operand:MODEF 0 "register_operand" "=x")
17861 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17862 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17865 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17866 [(set_attr "type" "ssecvt")
17867 (set_attr "prefix_extra" "1")
17868 (set_attr "prefix" "maybe_vex")
17869 (set_attr "mode" "<MODE>")])
17871 (define_insn "rintxf2"
17872 [(set (match_operand:XF 0 "register_operand" "=f")
17873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17875 "TARGET_USE_FANCY_MATH_387
17876 && flag_unsafe_math_optimizations"
17878 [(set_attr "type" "fpspc")
17879 (set_attr "mode" "XF")])
17881 (define_expand "rint<mode>2"
17882 [(use (match_operand:MODEF 0 "register_operand" ""))
17883 (use (match_operand:MODEF 1 "register_operand" ""))]
17884 "(TARGET_USE_FANCY_MATH_387
17885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17886 || TARGET_MIX_SSE_I387)
17887 && flag_unsafe_math_optimizations)
17888 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17889 && !flag_trapping_math)"
17891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17892 && !flag_trapping_math)
17894 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17897 emit_insn (gen_sse4_1_round<mode>2
17898 (operands[0], operands[1], GEN_INT (0x04)));
17900 ix86_expand_rint (operand0, operand1);
17904 rtx op0 = gen_reg_rtx (XFmode);
17905 rtx op1 = gen_reg_rtx (XFmode);
17907 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17908 emit_insn (gen_rintxf2 (op0, op1));
17910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17915 (define_expand "round<mode>2"
17916 [(match_operand:MODEF 0 "register_operand" "")
17917 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17918 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919 && !flag_trapping_math && !flag_rounding_math"
17921 if (optimize_insn_for_size_p ())
17923 if (TARGET_64BIT || (<MODE>mode != DFmode))
17924 ix86_expand_round (operand0, operand1);
17926 ix86_expand_rounddf_32 (operand0, operand1);
17930 (define_insn_and_split "*fistdi2_1"
17931 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17932 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17934 "TARGET_USE_FANCY_MATH_387
17935 && !(reload_completed || reload_in_progress)"
17940 if (memory_operand (operands[0], VOIDmode))
17941 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17944 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17945 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17950 [(set_attr "type" "fpspc")
17951 (set_attr "mode" "DI")])
17953 (define_insn "fistdi2"
17954 [(set (match_operand:DI 0 "memory_operand" "=m")
17955 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17957 (clobber (match_scratch:XF 2 "=&1f"))]
17958 "TARGET_USE_FANCY_MATH_387"
17959 "* return output_fix_trunc (insn, operands, 0);"
17960 [(set_attr "type" "fpspc")
17961 (set_attr "mode" "DI")])
17963 (define_insn "fistdi2_with_temp"
17964 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17965 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17967 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17968 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17969 "TARGET_USE_FANCY_MATH_387"
17971 [(set_attr "type" "fpspc")
17972 (set_attr "mode" "DI")])
17975 [(set (match_operand:DI 0 "register_operand" "")
17976 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17978 (clobber (match_operand:DI 2 "memory_operand" ""))
17979 (clobber (match_scratch 3 ""))]
17981 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17982 (clobber (match_dup 3))])
17983 (set (match_dup 0) (match_dup 2))]
17987 [(set (match_operand:DI 0 "memory_operand" "")
17988 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17990 (clobber (match_operand:DI 2 "memory_operand" ""))
17991 (clobber (match_scratch 3 ""))]
17993 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17994 (clobber (match_dup 3))])]
17997 (define_insn_and_split "*fist<mode>2_1"
17998 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17999 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18001 "TARGET_USE_FANCY_MATH_387
18002 && !(reload_completed || reload_in_progress)"
18007 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18008 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18012 [(set_attr "type" "fpspc")
18013 (set_attr "mode" "<MODE>")])
18015 (define_insn "fist<mode>2"
18016 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18017 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18019 "TARGET_USE_FANCY_MATH_387"
18020 "* return output_fix_trunc (insn, operands, 0);"
18021 [(set_attr "type" "fpspc")
18022 (set_attr "mode" "<MODE>")])
18024 (define_insn "fist<mode>2_with_temp"
18025 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18026 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18028 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18029 "TARGET_USE_FANCY_MATH_387"
18031 [(set_attr "type" "fpspc")
18032 (set_attr "mode" "<MODE>")])
18035 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18036 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18038 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18040 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18041 (set (match_dup 0) (match_dup 2))]
18045 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18046 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18048 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18050 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18053 (define_expand "lrintxf<mode>2"
18054 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18055 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18057 "TARGET_USE_FANCY_MATH_387"
18060 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18061 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18062 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18063 UNSPEC_FIX_NOTRUNC))]
18064 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18065 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18068 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18069 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18070 (match_operand:MODEF 1 "register_operand" "")]
18071 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18072 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18073 && !flag_trapping_math && !flag_rounding_math"
18075 if (optimize_insn_for_size_p ())
18077 ix86_expand_lround (operand0, operand1);
18081 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18082 (define_insn_and_split "frndintxf2_floor"
18083 [(set (match_operand:XF 0 "register_operand" "")
18084 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18085 UNSPEC_FRNDINT_FLOOR))
18086 (clobber (reg:CC FLAGS_REG))]
18087 "TARGET_USE_FANCY_MATH_387
18088 && flag_unsafe_math_optimizations
18089 && !(reload_completed || reload_in_progress)"
18094 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18096 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18097 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18099 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18100 operands[2], operands[3]));
18103 [(set_attr "type" "frndint")
18104 (set_attr "i387_cw" "floor")
18105 (set_attr "mode" "XF")])
18107 (define_insn "frndintxf2_floor_i387"
18108 [(set (match_operand:XF 0 "register_operand" "=f")
18109 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18110 UNSPEC_FRNDINT_FLOOR))
18111 (use (match_operand:HI 2 "memory_operand" "m"))
18112 (use (match_operand:HI 3 "memory_operand" "m"))]
18113 "TARGET_USE_FANCY_MATH_387
18114 && flag_unsafe_math_optimizations"
18115 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18116 [(set_attr "type" "frndint")
18117 (set_attr "i387_cw" "floor")
18118 (set_attr "mode" "XF")])
18120 (define_expand "floorxf2"
18121 [(use (match_operand:XF 0 "register_operand" ""))
18122 (use (match_operand:XF 1 "register_operand" ""))]
18123 "TARGET_USE_FANCY_MATH_387
18124 && flag_unsafe_math_optimizations"
18126 if (optimize_insn_for_size_p ())
18128 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18132 (define_expand "floor<mode>2"
18133 [(use (match_operand:MODEF 0 "register_operand" ""))
18134 (use (match_operand:MODEF 1 "register_operand" ""))]
18135 "(TARGET_USE_FANCY_MATH_387
18136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18137 || TARGET_MIX_SSE_I387)
18138 && flag_unsafe_math_optimizations)
18139 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18140 && !flag_trapping_math)"
18142 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18143 && !flag_trapping_math
18144 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18146 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18149 emit_insn (gen_sse4_1_round<mode>2
18150 (operands[0], operands[1], GEN_INT (0x01)));
18151 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18152 ix86_expand_floorceil (operand0, operand1, true);
18154 ix86_expand_floorceildf_32 (operand0, operand1, true);
18160 if (optimize_insn_for_size_p ())
18163 op0 = gen_reg_rtx (XFmode);
18164 op1 = gen_reg_rtx (XFmode);
18165 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18166 emit_insn (gen_frndintxf2_floor (op0, op1));
18168 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18173 (define_insn_and_split "*fist<mode>2_floor_1"
18174 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18175 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18176 UNSPEC_FIST_FLOOR))
18177 (clobber (reg:CC FLAGS_REG))]
18178 "TARGET_USE_FANCY_MATH_387
18179 && flag_unsafe_math_optimizations
18180 && !(reload_completed || reload_in_progress)"
18185 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18187 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18188 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18189 if (memory_operand (operands[0], VOIDmode))
18190 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18191 operands[2], operands[3]));
18194 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18195 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18196 operands[2], operands[3],
18201 [(set_attr "type" "fistp")
18202 (set_attr "i387_cw" "floor")
18203 (set_attr "mode" "<MODE>")])
18205 (define_insn "fistdi2_floor"
18206 [(set (match_operand:DI 0 "memory_operand" "=m")
18207 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18208 UNSPEC_FIST_FLOOR))
18209 (use (match_operand:HI 2 "memory_operand" "m"))
18210 (use (match_operand:HI 3 "memory_operand" "m"))
18211 (clobber (match_scratch:XF 4 "=&1f"))]
18212 "TARGET_USE_FANCY_MATH_387
18213 && flag_unsafe_math_optimizations"
18214 "* return output_fix_trunc (insn, operands, 0);"
18215 [(set_attr "type" "fistp")
18216 (set_attr "i387_cw" "floor")
18217 (set_attr "mode" "DI")])
18219 (define_insn "fistdi2_floor_with_temp"
18220 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18221 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18222 UNSPEC_FIST_FLOOR))
18223 (use (match_operand:HI 2 "memory_operand" "m,m"))
18224 (use (match_operand:HI 3 "memory_operand" "m,m"))
18225 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18226 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18227 "TARGET_USE_FANCY_MATH_387
18228 && flag_unsafe_math_optimizations"
18230 [(set_attr "type" "fistp")
18231 (set_attr "i387_cw" "floor")
18232 (set_attr "mode" "DI")])
18235 [(set (match_operand:DI 0 "register_operand" "")
18236 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18237 UNSPEC_FIST_FLOOR))
18238 (use (match_operand:HI 2 "memory_operand" ""))
18239 (use (match_operand:HI 3 "memory_operand" ""))
18240 (clobber (match_operand:DI 4 "memory_operand" ""))
18241 (clobber (match_scratch 5 ""))]
18243 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18244 (use (match_dup 2))
18245 (use (match_dup 3))
18246 (clobber (match_dup 5))])
18247 (set (match_dup 0) (match_dup 4))]
18251 [(set (match_operand:DI 0 "memory_operand" "")
18252 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18253 UNSPEC_FIST_FLOOR))
18254 (use (match_operand:HI 2 "memory_operand" ""))
18255 (use (match_operand:HI 3 "memory_operand" ""))
18256 (clobber (match_operand:DI 4 "memory_operand" ""))
18257 (clobber (match_scratch 5 ""))]
18259 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18260 (use (match_dup 2))
18261 (use (match_dup 3))
18262 (clobber (match_dup 5))])]
18265 (define_insn "fist<mode>2_floor"
18266 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18267 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18268 UNSPEC_FIST_FLOOR))
18269 (use (match_operand:HI 2 "memory_operand" "m"))
18270 (use (match_operand:HI 3 "memory_operand" "m"))]
18271 "TARGET_USE_FANCY_MATH_387
18272 && flag_unsafe_math_optimizations"
18273 "* return output_fix_trunc (insn, operands, 0);"
18274 [(set_attr "type" "fistp")
18275 (set_attr "i387_cw" "floor")
18276 (set_attr "mode" "<MODE>")])
18278 (define_insn "fist<mode>2_floor_with_temp"
18279 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18280 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18281 UNSPEC_FIST_FLOOR))
18282 (use (match_operand:HI 2 "memory_operand" "m,m"))
18283 (use (match_operand:HI 3 "memory_operand" "m,m"))
18284 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18285 "TARGET_USE_FANCY_MATH_387
18286 && flag_unsafe_math_optimizations"
18288 [(set_attr "type" "fistp")
18289 (set_attr "i387_cw" "floor")
18290 (set_attr "mode" "<MODE>")])
18293 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18294 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18295 UNSPEC_FIST_FLOOR))
18296 (use (match_operand:HI 2 "memory_operand" ""))
18297 (use (match_operand:HI 3 "memory_operand" ""))
18298 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18300 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18301 UNSPEC_FIST_FLOOR))
18302 (use (match_dup 2))
18303 (use (match_dup 3))])
18304 (set (match_dup 0) (match_dup 4))]
18308 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18310 UNSPEC_FIST_FLOOR))
18311 (use (match_operand:HI 2 "memory_operand" ""))
18312 (use (match_operand:HI 3 "memory_operand" ""))
18313 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18315 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18316 UNSPEC_FIST_FLOOR))
18317 (use (match_dup 2))
18318 (use (match_dup 3))])]
18321 (define_expand "lfloorxf<mode>2"
18322 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18323 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18324 UNSPEC_FIST_FLOOR))
18325 (clobber (reg:CC FLAGS_REG))])]
18326 "TARGET_USE_FANCY_MATH_387
18327 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18328 && flag_unsafe_math_optimizations"
18331 (define_expand "lfloor<mode>di2"
18332 [(match_operand:DI 0 "nonimmediate_operand" "")
18333 (match_operand:MODEF 1 "register_operand" "")]
18334 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18335 && !flag_trapping_math"
18337 if (optimize_insn_for_size_p ())
18339 ix86_expand_lfloorceil (operand0, operand1, true);
18343 (define_expand "lfloor<mode>si2"
18344 [(match_operand:SI 0 "nonimmediate_operand" "")
18345 (match_operand:MODEF 1 "register_operand" "")]
18346 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18347 && !flag_trapping_math"
18349 if (optimize_insn_for_size_p () && TARGET_64BIT)
18351 ix86_expand_lfloorceil (operand0, operand1, true);
18355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18356 (define_insn_and_split "frndintxf2_ceil"
18357 [(set (match_operand:XF 0 "register_operand" "")
18358 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18359 UNSPEC_FRNDINT_CEIL))
18360 (clobber (reg:CC FLAGS_REG))]
18361 "TARGET_USE_FANCY_MATH_387
18362 && flag_unsafe_math_optimizations
18363 && !(reload_completed || reload_in_progress)"
18368 ix86_optimize_mode_switching[I387_CEIL] = 1;
18370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18373 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18374 operands[2], operands[3]));
18377 [(set_attr "type" "frndint")
18378 (set_attr "i387_cw" "ceil")
18379 (set_attr "mode" "XF")])
18381 (define_insn "frndintxf2_ceil_i387"
18382 [(set (match_operand:XF 0 "register_operand" "=f")
18383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18384 UNSPEC_FRNDINT_CEIL))
18385 (use (match_operand:HI 2 "memory_operand" "m"))
18386 (use (match_operand:HI 3 "memory_operand" "m"))]
18387 "TARGET_USE_FANCY_MATH_387
18388 && flag_unsafe_math_optimizations"
18389 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18390 [(set_attr "type" "frndint")
18391 (set_attr "i387_cw" "ceil")
18392 (set_attr "mode" "XF")])
18394 (define_expand "ceilxf2"
18395 [(use (match_operand:XF 0 "register_operand" ""))
18396 (use (match_operand:XF 1 "register_operand" ""))]
18397 "TARGET_USE_FANCY_MATH_387
18398 && flag_unsafe_math_optimizations"
18400 if (optimize_insn_for_size_p ())
18402 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18406 (define_expand "ceil<mode>2"
18407 [(use (match_operand:MODEF 0 "register_operand" ""))
18408 (use (match_operand:MODEF 1 "register_operand" ""))]
18409 "(TARGET_USE_FANCY_MATH_387
18410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18411 || TARGET_MIX_SSE_I387)
18412 && flag_unsafe_math_optimizations)
18413 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18414 && !flag_trapping_math)"
18416 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18417 && !flag_trapping_math
18418 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18421 emit_insn (gen_sse4_1_round<mode>2
18422 (operands[0], operands[1], GEN_INT (0x02)));
18423 else if (optimize_insn_for_size_p ())
18425 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18426 ix86_expand_floorceil (operand0, operand1, false);
18428 ix86_expand_floorceildf_32 (operand0, operand1, false);
18434 if (optimize_insn_for_size_p ())
18437 op0 = gen_reg_rtx (XFmode);
18438 op1 = gen_reg_rtx (XFmode);
18439 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18440 emit_insn (gen_frndintxf2_ceil (op0, op1));
18442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18447 (define_insn_and_split "*fist<mode>2_ceil_1"
18448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18449 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18451 (clobber (reg:CC FLAGS_REG))]
18452 "TARGET_USE_FANCY_MATH_387
18453 && flag_unsafe_math_optimizations
18454 && !(reload_completed || reload_in_progress)"
18459 ix86_optimize_mode_switching[I387_CEIL] = 1;
18461 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18462 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18463 if (memory_operand (operands[0], VOIDmode))
18464 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18465 operands[2], operands[3]));
18468 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18469 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18470 operands[2], operands[3],
18475 [(set_attr "type" "fistp")
18476 (set_attr "i387_cw" "ceil")
18477 (set_attr "mode" "<MODE>")])
18479 (define_insn "fistdi2_ceil"
18480 [(set (match_operand:DI 0 "memory_operand" "=m")
18481 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18483 (use (match_operand:HI 2 "memory_operand" "m"))
18484 (use (match_operand:HI 3 "memory_operand" "m"))
18485 (clobber (match_scratch:XF 4 "=&1f"))]
18486 "TARGET_USE_FANCY_MATH_387
18487 && flag_unsafe_math_optimizations"
18488 "* return output_fix_trunc (insn, operands, 0);"
18489 [(set_attr "type" "fistp")
18490 (set_attr "i387_cw" "ceil")
18491 (set_attr "mode" "DI")])
18493 (define_insn "fistdi2_ceil_with_temp"
18494 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18495 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18497 (use (match_operand:HI 2 "memory_operand" "m,m"))
18498 (use (match_operand:HI 3 "memory_operand" "m,m"))
18499 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18500 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18501 "TARGET_USE_FANCY_MATH_387
18502 && flag_unsafe_math_optimizations"
18504 [(set_attr "type" "fistp")
18505 (set_attr "i387_cw" "ceil")
18506 (set_attr "mode" "DI")])
18509 [(set (match_operand:DI 0 "register_operand" "")
18510 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18512 (use (match_operand:HI 2 "memory_operand" ""))
18513 (use (match_operand:HI 3 "memory_operand" ""))
18514 (clobber (match_operand:DI 4 "memory_operand" ""))
18515 (clobber (match_scratch 5 ""))]
18517 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18518 (use (match_dup 2))
18519 (use (match_dup 3))
18520 (clobber (match_dup 5))])
18521 (set (match_dup 0) (match_dup 4))]
18525 [(set (match_operand:DI 0 "memory_operand" "")
18526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18528 (use (match_operand:HI 2 "memory_operand" ""))
18529 (use (match_operand:HI 3 "memory_operand" ""))
18530 (clobber (match_operand:DI 4 "memory_operand" ""))
18531 (clobber (match_scratch 5 ""))]
18533 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18534 (use (match_dup 2))
18535 (use (match_dup 3))
18536 (clobber (match_dup 5))])]
18539 (define_insn "fist<mode>2_ceil"
18540 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18543 (use (match_operand:HI 2 "memory_operand" "m"))
18544 (use (match_operand:HI 3 "memory_operand" "m"))]
18545 "TARGET_USE_FANCY_MATH_387
18546 && flag_unsafe_math_optimizations"
18547 "* return output_fix_trunc (insn, operands, 0);"
18548 [(set_attr "type" "fistp")
18549 (set_attr "i387_cw" "ceil")
18550 (set_attr "mode" "<MODE>")])
18552 (define_insn "fist<mode>2_ceil_with_temp"
18553 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18556 (use (match_operand:HI 2 "memory_operand" "m,m"))
18557 (use (match_operand:HI 3 "memory_operand" "m,m"))
18558 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18559 "TARGET_USE_FANCY_MATH_387
18560 && flag_unsafe_math_optimizations"
18562 [(set_attr "type" "fistp")
18563 (set_attr "i387_cw" "ceil")
18564 (set_attr "mode" "<MODE>")])
18567 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18568 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18570 (use (match_operand:HI 2 "memory_operand" ""))
18571 (use (match_operand:HI 3 "memory_operand" ""))
18572 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18574 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18576 (use (match_dup 2))
18577 (use (match_dup 3))])
18578 (set (match_dup 0) (match_dup 4))]
18582 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18583 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18585 (use (match_operand:HI 2 "memory_operand" ""))
18586 (use (match_operand:HI 3 "memory_operand" ""))
18587 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18589 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18591 (use (match_dup 2))
18592 (use (match_dup 3))])]
18595 (define_expand "lceilxf<mode>2"
18596 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18597 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18599 (clobber (reg:CC FLAGS_REG))])]
18600 "TARGET_USE_FANCY_MATH_387
18601 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18602 && flag_unsafe_math_optimizations"
18605 (define_expand "lceil<mode>di2"
18606 [(match_operand:DI 0 "nonimmediate_operand" "")
18607 (match_operand:MODEF 1 "register_operand" "")]
18608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18609 && !flag_trapping_math"
18611 ix86_expand_lfloorceil (operand0, operand1, false);
18615 (define_expand "lceil<mode>si2"
18616 [(match_operand:SI 0 "nonimmediate_operand" "")
18617 (match_operand:MODEF 1 "register_operand" "")]
18618 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18619 && !flag_trapping_math"
18621 ix86_expand_lfloorceil (operand0, operand1, false);
18625 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18626 (define_insn_and_split "frndintxf2_trunc"
18627 [(set (match_operand:XF 0 "register_operand" "")
18628 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18629 UNSPEC_FRNDINT_TRUNC))
18630 (clobber (reg:CC FLAGS_REG))]
18631 "TARGET_USE_FANCY_MATH_387
18632 && flag_unsafe_math_optimizations
18633 && !(reload_completed || reload_in_progress)"
18638 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18640 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18641 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18643 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18644 operands[2], operands[3]));
18647 [(set_attr "type" "frndint")
18648 (set_attr "i387_cw" "trunc")
18649 (set_attr "mode" "XF")])
18651 (define_insn "frndintxf2_trunc_i387"
18652 [(set (match_operand:XF 0 "register_operand" "=f")
18653 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18654 UNSPEC_FRNDINT_TRUNC))
18655 (use (match_operand:HI 2 "memory_operand" "m"))
18656 (use (match_operand:HI 3 "memory_operand" "m"))]
18657 "TARGET_USE_FANCY_MATH_387
18658 && flag_unsafe_math_optimizations"
18659 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18660 [(set_attr "type" "frndint")
18661 (set_attr "i387_cw" "trunc")
18662 (set_attr "mode" "XF")])
18664 (define_expand "btruncxf2"
18665 [(use (match_operand:XF 0 "register_operand" ""))
18666 (use (match_operand:XF 1 "register_operand" ""))]
18667 "TARGET_USE_FANCY_MATH_387
18668 && flag_unsafe_math_optimizations"
18670 if (optimize_insn_for_size_p ())
18672 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18676 (define_expand "btrunc<mode>2"
18677 [(use (match_operand:MODEF 0 "register_operand" ""))
18678 (use (match_operand:MODEF 1 "register_operand" ""))]
18679 "(TARGET_USE_FANCY_MATH_387
18680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18681 || TARGET_MIX_SSE_I387)
18682 && flag_unsafe_math_optimizations)
18683 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18684 && !flag_trapping_math)"
18686 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18687 && !flag_trapping_math
18688 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18691 emit_insn (gen_sse4_1_round<mode>2
18692 (operands[0], operands[1], GEN_INT (0x03)));
18693 else if (optimize_insn_for_size_p ())
18695 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18696 ix86_expand_trunc (operand0, operand1);
18698 ix86_expand_truncdf_32 (operand0, operand1);
18704 if (optimize_insn_for_size_p ())
18707 op0 = gen_reg_rtx (XFmode);
18708 op1 = gen_reg_rtx (XFmode);
18709 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18710 emit_insn (gen_frndintxf2_trunc (op0, op1));
18712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18717 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18718 (define_insn_and_split "frndintxf2_mask_pm"
18719 [(set (match_operand:XF 0 "register_operand" "")
18720 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18721 UNSPEC_FRNDINT_MASK_PM))
18722 (clobber (reg:CC FLAGS_REG))]
18723 "TARGET_USE_FANCY_MATH_387
18724 && flag_unsafe_math_optimizations
18725 && !(reload_completed || reload_in_progress)"
18730 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18732 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18733 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18735 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18736 operands[2], operands[3]));
18739 [(set_attr "type" "frndint")
18740 (set_attr "i387_cw" "mask_pm")
18741 (set_attr "mode" "XF")])
18743 (define_insn "frndintxf2_mask_pm_i387"
18744 [(set (match_operand:XF 0 "register_operand" "=f")
18745 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18746 UNSPEC_FRNDINT_MASK_PM))
18747 (use (match_operand:HI 2 "memory_operand" "m"))
18748 (use (match_operand:HI 3 "memory_operand" "m"))]
18749 "TARGET_USE_FANCY_MATH_387
18750 && flag_unsafe_math_optimizations"
18751 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18752 [(set_attr "type" "frndint")
18753 (set_attr "i387_cw" "mask_pm")
18754 (set_attr "mode" "XF")])
18756 (define_expand "nearbyintxf2"
18757 [(use (match_operand:XF 0 "register_operand" ""))
18758 (use (match_operand:XF 1 "register_operand" ""))]
18759 "TARGET_USE_FANCY_MATH_387
18760 && flag_unsafe_math_optimizations"
18762 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18767 (define_expand "nearbyint<mode>2"
18768 [(use (match_operand:MODEF 0 "register_operand" ""))
18769 (use (match_operand:MODEF 1 "register_operand" ""))]
18770 "TARGET_USE_FANCY_MATH_387
18771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18772 || TARGET_MIX_SSE_I387)
18773 && flag_unsafe_math_optimizations"
18775 rtx op0 = gen_reg_rtx (XFmode);
18776 rtx op1 = gen_reg_rtx (XFmode);
18778 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18779 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18785 (define_insn "fxam<mode>2_i387"
18786 [(set (match_operand:HI 0 "register_operand" "=a")
18788 [(match_operand:X87MODEF 1 "register_operand" "f")]
18790 "TARGET_USE_FANCY_MATH_387"
18791 "fxam\n\tfnstsw\t%0"
18792 [(set_attr "type" "multi")
18793 (set_attr "unit" "i387")
18794 (set_attr "mode" "<MODE>")])
18796 (define_expand "isinf<mode>2"
18797 [(use (match_operand:SI 0 "register_operand" ""))
18798 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18799 "TARGET_USE_FANCY_MATH_387
18800 && TARGET_C99_FUNCTIONS
18801 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18803 rtx mask = GEN_INT (0x45);
18804 rtx val = GEN_INT (0x05);
18808 rtx scratch = gen_reg_rtx (HImode);
18809 rtx res = gen_reg_rtx (QImode);
18811 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18812 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18813 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18814 cond = gen_rtx_fmt_ee (EQ, QImode,
18815 gen_rtx_REG (CCmode, FLAGS_REG),
18817 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18818 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18822 (define_expand "signbit<mode>2"
18823 [(use (match_operand:SI 0 "register_operand" ""))
18824 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18825 "TARGET_USE_FANCY_MATH_387
18826 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18828 rtx mask = GEN_INT (0x0200);
18830 rtx scratch = gen_reg_rtx (HImode);
18832 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18833 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18837 ;; Block operation instructions
18840 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18843 [(set_attr "length" "1")
18844 (set_attr "length_immediate" "0")
18845 (set_attr "modrm" "0")])
18847 (define_expand "movmemsi"
18848 [(use (match_operand:BLK 0 "memory_operand" ""))
18849 (use (match_operand:BLK 1 "memory_operand" ""))
18850 (use (match_operand:SI 2 "nonmemory_operand" ""))
18851 (use (match_operand:SI 3 "const_int_operand" ""))
18852 (use (match_operand:SI 4 "const_int_operand" ""))
18853 (use (match_operand:SI 5 "const_int_operand" ""))]
18856 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18857 operands[4], operands[5]))
18863 (define_expand "movmemdi"
18864 [(use (match_operand:BLK 0 "memory_operand" ""))
18865 (use (match_operand:BLK 1 "memory_operand" ""))
18866 (use (match_operand:DI 2 "nonmemory_operand" ""))
18867 (use (match_operand:DI 3 "const_int_operand" ""))
18868 (use (match_operand:SI 4 "const_int_operand" ""))
18869 (use (match_operand:SI 5 "const_int_operand" ""))]
18872 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18873 operands[4], operands[5]))
18879 ;; Most CPUs don't like single string operations
18880 ;; Handle this case here to simplify previous expander.
18882 (define_expand "strmov"
18883 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18884 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18885 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18886 (clobber (reg:CC FLAGS_REG))])
18887 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18888 (clobber (reg:CC FLAGS_REG))])]
18891 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18893 /* If .md ever supports :P for Pmode, these can be directly
18894 in the pattern above. */
18895 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18896 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18898 /* Can't use this if the user has appropriated esi or edi. */
18899 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18900 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18902 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18903 operands[2], operands[3],
18904 operands[5], operands[6]));
18908 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18911 (define_expand "strmov_singleop"
18912 [(parallel [(set (match_operand 1 "memory_operand" "")
18913 (match_operand 3 "memory_operand" ""))
18914 (set (match_operand 0 "register_operand" "")
18915 (match_operand 4 "" ""))
18916 (set (match_operand 2 "register_operand" "")
18917 (match_operand 5 "" ""))])]
18919 "ix86_current_function_needs_cld = 1;")
18921 (define_insn "*strmovdi_rex_1"
18922 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18923 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18924 (set (match_operand:DI 0 "register_operand" "=D")
18925 (plus:DI (match_dup 2)
18927 (set (match_operand:DI 1 "register_operand" "=S")
18928 (plus:DI (match_dup 3)
18932 [(set_attr "type" "str")
18933 (set_attr "mode" "DI")
18934 (set_attr "memory" "both")])
18936 (define_insn "*strmovsi_1"
18937 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18938 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18939 (set (match_operand:SI 0 "register_operand" "=D")
18940 (plus:SI (match_dup 2)
18942 (set (match_operand:SI 1 "register_operand" "=S")
18943 (plus:SI (match_dup 3)
18947 [(set_attr "type" "str")
18948 (set_attr "mode" "SI")
18949 (set_attr "memory" "both")])
18951 (define_insn "*strmovsi_rex_1"
18952 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18953 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18954 (set (match_operand:DI 0 "register_operand" "=D")
18955 (plus:DI (match_dup 2)
18957 (set (match_operand:DI 1 "register_operand" "=S")
18958 (plus:DI (match_dup 3)
18962 [(set_attr "type" "str")
18963 (set_attr "mode" "SI")
18964 (set_attr "memory" "both")])
18966 (define_insn "*strmovhi_1"
18967 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18968 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18969 (set (match_operand:SI 0 "register_operand" "=D")
18970 (plus:SI (match_dup 2)
18972 (set (match_operand:SI 1 "register_operand" "=S")
18973 (plus:SI (match_dup 3)
18977 [(set_attr "type" "str")
18978 (set_attr "memory" "both")
18979 (set_attr "mode" "HI")])
18981 (define_insn "*strmovhi_rex_1"
18982 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18983 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18984 (set (match_operand:DI 0 "register_operand" "=D")
18985 (plus:DI (match_dup 2)
18987 (set (match_operand:DI 1 "register_operand" "=S")
18988 (plus:DI (match_dup 3)
18992 [(set_attr "type" "str")
18993 (set_attr "memory" "both")
18994 (set_attr "mode" "HI")])
18996 (define_insn "*strmovqi_1"
18997 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18998 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18999 (set (match_operand:SI 0 "register_operand" "=D")
19000 (plus:SI (match_dup 2)
19002 (set (match_operand:SI 1 "register_operand" "=S")
19003 (plus:SI (match_dup 3)
19007 [(set_attr "type" "str")
19008 (set_attr "memory" "both")
19009 (set_attr "mode" "QI")])
19011 (define_insn "*strmovqi_rex_1"
19012 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19013 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19014 (set (match_operand:DI 0 "register_operand" "=D")
19015 (plus:DI (match_dup 2)
19017 (set (match_operand:DI 1 "register_operand" "=S")
19018 (plus:DI (match_dup 3)
19022 [(set_attr "type" "str")
19023 (set_attr "memory" "both")
19024 (set_attr "mode" "QI")])
19026 (define_expand "rep_mov"
19027 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19028 (set (match_operand 0 "register_operand" "")
19029 (match_operand 5 "" ""))
19030 (set (match_operand 2 "register_operand" "")
19031 (match_operand 6 "" ""))
19032 (set (match_operand 1 "memory_operand" "")
19033 (match_operand 3 "memory_operand" ""))
19034 (use (match_dup 4))])]
19036 "ix86_current_function_needs_cld = 1;")
19038 (define_insn "*rep_movdi_rex64"
19039 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19040 (set (match_operand:DI 0 "register_operand" "=D")
19041 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19043 (match_operand:DI 3 "register_operand" "0")))
19044 (set (match_operand:DI 1 "register_operand" "=S")
19045 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19046 (match_operand:DI 4 "register_operand" "1")))
19047 (set (mem:BLK (match_dup 3))
19048 (mem:BLK (match_dup 4)))
19049 (use (match_dup 5))]
19052 [(set_attr "type" "str")
19053 (set_attr "prefix_rep" "1")
19054 (set_attr "memory" "both")
19055 (set_attr "mode" "DI")])
19057 (define_insn "*rep_movsi"
19058 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19059 (set (match_operand:SI 0 "register_operand" "=D")
19060 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19062 (match_operand:SI 3 "register_operand" "0")))
19063 (set (match_operand:SI 1 "register_operand" "=S")
19064 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19065 (match_operand:SI 4 "register_operand" "1")))
19066 (set (mem:BLK (match_dup 3))
19067 (mem:BLK (match_dup 4)))
19068 (use (match_dup 5))]
19071 [(set_attr "type" "str")
19072 (set_attr "prefix_rep" "1")
19073 (set_attr "memory" "both")
19074 (set_attr "mode" "SI")])
19076 (define_insn "*rep_movsi_rex64"
19077 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19078 (set (match_operand:DI 0 "register_operand" "=D")
19079 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19081 (match_operand:DI 3 "register_operand" "0")))
19082 (set (match_operand:DI 1 "register_operand" "=S")
19083 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19084 (match_operand:DI 4 "register_operand" "1")))
19085 (set (mem:BLK (match_dup 3))
19086 (mem:BLK (match_dup 4)))
19087 (use (match_dup 5))]
19090 [(set_attr "type" "str")
19091 (set_attr "prefix_rep" "1")
19092 (set_attr "memory" "both")
19093 (set_attr "mode" "SI")])
19095 (define_insn "*rep_movqi"
19096 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19097 (set (match_operand:SI 0 "register_operand" "=D")
19098 (plus:SI (match_operand:SI 3 "register_operand" "0")
19099 (match_operand:SI 5 "register_operand" "2")))
19100 (set (match_operand:SI 1 "register_operand" "=S")
19101 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19102 (set (mem:BLK (match_dup 3))
19103 (mem:BLK (match_dup 4)))
19104 (use (match_dup 5))]
19107 [(set_attr "type" "str")
19108 (set_attr "prefix_rep" "1")
19109 (set_attr "memory" "both")
19110 (set_attr "mode" "SI")])
19112 (define_insn "*rep_movqi_rex64"
19113 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19114 (set (match_operand:DI 0 "register_operand" "=D")
19115 (plus:DI (match_operand:DI 3 "register_operand" "0")
19116 (match_operand:DI 5 "register_operand" "2")))
19117 (set (match_operand:DI 1 "register_operand" "=S")
19118 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19119 (set (mem:BLK (match_dup 3))
19120 (mem:BLK (match_dup 4)))
19121 (use (match_dup 5))]
19124 [(set_attr "type" "str")
19125 (set_attr "prefix_rep" "1")
19126 (set_attr "memory" "both")
19127 (set_attr "mode" "SI")])
19129 (define_expand "setmemsi"
19130 [(use (match_operand:BLK 0 "memory_operand" ""))
19131 (use (match_operand:SI 1 "nonmemory_operand" ""))
19132 (use (match_operand 2 "const_int_operand" ""))
19133 (use (match_operand 3 "const_int_operand" ""))
19134 (use (match_operand:SI 4 "const_int_operand" ""))
19135 (use (match_operand:SI 5 "const_int_operand" ""))]
19138 if (ix86_expand_setmem (operands[0], operands[1],
19139 operands[2], operands[3],
19140 operands[4], operands[5]))
19146 (define_expand "setmemdi"
19147 [(use (match_operand:BLK 0 "memory_operand" ""))
19148 (use (match_operand:DI 1 "nonmemory_operand" ""))
19149 (use (match_operand 2 "const_int_operand" ""))
19150 (use (match_operand 3 "const_int_operand" ""))
19151 (use (match_operand 4 "const_int_operand" ""))
19152 (use (match_operand 5 "const_int_operand" ""))]
19155 if (ix86_expand_setmem (operands[0], operands[1],
19156 operands[2], operands[3],
19157 operands[4], operands[5]))
19163 ;; Most CPUs don't like single string operations
19164 ;; Handle this case here to simplify previous expander.
19166 (define_expand "strset"
19167 [(set (match_operand 1 "memory_operand" "")
19168 (match_operand 2 "register_operand" ""))
19169 (parallel [(set (match_operand 0 "register_operand" "")
19171 (clobber (reg:CC FLAGS_REG))])]
19174 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19175 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19177 /* If .md ever supports :P for Pmode, this can be directly
19178 in the pattern above. */
19179 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19180 GEN_INT (GET_MODE_SIZE (GET_MODE
19182 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19184 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19190 (define_expand "strset_singleop"
19191 [(parallel [(set (match_operand 1 "memory_operand" "")
19192 (match_operand 2 "register_operand" ""))
19193 (set (match_operand 0 "register_operand" "")
19194 (match_operand 3 "" ""))])]
19196 "ix86_current_function_needs_cld = 1;")
19198 (define_insn "*strsetdi_rex_1"
19199 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19200 (match_operand:DI 2 "register_operand" "a"))
19201 (set (match_operand:DI 0 "register_operand" "=D")
19202 (plus:DI (match_dup 1)
19206 [(set_attr "type" "str")
19207 (set_attr "memory" "store")
19208 (set_attr "mode" "DI")])
19210 (define_insn "*strsetsi_1"
19211 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19212 (match_operand:SI 2 "register_operand" "a"))
19213 (set (match_operand:SI 0 "register_operand" "=D")
19214 (plus:SI (match_dup 1)
19218 [(set_attr "type" "str")
19219 (set_attr "memory" "store")
19220 (set_attr "mode" "SI")])
19222 (define_insn "*strsetsi_rex_1"
19223 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19224 (match_operand:SI 2 "register_operand" "a"))
19225 (set (match_operand:DI 0 "register_operand" "=D")
19226 (plus:DI (match_dup 1)
19230 [(set_attr "type" "str")
19231 (set_attr "memory" "store")
19232 (set_attr "mode" "SI")])
19234 (define_insn "*strsethi_1"
19235 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19236 (match_operand:HI 2 "register_operand" "a"))
19237 (set (match_operand:SI 0 "register_operand" "=D")
19238 (plus:SI (match_dup 1)
19242 [(set_attr "type" "str")
19243 (set_attr "memory" "store")
19244 (set_attr "mode" "HI")])
19246 (define_insn "*strsethi_rex_1"
19247 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19248 (match_operand:HI 2 "register_operand" "a"))
19249 (set (match_operand:DI 0 "register_operand" "=D")
19250 (plus:DI (match_dup 1)
19254 [(set_attr "type" "str")
19255 (set_attr "memory" "store")
19256 (set_attr "mode" "HI")])
19258 (define_insn "*strsetqi_1"
19259 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19260 (match_operand:QI 2 "register_operand" "a"))
19261 (set (match_operand:SI 0 "register_operand" "=D")
19262 (plus:SI (match_dup 1)
19266 [(set_attr "type" "str")
19267 (set_attr "memory" "store")
19268 (set_attr "mode" "QI")])
19270 (define_insn "*strsetqi_rex_1"
19271 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19272 (match_operand:QI 2 "register_operand" "a"))
19273 (set (match_operand:DI 0 "register_operand" "=D")
19274 (plus:DI (match_dup 1)
19278 [(set_attr "type" "str")
19279 (set_attr "memory" "store")
19280 (set_attr "mode" "QI")])
19282 (define_expand "rep_stos"
19283 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19284 (set (match_operand 0 "register_operand" "")
19285 (match_operand 4 "" ""))
19286 (set (match_operand 2 "memory_operand" "") (const_int 0))
19287 (use (match_operand 3 "register_operand" ""))
19288 (use (match_dup 1))])]
19290 "ix86_current_function_needs_cld = 1;")
19292 (define_insn "*rep_stosdi_rex64"
19293 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19294 (set (match_operand:DI 0 "register_operand" "=D")
19295 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19297 (match_operand:DI 3 "register_operand" "0")))
19298 (set (mem:BLK (match_dup 3))
19300 (use (match_operand:DI 2 "register_operand" "a"))
19301 (use (match_dup 4))]
19304 [(set_attr "type" "str")
19305 (set_attr "prefix_rep" "1")
19306 (set_attr "memory" "store")
19307 (set_attr "mode" "DI")])
19309 (define_insn "*rep_stossi"
19310 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19311 (set (match_operand:SI 0 "register_operand" "=D")
19312 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19314 (match_operand:SI 3 "register_operand" "0")))
19315 (set (mem:BLK (match_dup 3))
19317 (use (match_operand:SI 2 "register_operand" "a"))
19318 (use (match_dup 4))]
19321 [(set_attr "type" "str")
19322 (set_attr "prefix_rep" "1")
19323 (set_attr "memory" "store")
19324 (set_attr "mode" "SI")])
19326 (define_insn "*rep_stossi_rex64"
19327 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19328 (set (match_operand:DI 0 "register_operand" "=D")
19329 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19331 (match_operand:DI 3 "register_operand" "0")))
19332 (set (mem:BLK (match_dup 3))
19334 (use (match_operand:SI 2 "register_operand" "a"))
19335 (use (match_dup 4))]
19338 [(set_attr "type" "str")
19339 (set_attr "prefix_rep" "1")
19340 (set_attr "memory" "store")
19341 (set_attr "mode" "SI")])
19343 (define_insn "*rep_stosqi"
19344 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19345 (set (match_operand:SI 0 "register_operand" "=D")
19346 (plus:SI (match_operand:SI 3 "register_operand" "0")
19347 (match_operand:SI 4 "register_operand" "1")))
19348 (set (mem:BLK (match_dup 3))
19350 (use (match_operand:QI 2 "register_operand" "a"))
19351 (use (match_dup 4))]
19354 [(set_attr "type" "str")
19355 (set_attr "prefix_rep" "1")
19356 (set_attr "memory" "store")
19357 (set_attr "mode" "QI")])
19359 (define_insn "*rep_stosqi_rex64"
19360 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19361 (set (match_operand:DI 0 "register_operand" "=D")
19362 (plus:DI (match_operand:DI 3 "register_operand" "0")
19363 (match_operand:DI 4 "register_operand" "1")))
19364 (set (mem:BLK (match_dup 3))
19366 (use (match_operand:QI 2 "register_operand" "a"))
19367 (use (match_dup 4))]
19370 [(set_attr "type" "str")
19371 (set_attr "prefix_rep" "1")
19372 (set_attr "memory" "store")
19373 (set_attr "mode" "QI")])
19375 (define_expand "cmpstrnsi"
19376 [(set (match_operand:SI 0 "register_operand" "")
19377 (compare:SI (match_operand:BLK 1 "general_operand" "")
19378 (match_operand:BLK 2 "general_operand" "")))
19379 (use (match_operand 3 "general_operand" ""))
19380 (use (match_operand 4 "immediate_operand" ""))]
19383 rtx addr1, addr2, out, outlow, count, countreg, align;
19385 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19388 /* Can't use this if the user has appropriated esi or edi. */
19389 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19394 out = gen_reg_rtx (SImode);
19396 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19397 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19398 if (addr1 != XEXP (operands[1], 0))
19399 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19400 if (addr2 != XEXP (operands[2], 0))
19401 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19403 count = operands[3];
19404 countreg = ix86_zero_extend_to_Pmode (count);
19406 /* %%% Iff we are testing strict equality, we can use known alignment
19407 to good advantage. This may be possible with combine, particularly
19408 once cc0 is dead. */
19409 align = operands[4];
19411 if (CONST_INT_P (count))
19413 if (INTVAL (count) == 0)
19415 emit_move_insn (operands[0], const0_rtx);
19418 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19419 operands[1], operands[2]));
19424 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19426 emit_insn (gen_cmpsi_1 (countreg, countreg));
19427 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19428 operands[1], operands[2]));
19431 outlow = gen_lowpart (QImode, out);
19432 emit_insn (gen_cmpintqi (outlow));
19433 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19435 if (operands[0] != out)
19436 emit_move_insn (operands[0], out);
19441 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19443 (define_expand "cmpintqi"
19444 [(set (match_dup 1)
19445 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19447 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19448 (parallel [(set (match_operand:QI 0 "register_operand" "")
19449 (minus:QI (match_dup 1)
19451 (clobber (reg:CC FLAGS_REG))])]
19453 "operands[1] = gen_reg_rtx (QImode);
19454 operands[2] = gen_reg_rtx (QImode);")
19456 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19457 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19459 (define_expand "cmpstrnqi_nz_1"
19460 [(parallel [(set (reg:CC FLAGS_REG)
19461 (compare:CC (match_operand 4 "memory_operand" "")
19462 (match_operand 5 "memory_operand" "")))
19463 (use (match_operand 2 "register_operand" ""))
19464 (use (match_operand:SI 3 "immediate_operand" ""))
19465 (clobber (match_operand 0 "register_operand" ""))
19466 (clobber (match_operand 1 "register_operand" ""))
19467 (clobber (match_dup 2))])]
19469 "ix86_current_function_needs_cld = 1;")
19471 (define_insn "*cmpstrnqi_nz_1"
19472 [(set (reg:CC FLAGS_REG)
19473 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19474 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19475 (use (match_operand:SI 6 "register_operand" "2"))
19476 (use (match_operand:SI 3 "immediate_operand" "i"))
19477 (clobber (match_operand:SI 0 "register_operand" "=S"))
19478 (clobber (match_operand:SI 1 "register_operand" "=D"))
19479 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19482 [(set_attr "type" "str")
19483 (set_attr "mode" "QI")
19484 (set_attr "prefix_rep" "1")])
19486 (define_insn "*cmpstrnqi_nz_rex_1"
19487 [(set (reg:CC FLAGS_REG)
19488 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19489 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19490 (use (match_operand:DI 6 "register_operand" "2"))
19491 (use (match_operand:SI 3 "immediate_operand" "i"))
19492 (clobber (match_operand:DI 0 "register_operand" "=S"))
19493 (clobber (match_operand:DI 1 "register_operand" "=D"))
19494 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19497 [(set_attr "type" "str")
19498 (set_attr "mode" "QI")
19499 (set_attr "prefix_rep" "1")])
19501 ;; The same, but the count is not known to not be zero.
19503 (define_expand "cmpstrnqi_1"
19504 [(parallel [(set (reg:CC FLAGS_REG)
19505 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19507 (compare:CC (match_operand 4 "memory_operand" "")
19508 (match_operand 5 "memory_operand" ""))
19510 (use (match_operand:SI 3 "immediate_operand" ""))
19511 (use (reg:CC FLAGS_REG))
19512 (clobber (match_operand 0 "register_operand" ""))
19513 (clobber (match_operand 1 "register_operand" ""))
19514 (clobber (match_dup 2))])]
19516 "ix86_current_function_needs_cld = 1;")
19518 (define_insn "*cmpstrnqi_1"
19519 [(set (reg:CC FLAGS_REG)
19520 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19522 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19523 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19525 (use (match_operand:SI 3 "immediate_operand" "i"))
19526 (use (reg:CC FLAGS_REG))
19527 (clobber (match_operand:SI 0 "register_operand" "=S"))
19528 (clobber (match_operand:SI 1 "register_operand" "=D"))
19529 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19532 [(set_attr "type" "str")
19533 (set_attr "mode" "QI")
19534 (set_attr "prefix_rep" "1")])
19536 (define_insn "*cmpstrnqi_rex_1"
19537 [(set (reg:CC FLAGS_REG)
19538 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19540 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19541 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19543 (use (match_operand:SI 3 "immediate_operand" "i"))
19544 (use (reg:CC FLAGS_REG))
19545 (clobber (match_operand:DI 0 "register_operand" "=S"))
19546 (clobber (match_operand:DI 1 "register_operand" "=D"))
19547 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19550 [(set_attr "type" "str")
19551 (set_attr "mode" "QI")
19552 (set_attr "prefix_rep" "1")])
19554 (define_expand "strlensi"
19555 [(set (match_operand:SI 0 "register_operand" "")
19556 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19557 (match_operand:QI 2 "immediate_operand" "")
19558 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19567 (define_expand "strlendi"
19568 [(set (match_operand:DI 0 "register_operand" "")
19569 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19570 (match_operand:QI 2 "immediate_operand" "")
19571 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19574 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19580 (define_expand "strlenqi_1"
19581 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19582 (clobber (match_operand 1 "register_operand" ""))
19583 (clobber (reg:CC FLAGS_REG))])]
19585 "ix86_current_function_needs_cld = 1;")
19587 (define_insn "*strlenqi_1"
19588 [(set (match_operand:SI 0 "register_operand" "=&c")
19589 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19590 (match_operand:QI 2 "register_operand" "a")
19591 (match_operand:SI 3 "immediate_operand" "i")
19592 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19593 (clobber (match_operand:SI 1 "register_operand" "=D"))
19594 (clobber (reg:CC FLAGS_REG))]
19597 [(set_attr "type" "str")
19598 (set_attr "mode" "QI")
19599 (set_attr "prefix_rep" "1")])
19601 (define_insn "*strlenqi_rex_1"
19602 [(set (match_operand:DI 0 "register_operand" "=&c")
19603 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19604 (match_operand:QI 2 "register_operand" "a")
19605 (match_operand:DI 3 "immediate_operand" "i")
19606 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19607 (clobber (match_operand:DI 1 "register_operand" "=D"))
19608 (clobber (reg:CC FLAGS_REG))]
19611 [(set_attr "type" "str")
19612 (set_attr "mode" "QI")
19613 (set_attr "prefix_rep" "1")])
19615 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19616 ;; handled in combine, but it is not currently up to the task.
19617 ;; When used for their truth value, the cmpstrn* expanders generate
19626 ;; The intermediate three instructions are unnecessary.
19628 ;; This one handles cmpstrn*_nz_1...
19631 (set (reg:CC FLAGS_REG)
19632 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19633 (mem:BLK (match_operand 5 "register_operand" ""))))
19634 (use (match_operand 6 "register_operand" ""))
19635 (use (match_operand:SI 3 "immediate_operand" ""))
19636 (clobber (match_operand 0 "register_operand" ""))
19637 (clobber (match_operand 1 "register_operand" ""))
19638 (clobber (match_operand 2 "register_operand" ""))])
19639 (set (match_operand:QI 7 "register_operand" "")
19640 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19641 (set (match_operand:QI 8 "register_operand" "")
19642 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19643 (set (reg FLAGS_REG)
19644 (compare (match_dup 7) (match_dup 8)))
19646 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19648 (set (reg:CC FLAGS_REG)
19649 (compare:CC (mem:BLK (match_dup 4))
19650 (mem:BLK (match_dup 5))))
19651 (use (match_dup 6))
19652 (use (match_dup 3))
19653 (clobber (match_dup 0))
19654 (clobber (match_dup 1))
19655 (clobber (match_dup 2))])]
19658 ;; ...and this one handles cmpstrn*_1.
19661 (set (reg:CC FLAGS_REG)
19662 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19664 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19665 (mem:BLK (match_operand 5 "register_operand" "")))
19667 (use (match_operand:SI 3 "immediate_operand" ""))
19668 (use (reg:CC FLAGS_REG))
19669 (clobber (match_operand 0 "register_operand" ""))
19670 (clobber (match_operand 1 "register_operand" ""))
19671 (clobber (match_operand 2 "register_operand" ""))])
19672 (set (match_operand:QI 7 "register_operand" "")
19673 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19674 (set (match_operand:QI 8 "register_operand" "")
19675 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19676 (set (reg FLAGS_REG)
19677 (compare (match_dup 7) (match_dup 8)))
19679 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19681 (set (reg:CC FLAGS_REG)
19682 (if_then_else:CC (ne (match_dup 6)
19684 (compare:CC (mem:BLK (match_dup 4))
19685 (mem:BLK (match_dup 5)))
19687 (use (match_dup 3))
19688 (use (reg:CC FLAGS_REG))
19689 (clobber (match_dup 0))
19690 (clobber (match_dup 1))
19691 (clobber (match_dup 2))])]
19696 ;; Conditional move instructions.
19698 (define_expand "movdicc"
19699 [(set (match_operand:DI 0 "register_operand" "")
19700 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19701 (match_operand:DI 2 "general_operand" "")
19702 (match_operand:DI 3 "general_operand" "")))]
19704 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19706 (define_insn "x86_movdicc_0_m1_rex64"
19707 [(set (match_operand:DI 0 "register_operand" "=r")
19708 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19711 (clobber (reg:CC FLAGS_REG))]
19714 ; Since we don't have the proper number of operands for an alu insn,
19715 ; fill in all the blanks.
19716 [(set_attr "type" "alu")
19717 (set_attr "pent_pair" "pu")
19718 (set_attr "memory" "none")
19719 (set_attr "imm_disp" "false")
19720 (set_attr "mode" "DI")
19721 (set_attr "length_immediate" "0")])
19723 (define_insn "*x86_movdicc_0_m1_se"
19724 [(set (match_operand:DI 0 "register_operand" "=r")
19725 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19728 (clobber (reg:CC FLAGS_REG))]
19731 [(set_attr "type" "alu")
19732 (set_attr "pent_pair" "pu")
19733 (set_attr "memory" "none")
19734 (set_attr "imm_disp" "false")
19735 (set_attr "mode" "DI")
19736 (set_attr "length_immediate" "0")])
19738 (define_insn "*movdicc_c_rex64"
19739 [(set (match_operand:DI 0 "register_operand" "=r,r")
19740 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19741 [(reg FLAGS_REG) (const_int 0)])
19742 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19743 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19744 "TARGET_64BIT && TARGET_CMOVE
19745 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19747 cmov%O2%C1\t{%2, %0|%0, %2}
19748 cmov%O2%c1\t{%3, %0|%0, %3}"
19749 [(set_attr "type" "icmov")
19750 (set_attr "mode" "DI")])
19752 (define_expand "movsicc"
19753 [(set (match_operand:SI 0 "register_operand" "")
19754 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19755 (match_operand:SI 2 "general_operand" "")
19756 (match_operand:SI 3 "general_operand" "")))]
19758 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19760 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19761 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19762 ;; So just document what we're doing explicitly.
19764 (define_insn "x86_movsicc_0_m1"
19765 [(set (match_operand:SI 0 "register_operand" "=r")
19766 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19769 (clobber (reg:CC FLAGS_REG))]
19772 ; Since we don't have the proper number of operands for an alu insn,
19773 ; fill in all the blanks.
19774 [(set_attr "type" "alu")
19775 (set_attr "pent_pair" "pu")
19776 (set_attr "memory" "none")
19777 (set_attr "imm_disp" "false")
19778 (set_attr "mode" "SI")
19779 (set_attr "length_immediate" "0")])
19781 (define_insn "*x86_movsicc_0_m1_se"
19782 [(set (match_operand:SI 0 "register_operand" "=r")
19783 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19786 (clobber (reg:CC FLAGS_REG))]
19789 [(set_attr "type" "alu")
19790 (set_attr "pent_pair" "pu")
19791 (set_attr "memory" "none")
19792 (set_attr "imm_disp" "false")
19793 (set_attr "mode" "SI")
19794 (set_attr "length_immediate" "0")])
19796 (define_insn "*movsicc_noc"
19797 [(set (match_operand:SI 0 "register_operand" "=r,r")
19798 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19799 [(reg FLAGS_REG) (const_int 0)])
19800 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19801 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19803 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19805 cmov%O2%C1\t{%2, %0|%0, %2}
19806 cmov%O2%c1\t{%3, %0|%0, %3}"
19807 [(set_attr "type" "icmov")
19808 (set_attr "mode" "SI")])
19810 (define_expand "movhicc"
19811 [(set (match_operand:HI 0 "register_operand" "")
19812 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19813 (match_operand:HI 2 "general_operand" "")
19814 (match_operand:HI 3 "general_operand" "")))]
19815 "TARGET_HIMODE_MATH"
19816 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19818 (define_insn "*movhicc_noc"
19819 [(set (match_operand:HI 0 "register_operand" "=r,r")
19820 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19821 [(reg FLAGS_REG) (const_int 0)])
19822 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19823 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19825 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19827 cmov%O2%C1\t{%2, %0|%0, %2}
19828 cmov%O2%c1\t{%3, %0|%0, %3}"
19829 [(set_attr "type" "icmov")
19830 (set_attr "mode" "HI")])
19832 (define_expand "movqicc"
19833 [(set (match_operand:QI 0 "register_operand" "")
19834 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19835 (match_operand:QI 2 "general_operand" "")
19836 (match_operand:QI 3 "general_operand" "")))]
19837 "TARGET_QIMODE_MATH"
19838 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19840 (define_insn_and_split "*movqicc_noc"
19841 [(set (match_operand:QI 0 "register_operand" "=r,r")
19842 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19843 [(match_operand 4 "flags_reg_operand" "")
19845 (match_operand:QI 2 "register_operand" "r,0")
19846 (match_operand:QI 3 "register_operand" "0,r")))]
19847 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19849 "&& reload_completed"
19850 [(set (match_dup 0)
19851 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19854 "operands[0] = gen_lowpart (SImode, operands[0]);
19855 operands[2] = gen_lowpart (SImode, operands[2]);
19856 operands[3] = gen_lowpart (SImode, operands[3]);"
19857 [(set_attr "type" "icmov")
19858 (set_attr "mode" "SI")])
19860 (define_expand "mov<mode>cc"
19861 [(set (match_operand:X87MODEF 0 "register_operand" "")
19862 (if_then_else:X87MODEF
19863 (match_operand 1 "comparison_operator" "")
19864 (match_operand:X87MODEF 2 "register_operand" "")
19865 (match_operand:X87MODEF 3 "register_operand" "")))]
19866 "(TARGET_80387 && TARGET_CMOVE)
19867 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19868 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19870 (define_insn "*movsfcc_1_387"
19871 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19872 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19873 [(reg FLAGS_REG) (const_int 0)])
19874 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19875 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19876 "TARGET_80387 && TARGET_CMOVE
19877 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19879 fcmov%F1\t{%2, %0|%0, %2}
19880 fcmov%f1\t{%3, %0|%0, %3}
19881 cmov%O2%C1\t{%2, %0|%0, %2}
19882 cmov%O2%c1\t{%3, %0|%0, %3}"
19883 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19884 (set_attr "mode" "SF,SF,SI,SI")])
19886 (define_insn "*movdfcc_1"
19887 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19888 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19889 [(reg FLAGS_REG) (const_int 0)])
19890 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19891 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19892 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19893 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19895 fcmov%F1\t{%2, %0|%0, %2}
19896 fcmov%f1\t{%3, %0|%0, %3}
19899 [(set_attr "type" "fcmov,fcmov,multi,multi")
19900 (set_attr "mode" "DF")])
19902 (define_insn "*movdfcc_1_rex64"
19903 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19904 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19905 [(reg FLAGS_REG) (const_int 0)])
19906 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19907 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19908 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19909 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19911 fcmov%F1\t{%2, %0|%0, %2}
19912 fcmov%f1\t{%3, %0|%0, %3}
19913 cmov%O2%C1\t{%2, %0|%0, %2}
19914 cmov%O2%c1\t{%3, %0|%0, %3}"
19915 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19916 (set_attr "mode" "DF")])
19919 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19920 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19921 [(match_operand 4 "flags_reg_operand" "")
19923 (match_operand:DF 2 "nonimmediate_operand" "")
19924 (match_operand:DF 3 "nonimmediate_operand" "")))]
19925 "!TARGET_64BIT && reload_completed"
19926 [(set (match_dup 2)
19927 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19931 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19934 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19935 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19937 (define_insn "*movxfcc_1"
19938 [(set (match_operand:XF 0 "register_operand" "=f,f")
19939 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19940 [(reg FLAGS_REG) (const_int 0)])
19941 (match_operand:XF 2 "register_operand" "f,0")
19942 (match_operand:XF 3 "register_operand" "0,f")))]
19943 "TARGET_80387 && TARGET_CMOVE"
19945 fcmov%F1\t{%2, %0|%0, %2}
19946 fcmov%f1\t{%3, %0|%0, %3}"
19947 [(set_attr "type" "fcmov")
19948 (set_attr "mode" "XF")])
19950 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19951 ;; the scalar versions to have only XMM registers as operands.
19953 ;; SSE5 conditional move
19954 (define_insn "*sse5_pcmov_<mode>"
19955 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19956 (if_then_else:MODEF
19957 (match_operand:MODEF 1 "register_operand" "x,0")
19958 (match_operand:MODEF 2 "register_operand" "0,x")
19959 (match_operand:MODEF 3 "register_operand" "x,x")))]
19960 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19961 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19962 [(set_attr "type" "sse4arg")])
19964 ;; These versions of the min/max patterns are intentionally ignorant of
19965 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19966 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19967 ;; are undefined in this condition, we're certain this is correct.
19969 (define_insn "*avx_<code><mode>3"
19970 [(set (match_operand:MODEF 0 "register_operand" "=x")
19972 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19973 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19974 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19975 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19976 [(set_attr "type" "sseadd")
19977 (set_attr "prefix" "vex")
19978 (set_attr "mode" "<MODE>")])
19980 (define_insn "<code><mode>3"
19981 [(set (match_operand:MODEF 0 "register_operand" "=x")
19983 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19984 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19985 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19986 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19987 [(set_attr "type" "sseadd")
19988 (set_attr "mode" "<MODE>")])
19990 ;; These versions of the min/max patterns implement exactly the operations
19991 ;; min = (op1 < op2 ? op1 : op2)
19992 ;; max = (!(op1 < op2) ? op1 : op2)
19993 ;; Their operands are not commutative, and thus they may be used in the
19994 ;; presence of -0.0 and NaN.
19996 (define_insn "*avx_ieee_smin<mode>3"
19997 [(set (match_operand:MODEF 0 "register_operand" "=x")
19999 [(match_operand:MODEF 1 "register_operand" "x")
20000 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20002 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20003 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20004 [(set_attr "type" "sseadd")
20005 (set_attr "prefix" "vex")
20006 (set_attr "mode" "<MODE>")])
20008 (define_insn "*ieee_smin<mode>3"
20009 [(set (match_operand:MODEF 0 "register_operand" "=x")
20011 [(match_operand:MODEF 1 "register_operand" "0")
20012 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20015 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20016 [(set_attr "type" "sseadd")
20017 (set_attr "mode" "<MODE>")])
20019 (define_insn "*avx_ieee_smax<mode>3"
20020 [(set (match_operand:MODEF 0 "register_operand" "=x")
20022 [(match_operand:MODEF 1 "register_operand" "0")
20023 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20025 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20026 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20027 [(set_attr "type" "sseadd")
20028 (set_attr "prefix" "vex")
20029 (set_attr "mode" "<MODE>")])
20031 (define_insn "*ieee_smax<mode>3"
20032 [(set (match_operand:MODEF 0 "register_operand" "=x")
20034 [(match_operand:MODEF 1 "register_operand" "0")
20035 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20037 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20038 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20039 [(set_attr "type" "sseadd")
20040 (set_attr "mode" "<MODE>")])
20042 ;; Make two stack loads independent:
20044 ;; fld %st(0) -> fld bb
20045 ;; fmul bb fmul %st(1), %st
20047 ;; Actually we only match the last two instructions for simplicity.
20049 [(set (match_operand 0 "fp_register_operand" "")
20050 (match_operand 1 "fp_register_operand" ""))
20052 (match_operator 2 "binary_fp_operator"
20054 (match_operand 3 "memory_operand" "")]))]
20055 "REGNO (operands[0]) != REGNO (operands[1])"
20056 [(set (match_dup 0) (match_dup 3))
20057 (set (match_dup 0) (match_dup 4))]
20059 ;; The % modifier is not operational anymore in peephole2's, so we have to
20060 ;; swap the operands manually in the case of addition and multiplication.
20061 "if (COMMUTATIVE_ARITH_P (operands[2]))
20062 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20063 operands[0], operands[1]);
20065 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20066 operands[1], operands[0]);")
20068 ;; Conditional addition patterns
20069 (define_expand "add<mode>cc"
20070 [(match_operand:SWI 0 "register_operand" "")
20071 (match_operand 1 "comparison_operator" "")
20072 (match_operand:SWI 2 "register_operand" "")
20073 (match_operand:SWI 3 "const_int_operand" "")]
20075 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20078 ;; Misc patterns (?)
20080 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20081 ;; Otherwise there will be nothing to keep
20083 ;; [(set (reg ebp) (reg esp))]
20084 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20085 ;; (clobber (eflags)]
20086 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20088 ;; in proper program order.
20089 (define_insn "pro_epilogue_adjust_stack_1"
20090 [(set (match_operand:SI 0 "register_operand" "=r,r")
20091 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20092 (match_operand:SI 2 "immediate_operand" "i,i")))
20093 (clobber (reg:CC FLAGS_REG))
20094 (clobber (mem:BLK (scratch)))]
20097 switch (get_attr_type (insn))
20100 return "mov{l}\t{%1, %0|%0, %1}";
20103 if (CONST_INT_P (operands[2])
20104 && (INTVAL (operands[2]) == 128
20105 || (INTVAL (operands[2]) < 0
20106 && INTVAL (operands[2]) != -128)))
20108 operands[2] = GEN_INT (-INTVAL (operands[2]));
20109 return "sub{l}\t{%2, %0|%0, %2}";
20111 return "add{l}\t{%2, %0|%0, %2}";
20114 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20115 return "lea{l}\t{%a2, %0|%0, %a2}";
20118 gcc_unreachable ();
20121 [(set (attr "type")
20122 (cond [(eq_attr "alternative" "0")
20123 (const_string "alu")
20124 (match_operand:SI 2 "const0_operand" "")
20125 (const_string "imov")
20127 (const_string "lea")))
20128 (set_attr "mode" "SI")])
20130 (define_insn "pro_epilogue_adjust_stack_rex64"
20131 [(set (match_operand:DI 0 "register_operand" "=r,r")
20132 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20133 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20134 (clobber (reg:CC FLAGS_REG))
20135 (clobber (mem:BLK (scratch)))]
20138 switch (get_attr_type (insn))
20141 return "mov{q}\t{%1, %0|%0, %1}";
20144 if (CONST_INT_P (operands[2])
20145 /* Avoid overflows. */
20146 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20147 && (INTVAL (operands[2]) == 128
20148 || (INTVAL (operands[2]) < 0
20149 && INTVAL (operands[2]) != -128)))
20151 operands[2] = GEN_INT (-INTVAL (operands[2]));
20152 return "sub{q}\t{%2, %0|%0, %2}";
20154 return "add{q}\t{%2, %0|%0, %2}";
20157 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20158 return "lea{q}\t{%a2, %0|%0, %a2}";
20161 gcc_unreachable ();
20164 [(set (attr "type")
20165 (cond [(eq_attr "alternative" "0")
20166 (const_string "alu")
20167 (match_operand:DI 2 "const0_operand" "")
20168 (const_string "imov")
20170 (const_string "lea")))
20171 (set_attr "mode" "DI")])
20173 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20174 [(set (match_operand:DI 0 "register_operand" "=r,r")
20175 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20176 (match_operand:DI 3 "immediate_operand" "i,i")))
20177 (use (match_operand:DI 2 "register_operand" "r,r"))
20178 (clobber (reg:CC FLAGS_REG))
20179 (clobber (mem:BLK (scratch)))]
20182 switch (get_attr_type (insn))
20185 return "add{q}\t{%2, %0|%0, %2}";
20188 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20189 return "lea{q}\t{%a2, %0|%0, %a2}";
20192 gcc_unreachable ();
20195 [(set_attr "type" "alu,lea")
20196 (set_attr "mode" "DI")])
20198 (define_insn "allocate_stack_worker_32"
20199 [(set (match_operand:SI 0 "register_operand" "+a")
20200 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20201 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20202 (clobber (reg:CC FLAGS_REG))]
20203 "!TARGET_64BIT && TARGET_STACK_PROBE"
20205 [(set_attr "type" "multi")
20206 (set_attr "length" "5")])
20208 (define_insn "allocate_stack_worker_64"
20209 [(set (match_operand:DI 0 "register_operand" "+a")
20210 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20211 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20212 (clobber (reg:DI R10_REG))
20213 (clobber (reg:DI R11_REG))
20214 (clobber (reg:CC FLAGS_REG))]
20215 "TARGET_64BIT && TARGET_STACK_PROBE"
20217 [(set_attr "type" "multi")
20218 (set_attr "length" "5")])
20220 (define_expand "allocate_stack"
20221 [(match_operand 0 "register_operand" "")
20222 (match_operand 1 "general_operand" "")]
20223 "TARGET_STACK_PROBE"
20227 #ifndef CHECK_STACK_LIMIT
20228 #define CHECK_STACK_LIMIT 0
20231 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20232 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20234 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20235 stack_pointer_rtx, 0, OPTAB_DIRECT);
20236 if (x != stack_pointer_rtx)
20237 emit_move_insn (stack_pointer_rtx, x);
20241 x = copy_to_mode_reg (Pmode, operands[1]);
20243 x = gen_allocate_stack_worker_64 (x);
20245 x = gen_allocate_stack_worker_32 (x);
20249 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20253 (define_expand "builtin_setjmp_receiver"
20254 [(label_ref (match_operand 0 "" ""))]
20255 "!TARGET_64BIT && flag_pic"
20261 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20262 rtx label_rtx = gen_label_rtx ();
20263 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20264 xops[0] = xops[1] = picreg;
20265 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20266 ix86_expand_binary_operator (MINUS, SImode, xops);
20270 emit_insn (gen_set_got (pic_offset_table_rtx));
20274 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20277 [(set (match_operand 0 "register_operand" "")
20278 (match_operator 3 "promotable_binary_operator"
20279 [(match_operand 1 "register_operand" "")
20280 (match_operand 2 "aligned_operand" "")]))
20281 (clobber (reg:CC FLAGS_REG))]
20282 "! TARGET_PARTIAL_REG_STALL && reload_completed
20283 && ((GET_MODE (operands[0]) == HImode
20284 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20285 /* ??? next two lines just !satisfies_constraint_K (...) */
20286 || !CONST_INT_P (operands[2])
20287 || satisfies_constraint_K (operands[2])))
20288 || (GET_MODE (operands[0]) == QImode
20289 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20290 [(parallel [(set (match_dup 0)
20291 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20292 (clobber (reg:CC FLAGS_REG))])]
20293 "operands[0] = gen_lowpart (SImode, operands[0]);
20294 operands[1] = gen_lowpart (SImode, operands[1]);
20295 if (GET_CODE (operands[3]) != ASHIFT)
20296 operands[2] = gen_lowpart (SImode, operands[2]);
20297 PUT_MODE (operands[3], SImode);")
20299 ; Promote the QImode tests, as i386 has encoding of the AND
20300 ; instruction with 32-bit sign-extended immediate and thus the
20301 ; instruction size is unchanged, except in the %eax case for
20302 ; which it is increased by one byte, hence the ! optimize_size.
20304 [(set (match_operand 0 "flags_reg_operand" "")
20305 (match_operator 2 "compare_operator"
20306 [(and (match_operand 3 "aligned_operand" "")
20307 (match_operand 4 "const_int_operand" ""))
20309 (set (match_operand 1 "register_operand" "")
20310 (and (match_dup 3) (match_dup 4)))]
20311 "! TARGET_PARTIAL_REG_STALL && reload_completed
20312 && optimize_insn_for_speed_p ()
20313 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20314 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20315 /* Ensure that the operand will remain sign-extended immediate. */
20316 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20317 [(parallel [(set (match_dup 0)
20318 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20321 (and:SI (match_dup 3) (match_dup 4)))])]
20324 = gen_int_mode (INTVAL (operands[4])
20325 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20326 operands[1] = gen_lowpart (SImode, operands[1]);
20327 operands[3] = gen_lowpart (SImode, operands[3]);
20330 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20331 ; the TEST instruction with 32-bit sign-extended immediate and thus
20332 ; the instruction size would at least double, which is not what we
20333 ; want even with ! optimize_size.
20335 [(set (match_operand 0 "flags_reg_operand" "")
20336 (match_operator 1 "compare_operator"
20337 [(and (match_operand:HI 2 "aligned_operand" "")
20338 (match_operand:HI 3 "const_int_operand" ""))
20340 "! TARGET_PARTIAL_REG_STALL && reload_completed
20341 && ! TARGET_FAST_PREFIX
20342 && optimize_insn_for_speed_p ()
20343 /* Ensure that the operand will remain sign-extended immediate. */
20344 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20345 [(set (match_dup 0)
20346 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20350 = gen_int_mode (INTVAL (operands[3])
20351 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20352 operands[2] = gen_lowpart (SImode, operands[2]);
20356 [(set (match_operand 0 "register_operand" "")
20357 (neg (match_operand 1 "register_operand" "")))
20358 (clobber (reg:CC FLAGS_REG))]
20359 "! TARGET_PARTIAL_REG_STALL && reload_completed
20360 && (GET_MODE (operands[0]) == HImode
20361 || (GET_MODE (operands[0]) == QImode
20362 && (TARGET_PROMOTE_QImode
20363 || optimize_insn_for_size_p ())))"
20364 [(parallel [(set (match_dup 0)
20365 (neg:SI (match_dup 1)))
20366 (clobber (reg:CC FLAGS_REG))])]
20367 "operands[0] = gen_lowpart (SImode, operands[0]);
20368 operands[1] = gen_lowpart (SImode, operands[1]);")
20371 [(set (match_operand 0 "register_operand" "")
20372 (not (match_operand 1 "register_operand" "")))]
20373 "! TARGET_PARTIAL_REG_STALL && reload_completed
20374 && (GET_MODE (operands[0]) == HImode
20375 || (GET_MODE (operands[0]) == QImode
20376 && (TARGET_PROMOTE_QImode
20377 || optimize_insn_for_size_p ())))"
20378 [(set (match_dup 0)
20379 (not:SI (match_dup 1)))]
20380 "operands[0] = gen_lowpart (SImode, operands[0]);
20381 operands[1] = gen_lowpart (SImode, operands[1]);")
20384 [(set (match_operand 0 "register_operand" "")
20385 (if_then_else (match_operator 1 "comparison_operator"
20386 [(reg FLAGS_REG) (const_int 0)])
20387 (match_operand 2 "register_operand" "")
20388 (match_operand 3 "register_operand" "")))]
20389 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20390 && (GET_MODE (operands[0]) == HImode
20391 || (GET_MODE (operands[0]) == QImode
20392 && (TARGET_PROMOTE_QImode
20393 || optimize_insn_for_size_p ())))"
20394 [(set (match_dup 0)
20395 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20396 "operands[0] = gen_lowpart (SImode, operands[0]);
20397 operands[2] = gen_lowpart (SImode, operands[2]);
20398 operands[3] = gen_lowpart (SImode, operands[3]);")
20401 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20402 ;; transform a complex memory operation into two memory to register operations.
20404 ;; Don't push memory operands
20406 [(set (match_operand:SI 0 "push_operand" "")
20407 (match_operand:SI 1 "memory_operand" ""))
20408 (match_scratch:SI 2 "r")]
20409 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20410 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20411 [(set (match_dup 2) (match_dup 1))
20412 (set (match_dup 0) (match_dup 2))]
20416 [(set (match_operand:DI 0 "push_operand" "")
20417 (match_operand:DI 1 "memory_operand" ""))
20418 (match_scratch:DI 2 "r")]
20419 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20420 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20421 [(set (match_dup 2) (match_dup 1))
20422 (set (match_dup 0) (match_dup 2))]
20425 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20428 [(set (match_operand:SF 0 "push_operand" "")
20429 (match_operand:SF 1 "memory_operand" ""))
20430 (match_scratch:SF 2 "r")]
20431 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20432 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20433 [(set (match_dup 2) (match_dup 1))
20434 (set (match_dup 0) (match_dup 2))]
20438 [(set (match_operand:HI 0 "push_operand" "")
20439 (match_operand:HI 1 "memory_operand" ""))
20440 (match_scratch:HI 2 "r")]
20441 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20442 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20443 [(set (match_dup 2) (match_dup 1))
20444 (set (match_dup 0) (match_dup 2))]
20448 [(set (match_operand:QI 0 "push_operand" "")
20449 (match_operand:QI 1 "memory_operand" ""))
20450 (match_scratch:QI 2 "q")]
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))]
20457 ;; Don't move an immediate directly to memory when the instruction
20460 [(match_scratch:SI 1 "r")
20461 (set (match_operand:SI 0 "memory_operand" "")
20463 "optimize_insn_for_speed_p ()
20464 && ! TARGET_USE_MOV0
20465 && TARGET_SPLIT_LONG_MOVES
20466 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20467 && peep2_regno_dead_p (0, FLAGS_REG)"
20468 [(parallel [(set (match_dup 1) (const_int 0))
20469 (clobber (reg:CC FLAGS_REG))])
20470 (set (match_dup 0) (match_dup 1))]
20474 [(match_scratch:HI 1 "r")
20475 (set (match_operand:HI 0 "memory_operand" "")
20477 "optimize_insn_for_speed_p ()
20478 && ! TARGET_USE_MOV0
20479 && TARGET_SPLIT_LONG_MOVES
20480 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20481 && peep2_regno_dead_p (0, FLAGS_REG)"
20482 [(parallel [(set (match_dup 2) (const_int 0))
20483 (clobber (reg:CC FLAGS_REG))])
20484 (set (match_dup 0) (match_dup 1))]
20485 "operands[2] = gen_lowpart (SImode, operands[1]);")
20488 [(match_scratch:QI 1 "q")
20489 (set (match_operand:QI 0 "memory_operand" "")
20491 "optimize_insn_for_speed_p ()
20492 && ! TARGET_USE_MOV0
20493 && TARGET_SPLIT_LONG_MOVES
20494 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20495 && peep2_regno_dead_p (0, FLAGS_REG)"
20496 [(parallel [(set (match_dup 2) (const_int 0))
20497 (clobber (reg:CC FLAGS_REG))])
20498 (set (match_dup 0) (match_dup 1))]
20499 "operands[2] = gen_lowpart (SImode, operands[1]);")
20502 [(match_scratch:SI 2 "r")
20503 (set (match_operand:SI 0 "memory_operand" "")
20504 (match_operand:SI 1 "immediate_operand" ""))]
20505 "optimize_insn_for_speed_p ()
20506 && TARGET_SPLIT_LONG_MOVES
20507 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20508 [(set (match_dup 2) (match_dup 1))
20509 (set (match_dup 0) (match_dup 2))]
20513 [(match_scratch:HI 2 "r")
20514 (set (match_operand:HI 0 "memory_operand" "")
20515 (match_operand:HI 1 "immediate_operand" ""))]
20516 "optimize_insn_for_speed_p ()
20517 && TARGET_SPLIT_LONG_MOVES
20518 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20519 [(set (match_dup 2) (match_dup 1))
20520 (set (match_dup 0) (match_dup 2))]
20524 [(match_scratch:QI 2 "q")
20525 (set (match_operand:QI 0 "memory_operand" "")
20526 (match_operand:QI 1 "immediate_operand" ""))]
20527 "optimize_insn_for_speed_p ()
20528 && TARGET_SPLIT_LONG_MOVES
20529 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20530 [(set (match_dup 2) (match_dup 1))
20531 (set (match_dup 0) (match_dup 2))]
20534 ;; Don't compare memory with zero, load and use a test instead.
20536 [(set (match_operand 0 "flags_reg_operand" "")
20537 (match_operator 1 "compare_operator"
20538 [(match_operand:SI 2 "memory_operand" "")
20540 (match_scratch:SI 3 "r")]
20541 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20542 [(set (match_dup 3) (match_dup 2))
20543 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20546 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20547 ;; Don't split NOTs with a displacement operand, because resulting XOR
20548 ;; will not be pairable anyway.
20550 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20551 ;; represented using a modRM byte. The XOR replacement is long decoded,
20552 ;; so this split helps here as well.
20554 ;; Note: Can't do this as a regular split because we can't get proper
20555 ;; lifetime information then.
20558 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20559 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20560 "optimize_insn_for_speed_p ()
20561 && ((TARGET_NOT_UNPAIRABLE
20562 && (!MEM_P (operands[0])
20563 || !memory_displacement_operand (operands[0], SImode)))
20564 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20565 && peep2_regno_dead_p (0, FLAGS_REG)"
20566 [(parallel [(set (match_dup 0)
20567 (xor:SI (match_dup 1) (const_int -1)))
20568 (clobber (reg:CC FLAGS_REG))])]
20572 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20573 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20574 "optimize_insn_for_speed_p ()
20575 && ((TARGET_NOT_UNPAIRABLE
20576 && (!MEM_P (operands[0])
20577 || !memory_displacement_operand (operands[0], HImode)))
20578 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20579 && peep2_regno_dead_p (0, FLAGS_REG)"
20580 [(parallel [(set (match_dup 0)
20581 (xor:HI (match_dup 1) (const_int -1)))
20582 (clobber (reg:CC FLAGS_REG))])]
20586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20587 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20588 "optimize_insn_for_speed_p ()
20589 && ((TARGET_NOT_UNPAIRABLE
20590 && (!MEM_P (operands[0])
20591 || !memory_displacement_operand (operands[0], QImode)))
20592 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20593 && peep2_regno_dead_p (0, FLAGS_REG)"
20594 [(parallel [(set (match_dup 0)
20595 (xor:QI (match_dup 1) (const_int -1)))
20596 (clobber (reg:CC FLAGS_REG))])]
20599 ;; Non pairable "test imm, reg" instructions can be translated to
20600 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20601 ;; byte opcode instead of two, have a short form for byte operands),
20602 ;; so do it for other CPUs as well. Given that the value was dead,
20603 ;; this should not create any new dependencies. Pass on the sub-word
20604 ;; versions if we're concerned about partial register stalls.
20607 [(set (match_operand 0 "flags_reg_operand" "")
20608 (match_operator 1 "compare_operator"
20609 [(and:SI (match_operand:SI 2 "register_operand" "")
20610 (match_operand:SI 3 "immediate_operand" ""))
20612 "ix86_match_ccmode (insn, CCNOmode)
20613 && (true_regnum (operands[2]) != AX_REG
20614 || satisfies_constraint_K (operands[3]))
20615 && peep2_reg_dead_p (1, operands[2])"
20617 [(set (match_dup 0)
20618 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20621 (and:SI (match_dup 2) (match_dup 3)))])]
20624 ;; We don't need to handle HImode case, because it will be promoted to SImode
20625 ;; on ! TARGET_PARTIAL_REG_STALL
20628 [(set (match_operand 0 "flags_reg_operand" "")
20629 (match_operator 1 "compare_operator"
20630 [(and:QI (match_operand:QI 2 "register_operand" "")
20631 (match_operand:QI 3 "immediate_operand" ""))
20633 "! TARGET_PARTIAL_REG_STALL
20634 && ix86_match_ccmode (insn, CCNOmode)
20635 && true_regnum (operands[2]) != AX_REG
20636 && peep2_reg_dead_p (1, operands[2])"
20638 [(set (match_dup 0)
20639 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20642 (and:QI (match_dup 2) (match_dup 3)))])]
20646 [(set (match_operand 0 "flags_reg_operand" "")
20647 (match_operator 1 "compare_operator"
20650 (match_operand 2 "ext_register_operand" "")
20653 (match_operand 3 "const_int_operand" ""))
20655 "! TARGET_PARTIAL_REG_STALL
20656 && ix86_match_ccmode (insn, CCNOmode)
20657 && true_regnum (operands[2]) != AX_REG
20658 && peep2_reg_dead_p (1, operands[2])"
20659 [(parallel [(set (match_dup 0)
20668 (set (zero_extract:SI (match_dup 2)
20679 ;; Don't do logical operations with memory inputs.
20681 [(match_scratch:SI 2 "r")
20682 (parallel [(set (match_operand:SI 0 "register_operand" "")
20683 (match_operator:SI 3 "arith_or_logical_operator"
20685 (match_operand:SI 1 "memory_operand" "")]))
20686 (clobber (reg:CC FLAGS_REG))])]
20687 "optimize_insn_for_speed_p ()"
20688 [(set (match_dup 2) (match_dup 1))
20689 (parallel [(set (match_dup 0)
20690 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20691 (clobber (reg:CC FLAGS_REG))])]
20695 [(match_scratch:SI 2 "r")
20696 (parallel [(set (match_operand:SI 0 "register_operand" "")
20697 (match_operator:SI 3 "arith_or_logical_operator"
20698 [(match_operand:SI 1 "memory_operand" "")
20700 (clobber (reg:CC FLAGS_REG))])]
20701 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20702 [(set (match_dup 2) (match_dup 1))
20703 (parallel [(set (match_dup 0)
20704 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20705 (clobber (reg:CC FLAGS_REG))])]
20708 ; Don't do logical operations with memory outputs
20710 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20711 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20712 ; the same decoder scheduling characteristics as the original.
20715 [(match_scratch:SI 2 "r")
20716 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20717 (match_operator:SI 3 "arith_or_logical_operator"
20719 (match_operand:SI 1 "nonmemory_operand" "")]))
20720 (clobber (reg:CC FLAGS_REG))])]
20721 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20722 [(set (match_dup 2) (match_dup 0))
20723 (parallel [(set (match_dup 2)
20724 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20725 (clobber (reg:CC FLAGS_REG))])
20726 (set (match_dup 0) (match_dup 2))]
20730 [(match_scratch:SI 2 "r")
20731 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20732 (match_operator:SI 3 "arith_or_logical_operator"
20733 [(match_operand:SI 1 "nonmemory_operand" "")
20735 (clobber (reg:CC FLAGS_REG))])]
20736 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20737 [(set (match_dup 2) (match_dup 0))
20738 (parallel [(set (match_dup 2)
20739 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20740 (clobber (reg:CC FLAGS_REG))])
20741 (set (match_dup 0) (match_dup 2))]
20744 ;; Attempt to always use XOR for zeroing registers.
20746 [(set (match_operand 0 "register_operand" "")
20747 (match_operand 1 "const0_operand" ""))]
20748 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20749 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20750 && GENERAL_REG_P (operands[0])
20751 && peep2_regno_dead_p (0, FLAGS_REG)"
20752 [(parallel [(set (match_dup 0) (const_int 0))
20753 (clobber (reg:CC FLAGS_REG))])]
20755 operands[0] = gen_lowpart (word_mode, operands[0]);
20759 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20761 "(GET_MODE (operands[0]) == QImode
20762 || GET_MODE (operands[0]) == HImode)
20763 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20764 && peep2_regno_dead_p (0, FLAGS_REG)"
20765 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20766 (clobber (reg:CC FLAGS_REG))])])
20768 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20770 [(set (match_operand 0 "register_operand" "")
20772 "(GET_MODE (operands[0]) == HImode
20773 || GET_MODE (operands[0]) == SImode
20774 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20775 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20776 && peep2_regno_dead_p (0, FLAGS_REG)"
20777 [(parallel [(set (match_dup 0) (const_int -1))
20778 (clobber (reg:CC FLAGS_REG))])]
20779 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20782 ;; Attempt to convert simple leas to adds. These can be created by
20785 [(set (match_operand:SI 0 "register_operand" "")
20786 (plus:SI (match_dup 0)
20787 (match_operand:SI 1 "nonmemory_operand" "")))]
20788 "peep2_regno_dead_p (0, FLAGS_REG)"
20789 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20790 (clobber (reg:CC FLAGS_REG))])]
20794 [(set (match_operand:SI 0 "register_operand" "")
20795 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20796 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20797 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20798 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20799 (clobber (reg:CC FLAGS_REG))])]
20800 "operands[2] = gen_lowpart (SImode, operands[2]);")
20803 [(set (match_operand:DI 0 "register_operand" "")
20804 (plus:DI (match_dup 0)
20805 (match_operand:DI 1 "x86_64_general_operand" "")))]
20806 "peep2_regno_dead_p (0, FLAGS_REG)"
20807 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20808 (clobber (reg:CC FLAGS_REG))])]
20812 [(set (match_operand:SI 0 "register_operand" "")
20813 (mult:SI (match_dup 0)
20814 (match_operand:SI 1 "const_int_operand" "")))]
20815 "exact_log2 (INTVAL (operands[1])) >= 0
20816 && peep2_regno_dead_p (0, FLAGS_REG)"
20817 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20818 (clobber (reg:CC FLAGS_REG))])]
20819 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20822 [(set (match_operand:DI 0 "register_operand" "")
20823 (mult:DI (match_dup 0)
20824 (match_operand:DI 1 "const_int_operand" "")))]
20825 "exact_log2 (INTVAL (operands[1])) >= 0
20826 && peep2_regno_dead_p (0, FLAGS_REG)"
20827 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20828 (clobber (reg:CC FLAGS_REG))])]
20829 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20832 [(set (match_operand:SI 0 "register_operand" "")
20833 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20834 (match_operand:DI 2 "const_int_operand" "")) 0))]
20835 "exact_log2 (INTVAL (operands[2])) >= 0
20836 && REGNO (operands[0]) == REGNO (operands[1])
20837 && peep2_regno_dead_p (0, FLAGS_REG)"
20838 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20839 (clobber (reg:CC FLAGS_REG))])]
20840 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20842 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20843 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20844 ;; many CPUs it is also faster, since special hardware to avoid esp
20845 ;; dependencies is present.
20847 ;; While some of these conversions may be done using splitters, we use peepholes
20848 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20850 ;; Convert prologue esp subtractions to push.
20851 ;; We need register to push. In order to keep verify_flow_info happy we have
20853 ;; - use scratch and clobber it in order to avoid dependencies
20854 ;; - use already live register
20855 ;; We can't use the second way right now, since there is no reliable way how to
20856 ;; verify that given register is live. First choice will also most likely in
20857 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20858 ;; call clobbered registers are dead. We may want to use base pointer as an
20859 ;; alternative when no register is available later.
20862 [(match_scratch:SI 0 "r")
20863 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20864 (clobber (reg:CC FLAGS_REG))
20865 (clobber (mem:BLK (scratch)))])]
20866 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20867 [(clobber (match_dup 0))
20868 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20869 (clobber (mem:BLK (scratch)))])])
20872 [(match_scratch:SI 0 "r")
20873 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20874 (clobber (reg:CC FLAGS_REG))
20875 (clobber (mem:BLK (scratch)))])]
20876 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20877 [(clobber (match_dup 0))
20878 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20879 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20880 (clobber (mem:BLK (scratch)))])])
20882 ;; Convert esp subtractions to push.
20884 [(match_scratch:SI 0 "r")
20885 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20886 (clobber (reg:CC FLAGS_REG))])]
20887 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20888 [(clobber (match_dup 0))
20889 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20892 [(match_scratch:SI 0 "r")
20893 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20894 (clobber (reg:CC FLAGS_REG))])]
20895 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20896 [(clobber (match_dup 0))
20897 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20898 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20900 ;; Convert epilogue deallocator to pop.
20902 [(match_scratch:SI 0 "r")
20903 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20904 (clobber (reg:CC FLAGS_REG))
20905 (clobber (mem:BLK (scratch)))])]
20906 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20907 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20908 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20909 (clobber (mem:BLK (scratch)))])]
20912 ;; Two pops case is tricky, since pop causes dependency on destination register.
20913 ;; We use two registers if available.
20915 [(match_scratch:SI 0 "r")
20916 (match_scratch:SI 1 "r")
20917 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20918 (clobber (reg:CC FLAGS_REG))
20919 (clobber (mem:BLK (scratch)))])]
20920 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20921 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20922 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20923 (clobber (mem:BLK (scratch)))])
20924 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20925 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20929 [(match_scratch:SI 0 "r")
20930 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20931 (clobber (reg:CC FLAGS_REG))
20932 (clobber (mem:BLK (scratch)))])]
20933 "optimize_insn_for_size_p ()"
20934 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20935 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20936 (clobber (mem:BLK (scratch)))])
20937 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20938 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20941 ;; Convert esp additions to pop.
20943 [(match_scratch:SI 0 "r")
20944 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20945 (clobber (reg:CC FLAGS_REG))])]
20947 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20948 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20951 ;; Two pops case is tricky, since pop causes dependency on destination register.
20952 ;; We use two registers if available.
20954 [(match_scratch:SI 0 "r")
20955 (match_scratch:SI 1 "r")
20956 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957 (clobber (reg:CC FLAGS_REG))])]
20959 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20960 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20961 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20966 [(match_scratch:SI 0 "r")
20967 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20968 (clobber (reg:CC FLAGS_REG))])]
20969 "optimize_insn_for_size_p ()"
20970 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20971 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20972 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20973 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20976 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20977 ;; required and register dies. Similarly for 128 to -128.
20979 [(set (match_operand 0 "flags_reg_operand" "")
20980 (match_operator 1 "compare_operator"
20981 [(match_operand 2 "register_operand" "")
20982 (match_operand 3 "const_int_operand" "")]))]
20983 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20984 && incdec_operand (operands[3], GET_MODE (operands[3])))
20985 || (!TARGET_FUSE_CMP_AND_BRANCH
20986 && INTVAL (operands[3]) == 128))
20987 && ix86_match_ccmode (insn, CCGCmode)
20988 && peep2_reg_dead_p (1, operands[2])"
20989 [(parallel [(set (match_dup 0)
20990 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20991 (clobber (match_dup 2))])]
20995 [(match_scratch:DI 0 "r")
20996 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20997 (clobber (reg:CC FLAGS_REG))
20998 (clobber (mem:BLK (scratch)))])]
20999 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21000 [(clobber (match_dup 0))
21001 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21002 (clobber (mem:BLK (scratch)))])])
21005 [(match_scratch:DI 0 "r")
21006 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21007 (clobber (reg:CC FLAGS_REG))
21008 (clobber (mem:BLK (scratch)))])]
21009 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21010 [(clobber (match_dup 0))
21011 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21012 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21013 (clobber (mem:BLK (scratch)))])])
21015 ;; Convert esp subtractions to push.
21017 [(match_scratch:DI 0 "r")
21018 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21019 (clobber (reg:CC FLAGS_REG))])]
21020 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21021 [(clobber (match_dup 0))
21022 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21025 [(match_scratch:DI 0 "r")
21026 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21027 (clobber (reg:CC FLAGS_REG))])]
21028 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21029 [(clobber (match_dup 0))
21030 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21031 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21033 ;; Convert epilogue deallocator to pop.
21035 [(match_scratch:DI 0 "r")
21036 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21037 (clobber (reg:CC FLAGS_REG))
21038 (clobber (mem:BLK (scratch)))])]
21039 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21040 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21041 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21042 (clobber (mem:BLK (scratch)))])]
21045 ;; Two pops case is tricky, since pop causes dependency on destination register.
21046 ;; We use two registers if available.
21048 [(match_scratch:DI 0 "r")
21049 (match_scratch:DI 1 "r")
21050 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21051 (clobber (reg:CC FLAGS_REG))
21052 (clobber (mem:BLK (scratch)))])]
21053 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21054 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21055 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21056 (clobber (mem:BLK (scratch)))])
21057 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21058 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21062 [(match_scratch:DI 0 "r")
21063 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21064 (clobber (reg:CC FLAGS_REG))
21065 (clobber (mem:BLK (scratch)))])]
21066 "optimize_insn_for_size_p ()"
21067 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21068 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21069 (clobber (mem:BLK (scratch)))])
21070 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21071 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21074 ;; Convert esp additions to pop.
21076 [(match_scratch:DI 0 "r")
21077 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21078 (clobber (reg:CC FLAGS_REG))])]
21080 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21081 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21084 ;; Two pops case is tricky, since pop causes dependency on destination register.
21085 ;; We use two registers if available.
21087 [(match_scratch:DI 0 "r")
21088 (match_scratch:DI 1 "r")
21089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090 (clobber (reg:CC FLAGS_REG))])]
21092 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21093 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21094 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21095 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21099 [(match_scratch:DI 0 "r")
21100 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21101 (clobber (reg:CC FLAGS_REG))])]
21102 "optimize_insn_for_size_p ()"
21103 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21104 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21105 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21106 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21109 ;; Convert imul by three, five and nine into lea
21112 [(set (match_operand:SI 0 "register_operand" "")
21113 (mult:SI (match_operand:SI 1 "register_operand" "")
21114 (match_operand:SI 2 "const_int_operand" "")))
21115 (clobber (reg:CC FLAGS_REG))])]
21116 "INTVAL (operands[2]) == 3
21117 || INTVAL (operands[2]) == 5
21118 || INTVAL (operands[2]) == 9"
21119 [(set (match_dup 0)
21120 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21122 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21126 [(set (match_operand:SI 0 "register_operand" "")
21127 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21128 (match_operand:SI 2 "const_int_operand" "")))
21129 (clobber (reg:CC FLAGS_REG))])]
21130 "optimize_insn_for_speed_p ()
21131 && (INTVAL (operands[2]) == 3
21132 || INTVAL (operands[2]) == 5
21133 || INTVAL (operands[2]) == 9)"
21134 [(set (match_dup 0) (match_dup 1))
21136 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21138 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21142 [(set (match_operand:DI 0 "register_operand" "")
21143 (mult:DI (match_operand:DI 1 "register_operand" "")
21144 (match_operand:DI 2 "const_int_operand" "")))
21145 (clobber (reg:CC FLAGS_REG))])]
21147 && (INTVAL (operands[2]) == 3
21148 || INTVAL (operands[2]) == 5
21149 || INTVAL (operands[2]) == 9)"
21150 [(set (match_dup 0)
21151 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21153 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21157 [(set (match_operand:DI 0 "register_operand" "")
21158 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21159 (match_operand:DI 2 "const_int_operand" "")))
21160 (clobber (reg:CC FLAGS_REG))])]
21162 && optimize_insn_for_speed_p ()
21163 && (INTVAL (operands[2]) == 3
21164 || INTVAL (operands[2]) == 5
21165 || INTVAL (operands[2]) == 9)"
21166 [(set (match_dup 0) (match_dup 1))
21168 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21170 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21172 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21173 ;; imul $32bit_imm, reg, reg is direct decoded.
21175 [(match_scratch:DI 3 "r")
21176 (parallel [(set (match_operand:DI 0 "register_operand" "")
21177 (mult:DI (match_operand:DI 1 "memory_operand" "")
21178 (match_operand:DI 2 "immediate_operand" "")))
21179 (clobber (reg:CC FLAGS_REG))])]
21180 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21181 && !satisfies_constraint_K (operands[2])"
21182 [(set (match_dup 3) (match_dup 1))
21183 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21184 (clobber (reg:CC FLAGS_REG))])]
21188 [(match_scratch:SI 3 "r")
21189 (parallel [(set (match_operand:SI 0 "register_operand" "")
21190 (mult:SI (match_operand:SI 1 "memory_operand" "")
21191 (match_operand:SI 2 "immediate_operand" "")))
21192 (clobber (reg:CC FLAGS_REG))])]
21193 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21194 && !satisfies_constraint_K (operands[2])"
21195 [(set (match_dup 3) (match_dup 1))
21196 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21197 (clobber (reg:CC FLAGS_REG))])]
21201 [(match_scratch:SI 3 "r")
21202 (parallel [(set (match_operand:DI 0 "register_operand" "")
21204 (mult:SI (match_operand:SI 1 "memory_operand" "")
21205 (match_operand:SI 2 "immediate_operand" ""))))
21206 (clobber (reg:CC FLAGS_REG))])]
21207 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21208 && !satisfies_constraint_K (operands[2])"
21209 [(set (match_dup 3) (match_dup 1))
21210 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21211 (clobber (reg:CC FLAGS_REG))])]
21214 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21215 ;; Convert it into imul reg, reg
21216 ;; It would be better to force assembler to encode instruction using long
21217 ;; immediate, but there is apparently no way to do so.
21219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21220 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21221 (match_operand:DI 2 "const_int_operand" "")))
21222 (clobber (reg:CC FLAGS_REG))])
21223 (match_scratch:DI 3 "r")]
21224 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21225 && satisfies_constraint_K (operands[2])"
21226 [(set (match_dup 3) (match_dup 2))
21227 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21228 (clobber (reg:CC FLAGS_REG))])]
21230 if (!rtx_equal_p (operands[0], operands[1]))
21231 emit_move_insn (operands[0], operands[1]);
21235 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21236 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21237 (match_operand:SI 2 "const_int_operand" "")))
21238 (clobber (reg:CC FLAGS_REG))])
21239 (match_scratch:SI 3 "r")]
21240 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21241 && satisfies_constraint_K (operands[2])"
21242 [(set (match_dup 3) (match_dup 2))
21243 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21244 (clobber (reg:CC FLAGS_REG))])]
21246 if (!rtx_equal_p (operands[0], operands[1]))
21247 emit_move_insn (operands[0], operands[1]);
21251 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21252 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21253 (match_operand:HI 2 "immediate_operand" "")))
21254 (clobber (reg:CC FLAGS_REG))])
21255 (match_scratch:HI 3 "r")]
21256 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21257 [(set (match_dup 3) (match_dup 2))
21258 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21259 (clobber (reg:CC FLAGS_REG))])]
21261 if (!rtx_equal_p (operands[0], operands[1]))
21262 emit_move_insn (operands[0], operands[1]);
21265 ;; After splitting up read-modify operations, array accesses with memory
21266 ;; operands might end up in form:
21268 ;; movl 4(%esp), %edx
21270 ;; instead of pre-splitting:
21272 ;; addl 4(%esp), %eax
21274 ;; movl 4(%esp), %edx
21275 ;; leal (%edx,%eax,4), %eax
21278 [(parallel [(set (match_operand 0 "register_operand" "")
21279 (ashift (match_operand 1 "register_operand" "")
21280 (match_operand 2 "const_int_operand" "")))
21281 (clobber (reg:CC FLAGS_REG))])
21282 (set (match_operand 3 "register_operand")
21283 (match_operand 4 "x86_64_general_operand" ""))
21284 (parallel [(set (match_operand 5 "register_operand" "")
21285 (plus (match_operand 6 "register_operand" "")
21286 (match_operand 7 "register_operand" "")))
21287 (clobber (reg:CC FLAGS_REG))])]
21288 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21289 /* Validate MODE for lea. */
21290 && ((!TARGET_PARTIAL_REG_STALL
21291 && (GET_MODE (operands[0]) == QImode
21292 || GET_MODE (operands[0]) == HImode))
21293 || GET_MODE (operands[0]) == SImode
21294 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21295 /* We reorder load and the shift. */
21296 && !rtx_equal_p (operands[1], operands[3])
21297 && !reg_overlap_mentioned_p (operands[0], operands[4])
21298 /* Last PLUS must consist of operand 0 and 3. */
21299 && !rtx_equal_p (operands[0], operands[3])
21300 && (rtx_equal_p (operands[3], operands[6])
21301 || rtx_equal_p (operands[3], operands[7]))
21302 && (rtx_equal_p (operands[0], operands[6])
21303 || rtx_equal_p (operands[0], operands[7]))
21304 /* The intermediate operand 0 must die or be same as output. */
21305 && (rtx_equal_p (operands[0], operands[5])
21306 || peep2_reg_dead_p (3, operands[0]))"
21307 [(set (match_dup 3) (match_dup 4))
21308 (set (match_dup 0) (match_dup 1))]
21310 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21311 int scale = 1 << INTVAL (operands[2]);
21312 rtx index = gen_lowpart (Pmode, operands[1]);
21313 rtx base = gen_lowpart (Pmode, operands[3]);
21314 rtx dest = gen_lowpart (mode, operands[5]);
21316 operands[1] = gen_rtx_PLUS (Pmode, base,
21317 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21319 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21320 operands[0] = dest;
21323 ;; Call-value patterns last so that the wildcard operand does not
21324 ;; disrupt insn-recog's switch tables.
21326 (define_insn "*call_value_pop_0"
21327 [(set (match_operand 0 "" "")
21328 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21329 (match_operand:SI 2 "" "")))
21330 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21331 (match_operand:SI 3 "immediate_operand" "")))]
21334 if (SIBLING_CALL_P (insn))
21337 return "call\t%P1";
21339 [(set_attr "type" "callv")])
21341 (define_insn "*call_value_pop_1"
21342 [(set (match_operand 0 "" "")
21343 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21344 (match_operand:SI 2 "" "")))
21345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21346 (match_operand:SI 3 "immediate_operand" "i")))]
21349 if (constant_call_address_operand (operands[1], Pmode))
21351 if (SIBLING_CALL_P (insn))
21354 return "call\t%P1";
21356 if (SIBLING_CALL_P (insn))
21359 return "call\t%A1";
21361 [(set_attr "type" "callv")])
21363 (define_insn "*call_value_0"
21364 [(set (match_operand 0 "" "")
21365 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21366 (match_operand:SI 2 "" "")))]
21369 if (SIBLING_CALL_P (insn))
21372 return "call\t%P1";
21374 [(set_attr "type" "callv")])
21376 (define_insn "*call_value_0_rex64"
21377 [(set (match_operand 0 "" "")
21378 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21379 (match_operand:DI 2 "const_int_operand" "")))]
21382 if (SIBLING_CALL_P (insn))
21385 return "call\t%P1";
21387 [(set_attr "type" "callv")])
21389 (define_insn "*call_value_1"
21390 [(set (match_operand 0 "" "")
21391 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21392 (match_operand:SI 2 "" "")))]
21393 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21395 if (constant_call_address_operand (operands[1], Pmode))
21396 return "call\t%P1";
21397 return "call\t%A1";
21399 [(set_attr "type" "callv")])
21401 (define_insn "*sibcall_value_1"
21402 [(set (match_operand 0 "" "")
21403 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21404 (match_operand:SI 2 "" "")))]
21405 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21407 if (constant_call_address_operand (operands[1], Pmode))
21411 [(set_attr "type" "callv")])
21413 (define_insn "*call_value_1_rex64"
21414 [(set (match_operand 0 "" "")
21415 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21416 (match_operand:DI 2 "" "")))]
21417 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21418 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21420 if (constant_call_address_operand (operands[1], Pmode))
21421 return "call\t%P1";
21422 return "call\t%A1";
21424 [(set_attr "type" "callv")])
21426 (define_insn "*call_value_1_rex64_large"
21427 [(set (match_operand 0 "" "")
21428 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21429 (match_operand:DI 2 "" "")))]
21430 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21432 [(set_attr "type" "callv")])
21434 (define_insn "*sibcall_value_1_rex64"
21435 [(set (match_operand 0 "" "")
21436 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21437 (match_operand:DI 2 "" "")))]
21438 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21440 [(set_attr "type" "callv")])
21442 (define_insn "*sibcall_value_1_rex64_v"
21443 [(set (match_operand 0 "" "")
21444 (call (mem:QI (reg:DI R11_REG))
21445 (match_operand:DI 1 "" "")))]
21446 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21448 [(set_attr "type" "callv")])
21450 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21451 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21452 ;; caught for use by garbage collectors and the like. Using an insn that
21453 ;; maps to SIGILL makes it more likely the program will rightfully die.
21454 ;; Keeping with tradition, "6" is in honor of #UD.
21455 (define_insn "trap"
21456 [(trap_if (const_int 1) (const_int 6))]
21458 { return ASM_SHORT "0x0b0f"; }
21459 [(set_attr "length" "2")])
21461 (define_expand "sse_prologue_save"
21462 [(parallel [(set (match_operand:BLK 0 "" "")
21463 (unspec:BLK [(reg:DI 21)
21470 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21471 (use (match_operand:DI 1 "register_operand" ""))
21472 (use (match_operand:DI 2 "immediate_operand" ""))
21473 (use (label_ref:DI (match_operand 3 "" "")))])]
21477 (define_insn "*sse_prologue_save_insn"
21478 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21479 (match_operand:DI 4 "const_int_operand" "n")))
21480 (unspec:BLK [(reg:DI 21)
21487 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21488 (use (match_operand:DI 1 "register_operand" "r"))
21489 (use (match_operand:DI 2 "const_int_operand" "i"))
21490 (use (label_ref:DI (match_operand 3 "" "X")))]
21492 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21493 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21496 operands[0] = gen_rtx_MEM (Pmode,
21497 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21498 /* VEX instruction with a REX prefix will #UD. */
21499 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21500 gcc_unreachable ();
21502 output_asm_insn ("jmp\t%A1", operands);
21503 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21505 operands[4] = adjust_address (operands[0], DImode, i*16);
21506 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21507 PUT_MODE (operands[4], TImode);
21508 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21509 output_asm_insn ("rex", operands);
21510 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21512 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21513 CODE_LABEL_NUMBER (operands[3]));
21516 [(set_attr "type" "other")
21517 (set_attr "length_immediate" "0")
21518 (set_attr "length_address" "0")
21519 (set (attr "length")
21521 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21522 (const_string "34")
21523 (const_string "42")))
21524 (set_attr "memory" "store")
21525 (set_attr "modrm" "0")
21526 (set_attr "prefix" "maybe_vex")
21527 (set_attr "mode" "DI")])
21529 (define_expand "prefetch"
21530 [(prefetch (match_operand 0 "address_operand" "")
21531 (match_operand:SI 1 "const_int_operand" "")
21532 (match_operand:SI 2 "const_int_operand" ""))]
21533 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21535 int rw = INTVAL (operands[1]);
21536 int locality = INTVAL (operands[2]);
21538 gcc_assert (rw == 0 || rw == 1);
21539 gcc_assert (locality >= 0 && locality <= 3);
21540 gcc_assert (GET_MODE (operands[0]) == Pmode
21541 || GET_MODE (operands[0]) == VOIDmode);
21543 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21544 supported by SSE counterpart or the SSE prefetch is not available
21545 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21547 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21548 operands[2] = GEN_INT (3);
21550 operands[1] = const0_rtx;
21553 (define_insn "*prefetch_sse"
21554 [(prefetch (match_operand:SI 0 "address_operand" "p")
21556 (match_operand:SI 1 "const_int_operand" ""))]
21557 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21559 static const char * const patterns[4] = {
21560 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21563 int locality = INTVAL (operands[1]);
21564 gcc_assert (locality >= 0 && locality <= 3);
21566 return patterns[locality];
21568 [(set_attr "type" "sse")
21569 (set_attr "memory" "none")])
21571 (define_insn "*prefetch_sse_rex"
21572 [(prefetch (match_operand:DI 0 "address_operand" "p")
21574 (match_operand:SI 1 "const_int_operand" ""))]
21575 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21577 static const char * const patterns[4] = {
21578 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21581 int locality = INTVAL (operands[1]);
21582 gcc_assert (locality >= 0 && locality <= 3);
21584 return patterns[locality];
21586 [(set_attr "type" "sse")
21587 (set_attr "memory" "none")])
21589 (define_insn "*prefetch_3dnow"
21590 [(prefetch (match_operand:SI 0 "address_operand" "p")
21591 (match_operand:SI 1 "const_int_operand" "n")
21593 "TARGET_3DNOW && !TARGET_64BIT"
21595 if (INTVAL (operands[1]) == 0)
21596 return "prefetch\t%a0";
21598 return "prefetchw\t%a0";
21600 [(set_attr "type" "mmx")
21601 (set_attr "memory" "none")])
21603 (define_insn "*prefetch_3dnow_rex"
21604 [(prefetch (match_operand:DI 0 "address_operand" "p")
21605 (match_operand:SI 1 "const_int_operand" "n")
21607 "TARGET_3DNOW && TARGET_64BIT"
21609 if (INTVAL (operands[1]) == 0)
21610 return "prefetch\t%a0";
21612 return "prefetchw\t%a0";
21614 [(set_attr "type" "mmx")
21615 (set_attr "memory" "none")])
21617 (define_expand "stack_protect_set"
21618 [(match_operand 0 "memory_operand" "")
21619 (match_operand 1 "memory_operand" "")]
21622 #ifdef TARGET_THREAD_SSP_OFFSET
21624 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21625 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21627 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21628 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21631 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21633 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21638 (define_insn "stack_protect_set_si"
21639 [(set (match_operand:SI 0 "memory_operand" "=m")
21640 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21641 (set (match_scratch:SI 2 "=&r") (const_int 0))
21642 (clobber (reg:CC FLAGS_REG))]
21644 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21645 [(set_attr "type" "multi")])
21647 (define_insn "stack_protect_set_di"
21648 [(set (match_operand:DI 0 "memory_operand" "=m")
21649 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21650 (set (match_scratch:DI 2 "=&r") (const_int 0))
21651 (clobber (reg:CC FLAGS_REG))]
21653 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21654 [(set_attr "type" "multi")])
21656 (define_insn "stack_tls_protect_set_si"
21657 [(set (match_operand:SI 0 "memory_operand" "=m")
21658 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21659 (set (match_scratch:SI 2 "=&r") (const_int 0))
21660 (clobber (reg:CC FLAGS_REG))]
21662 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21663 [(set_attr "type" "multi")])
21665 (define_insn "stack_tls_protect_set_di"
21666 [(set (match_operand:DI 0 "memory_operand" "=m")
21667 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21668 (set (match_scratch:DI 2 "=&r") (const_int 0))
21669 (clobber (reg:CC FLAGS_REG))]
21672 /* The kernel uses a different segment register for performance reasons; a
21673 system call would not have to trash the userspace segment register,
21674 which would be expensive */
21675 if (ix86_cmodel != CM_KERNEL)
21676 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21678 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21680 [(set_attr "type" "multi")])
21682 (define_expand "stack_protect_test"
21683 [(match_operand 0 "memory_operand" "")
21684 (match_operand 1 "memory_operand" "")
21685 (match_operand 2 "" "")]
21688 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21689 ix86_compare_op0 = operands[0];
21690 ix86_compare_op1 = operands[1];
21691 ix86_compare_emitted = flags;
21693 #ifdef TARGET_THREAD_SSP_OFFSET
21695 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21696 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21698 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21699 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21702 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21704 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21706 emit_jump_insn (gen_beq (operands[2]));
21710 (define_insn "stack_protect_test_si"
21711 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21712 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21713 (match_operand:SI 2 "memory_operand" "m")]
21715 (clobber (match_scratch:SI 3 "=&r"))]
21717 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21718 [(set_attr "type" "multi")])
21720 (define_insn "stack_protect_test_di"
21721 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21722 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21723 (match_operand:DI 2 "memory_operand" "m")]
21725 (clobber (match_scratch:DI 3 "=&r"))]
21727 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21728 [(set_attr "type" "multi")])
21730 (define_insn "stack_tls_protect_test_si"
21731 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21732 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21733 (match_operand:SI 2 "const_int_operand" "i")]
21734 UNSPEC_SP_TLS_TEST))
21735 (clobber (match_scratch:SI 3 "=r"))]
21737 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21738 [(set_attr "type" "multi")])
21740 (define_insn "stack_tls_protect_test_di"
21741 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21742 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21743 (match_operand:DI 2 "const_int_operand" "i")]
21744 UNSPEC_SP_TLS_TEST))
21745 (clobber (match_scratch:DI 3 "=r"))]
21748 /* The kernel uses a different segment register for performance reasons; a
21749 system call would not have to trash the userspace segment register,
21750 which would be expensive */
21751 if (ix86_cmodel != CM_KERNEL)
21752 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21754 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21756 [(set_attr "type" "multi")])
21758 (define_mode_iterator CRC32MODE [QI HI SI])
21759 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21760 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21762 (define_insn "sse4_2_crc32<mode>"
21763 [(set (match_operand:SI 0 "register_operand" "=r")
21765 [(match_operand:SI 1 "register_operand" "0")
21766 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21769 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21770 [(set_attr "type" "sselog1")
21771 (set_attr "prefix_rep" "1")
21772 (set_attr "prefix_extra" "1")
21773 (set_attr "mode" "SI")])
21775 (define_insn "sse4_2_crc32di"
21776 [(set (match_operand:DI 0 "register_operand" "=r")
21778 [(match_operand:DI 1 "register_operand" "0")
21779 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21781 "TARGET_SSE4_2 && TARGET_64BIT"
21782 "crc32q\t{%2, %0|%0, %2}"
21783 [(set_attr "type" "sselog1")
21784 (set_attr "prefix_rep" "1")
21785 (set_attr "prefix_extra" "1")
21786 (set_attr "mode" "DI")])
21790 (include "sync.md")