1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
61 (UNSPEC_MACHOPIC_OFFSET 10)
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
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)
108 (UNSPEC_MS_TO_SYSV_CALL 48)
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
163 (UNSPEC_INSERTQI 132)
168 (UNSPEC_INSERTPS 135)
170 (UNSPEC_MOVNTDQA 137)
172 (UNSPEC_PHMINPOSUW 139)
178 (UNSPEC_PCMPESTR 144)
179 (UNSPEC_PCMPISTR 145)
182 (UNSPEC_SSE5_INTRINSIC 150)
183 (UNSPEC_SSE5_UNSIGNED_CMP 151)
184 (UNSPEC_SSE5_TRUEFALSE 152)
185 (UNSPEC_SSE5_PERMUTE 153)
187 (UNSPEC_CVTPH2PS 155)
188 (UNSPEC_CVTPS2PH 156)
192 (UNSPEC_AESENCLAST 160)
194 (UNSPEC_AESDECLAST 162)
196 (UNSPEC_AESKEYGENASSIST 164)
204 (UNSPEC_VPERMIL2F128 168)
205 (UNSPEC_MASKLOAD 169)
206 (UNSPEC_MASKSTORE 170)
212 [(UNSPECV_BLOCKAGE 0)
213 (UNSPECV_STACK_PROBE 1)
225 (UNSPECV_PROLOGUE_USE 14)
227 (UNSPECV_VZEROALL 16)
228 (UNSPECV_VZEROUPPER 17)
231 ;; Constants to represent pcomtrue/pcomfalse variants
241 ;; Constants used in the SSE5 pperm instruction
243 [(PPERM_SRC 0x00) /* copy source */
244 (PPERM_INVERT 0x20) /* invert source */
245 (PPERM_REVERSE 0x40) /* bit reverse source */
246 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
247 (PPERM_ZERO 0x80) /* all 0's */
248 (PPERM_ONES 0xa0) /* all 1's */
249 (PPERM_SIGN 0xc0) /* propagate sign bit */
250 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
251 (PPERM_SRC1 0x00) /* use first source byte */
252 (PPERM_SRC2 0x10) /* use second source byte */
255 ;; Registers by name.
289 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
292 ;; In C guard expressions, put expressions which may be compile-time
293 ;; constants first. This allows for better optimization. For
294 ;; example, write "TARGET_64BIT && reload_completed", not
295 ;; "reload_completed && TARGET_64BIT".
299 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
301 (const (symbol_ref "ix86_schedule")))
303 ;; A basic instruction type. Refinements due to arguments to be
304 ;; provided in other attributes.
307 alu,alu1,negnot,imov,imovx,lea,
308 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
309 icmp,test,ibr,setcc,icmov,
310 push,pop,call,callv,leave,
312 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
313 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
314 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
317 (const_string "other"))
319 ;; Main data type used by the insn
321 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
322 (const_string "unknown"))
324 ;; The CPU unit operations uses.
325 (define_attr "unit" "integer,i387,sse,mmx,unknown"
326 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
327 (const_string "i387")
328 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
329 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
330 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
332 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
334 (eq_attr "type" "other")
335 (const_string "unknown")]
336 (const_string "integer")))
338 ;; The (bounding maximum) length of an instruction immediate.
339 (define_attr "length_immediate" ""
340 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
343 (eq_attr "unit" "i387,sse,mmx")
345 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
347 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
348 (eq_attr "type" "imov,test")
349 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
350 (eq_attr "type" "call")
351 (if_then_else (match_operand 0 "constant_call_address_operand" "")
354 (eq_attr "type" "callv")
355 (if_then_else (match_operand 1 "constant_call_address_operand" "")
358 ;; We don't know the size before shorten_branches. Expect
359 ;; the instruction to fit for better scheduling.
360 (eq_attr "type" "ibr")
363 (symbol_ref "/* Update immediate_length and other attributes! */
364 gcc_unreachable (),1")))
366 ;; The (bounding maximum) length of an instruction address.
367 (define_attr "length_address" ""
368 (cond [(eq_attr "type" "str,other,multi,fxch")
370 (and (eq_attr "type" "call")
371 (match_operand 0 "constant_call_address_operand" ""))
373 (and (eq_attr "type" "callv")
374 (match_operand 1 "constant_call_address_operand" ""))
377 (symbol_ref "ix86_attr_length_address_default (insn)")))
379 ;; Set when length prefix is used.
380 (define_attr "prefix_data16" ""
381 (if_then_else (ior (eq_attr "mode" "HI")
382 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
386 ;; Set when string REP prefix is used.
387 (define_attr "prefix_rep" ""
388 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
392 ;; Set when 0f opcode prefix is used.
393 (define_attr "prefix_0f" ""
395 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
396 (eq_attr "unit" "sse,mmx"))
400 ;; Set when REX opcode prefix is used.
401 (define_attr "prefix_rex" ""
402 (cond [(and (eq_attr "mode" "DI")
403 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
405 (and (eq_attr "mode" "QI")
406 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
409 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
415 ;; There are also additional prefixes in SSSE3.
416 (define_attr "prefix_extra" "" (const_int 0))
418 ;; Prefix used: original, VEX or maybe VEX.
419 (define_attr "prefix" "orig,vex,maybe_vex"
420 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
422 (const_string "orig")))
424 ;; There is a 8bit immediate for VEX.
425 (define_attr "prefix_vex_imm8" "" (const_int 0))
427 ;; VEX W bit is used.
428 (define_attr "prefix_vex_w" "" (const_int 0))
430 ;; The length of VEX prefix
431 (define_attr "length_vex" ""
432 (if_then_else (eq_attr "prefix_0f" "1")
433 (if_then_else (eq_attr "prefix_vex_w" "1")
434 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
435 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
436 (if_then_else (eq_attr "prefix_vex_w" "1")
437 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
438 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
440 ;; Set when modrm byte is used.
441 (define_attr "modrm" ""
442 (cond [(eq_attr "type" "str,leave")
444 (eq_attr "unit" "i387")
446 (and (eq_attr "type" "incdec")
447 (ior (match_operand:SI 1 "register_operand" "")
448 (match_operand:HI 1 "register_operand" "")))
450 (and (eq_attr "type" "push")
451 (not (match_operand 1 "memory_operand" "")))
453 (and (eq_attr "type" "pop")
454 (not (match_operand 0 "memory_operand" "")))
456 (and (eq_attr "type" "imov")
457 (ior (and (match_operand 0 "register_operand" "")
458 (match_operand 1 "immediate_operand" ""))
459 (ior (and (match_operand 0 "ax_reg_operand" "")
460 (match_operand 1 "memory_displacement_only_operand" ""))
461 (and (match_operand 0 "memory_displacement_only_operand" "")
462 (match_operand 1 "ax_reg_operand" "")))))
464 (and (eq_attr "type" "call")
465 (match_operand 0 "constant_call_address_operand" ""))
467 (and (eq_attr "type" "callv")
468 (match_operand 1 "constant_call_address_operand" ""))
473 ;; The (bounding maximum) length of an instruction in bytes.
474 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
475 ;; Later we may want to split them and compute proper length as for
477 (define_attr "length" ""
478 (cond [(eq_attr "type" "other,multi,fistp,frndint")
480 (eq_attr "type" "fcmp")
482 (eq_attr "unit" "i387")
484 (plus (attr "prefix_data16")
485 (attr "length_address")))
486 (ior (eq_attr "prefix" "vex")
487 (and (eq_attr "prefix" "maybe_vex")
488 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
489 (plus (attr "length_vex")
490 (plus (attr "prefix_vex_imm8")
492 (attr "length_address"))))]
493 (plus (plus (attr "modrm")
494 (plus (attr "prefix_0f")
495 (plus (attr "prefix_rex")
496 (plus (attr "prefix_extra")
498 (plus (attr "prefix_rep")
499 (plus (attr "prefix_data16")
500 (plus (attr "length_immediate")
501 (attr "length_address")))))))
503 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
504 ;; `store' if there is a simple memory reference therein, or `unknown'
505 ;; if the instruction is complex.
507 (define_attr "memory" "none,load,store,both,unknown"
508 (cond [(eq_attr "type" "other,multi,str")
509 (const_string "unknown")
510 (eq_attr "type" "lea,fcmov,fpspc")
511 (const_string "none")
512 (eq_attr "type" "fistp,leave")
513 (const_string "both")
514 (eq_attr "type" "frndint")
515 (const_string "load")
516 (eq_attr "type" "push")
517 (if_then_else (match_operand 1 "memory_operand" "")
518 (const_string "both")
519 (const_string "store"))
520 (eq_attr "type" "pop")
521 (if_then_else (match_operand 0 "memory_operand" "")
522 (const_string "both")
523 (const_string "load"))
524 (eq_attr "type" "setcc")
525 (if_then_else (match_operand 0 "memory_operand" "")
526 (const_string "store")
527 (const_string "none"))
528 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
529 (if_then_else (ior (match_operand 0 "memory_operand" "")
530 (match_operand 1 "memory_operand" ""))
531 (const_string "load")
532 (const_string "none"))
533 (eq_attr "type" "ibr")
534 (if_then_else (match_operand 0 "memory_operand" "")
535 (const_string "load")
536 (const_string "none"))
537 (eq_attr "type" "call")
538 (if_then_else (match_operand 0 "constant_call_address_operand" "")
539 (const_string "none")
540 (const_string "load"))
541 (eq_attr "type" "callv")
542 (if_then_else (match_operand 1 "constant_call_address_operand" "")
543 (const_string "none")
544 (const_string "load"))
545 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
546 (match_operand 1 "memory_operand" ""))
547 (const_string "both")
548 (and (match_operand 0 "memory_operand" "")
549 (match_operand 1 "memory_operand" ""))
550 (const_string "both")
551 (match_operand 0 "memory_operand" "")
552 (const_string "store")
553 (match_operand 1 "memory_operand" "")
554 (const_string "load")
556 "!alu1,negnot,ishift1,
557 imov,imovx,icmp,test,bitmanip,
559 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
560 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
561 (match_operand 2 "memory_operand" ""))
562 (const_string "load")
563 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
564 (match_operand 3 "memory_operand" ""))
565 (const_string "load")
567 (const_string "none")))
569 ;; Indicates if an instruction has both an immediate and a displacement.
571 (define_attr "imm_disp" "false,true,unknown"
572 (cond [(eq_attr "type" "other,multi")
573 (const_string "unknown")
574 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
575 (and (match_operand 0 "memory_displacement_operand" "")
576 (match_operand 1 "immediate_operand" "")))
577 (const_string "true")
578 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
579 (and (match_operand 0 "memory_displacement_operand" "")
580 (match_operand 2 "immediate_operand" "")))
581 (const_string "true")
583 (const_string "false")))
585 ;; Indicates if an FP operation has an integer source.
587 (define_attr "fp_int_src" "false,true"
588 (const_string "false"))
590 ;; Defines rounding mode of an FP operation.
592 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
593 (const_string "any"))
595 ;; Describe a user's asm statement.
596 (define_asm_attributes
597 [(set_attr "length" "128")
598 (set_attr "type" "multi")])
600 ;; All integer comparison codes.
601 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
603 ;; All floating-point comparison codes.
604 (define_code_iterator fp_cond [unordered ordered
605 uneq unge ungt unle unlt ltgt ])
607 (define_code_iterator plusminus [plus minus])
609 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
611 ;; Base name for define_insn
612 (define_code_attr plusminus_insn
613 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
614 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
616 ;; Base name for insn mnemonic.
617 (define_code_attr plusminus_mnemonic
618 [(plus "add") (ss_plus "adds") (us_plus "addus")
619 (minus "sub") (ss_minus "subs") (us_minus "subus")])
621 ;; Mark commutative operators as such in constraints.
622 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
623 (minus "") (ss_minus "") (us_minus "")])
625 ;; Mapping of signed max and min
626 (define_code_iterator smaxmin [smax smin])
628 ;; Mapping of unsigned max and min
629 (define_code_iterator umaxmin [umax umin])
631 ;; Mapping of signed/unsigned max and min
632 (define_code_iterator maxmin [smax smin umax umin])
634 ;; Base name for integer and FP insn mnemonic
635 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
636 (umax "maxu") (umin "minu")])
637 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
639 ;; Mapping of parallel logic operators
640 (define_code_iterator plogic [and ior xor])
642 ;; Base name for insn mnemonic.
643 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
645 ;; Mapping of abs neg operators
646 (define_code_iterator absneg [abs neg])
648 ;; Base name for x87 insn mnemonic.
649 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
651 ;; All single word integer modes.
652 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
654 ;; Single word integer modes without QImode.
655 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
657 ;; Instruction suffix for integer modes.
658 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
660 ;; Register class for integer modes.
661 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
663 ;; Immediate operand constraint for integer modes.
664 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
666 ;; General operand predicate for integer modes.
667 (define_mode_attr general_operand
668 [(QI "general_operand")
669 (HI "general_operand")
670 (SI "general_operand")
671 (DI "x86_64_general_operand")])
673 ;; SSE and x87 SFmode and DFmode floating point modes
674 (define_mode_iterator MODEF [SF DF])
676 ;; All x87 floating point modes
677 (define_mode_iterator X87MODEF [SF DF XF])
679 ;; All integer modes handled by x87 fisttp operator.
680 (define_mode_iterator X87MODEI [HI SI DI])
682 ;; All integer modes handled by integer x87 operators.
683 (define_mode_iterator X87MODEI12 [HI SI])
685 ;; All integer modes handled by SSE cvtts?2si* operators.
686 (define_mode_iterator SSEMODEI24 [SI DI])
688 ;; SSE asm suffix for floating point modes
689 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
691 ;; SSE vector mode corresponding to a scalar mode
692 (define_mode_attr ssevecmode
693 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
695 ;; Instruction suffix for REX 64bit operators.
696 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
698 ;; This mode iterator allows :P to be used for patterns that operate on
699 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
700 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
703 ;; Scheduling descriptions
705 (include "pentium.md")
708 (include "athlon.md")
712 ;; Operand and operator predicates and constraints
714 (include "predicates.md")
715 (include "constraints.md")
718 ;; Compare instructions.
720 ;; All compare insns have expanders that save the operands away without
721 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
722 ;; after the cmp) will actually emit the cmpM.
724 (define_expand "cmpti"
725 [(set (reg:CC FLAGS_REG)
726 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
727 (match_operand:TI 1 "x86_64_general_operand" "")))]
730 if (MEM_P (operands[0]) && MEM_P (operands[1]))
731 operands[0] = force_reg (TImode, operands[0]);
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
737 (define_expand "cmpdi"
738 [(set (reg:CC FLAGS_REG)
739 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
740 (match_operand:DI 1 "x86_64_general_operand" "")))]
743 if (MEM_P (operands[0]) && MEM_P (operands[1]))
744 operands[0] = force_reg (DImode, operands[0]);
745 ix86_compare_op0 = operands[0];
746 ix86_compare_op1 = operands[1];
750 (define_expand "cmpsi"
751 [(set (reg:CC FLAGS_REG)
752 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
753 (match_operand:SI 1 "general_operand" "")))]
756 if (MEM_P (operands[0]) && MEM_P (operands[1]))
757 operands[0] = force_reg (SImode, operands[0]);
758 ix86_compare_op0 = operands[0];
759 ix86_compare_op1 = operands[1];
763 (define_expand "cmphi"
764 [(set (reg:CC FLAGS_REG)
765 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
766 (match_operand:HI 1 "general_operand" "")))]
769 if (MEM_P (operands[0]) && MEM_P (operands[1]))
770 operands[0] = force_reg (HImode, operands[0]);
771 ix86_compare_op0 = operands[0];
772 ix86_compare_op1 = operands[1];
776 (define_expand "cmpqi"
777 [(set (reg:CC FLAGS_REG)
778 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
779 (match_operand:QI 1 "general_operand" "")))]
782 if (MEM_P (operands[0]) && MEM_P (operands[1]))
783 operands[0] = force_reg (QImode, operands[0]);
784 ix86_compare_op0 = operands[0];
785 ix86_compare_op1 = operands[1];
789 (define_insn "cmpdi_ccno_1_rex64"
790 [(set (reg FLAGS_REG)
791 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
792 (match_operand:DI 1 "const0_operand" "")))]
793 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
796 cmp{q}\t{%1, %0|%0, %1}"
797 [(set_attr "type" "test,icmp")
798 (set_attr "length_immediate" "0,1")
799 (set_attr "mode" "DI")])
801 (define_insn "*cmpdi_minus_1_rex64"
802 [(set (reg FLAGS_REG)
803 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
804 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
806 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
807 "cmp{q}\t{%1, %0|%0, %1}"
808 [(set_attr "type" "icmp")
809 (set_attr "mode" "DI")])
811 (define_expand "cmpdi_1_rex64"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
814 (match_operand:DI 1 "general_operand" "")))]
818 (define_insn "cmpdi_1_insn_rex64"
819 [(set (reg FLAGS_REG)
820 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
821 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
822 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823 "cmp{q}\t{%1, %0|%0, %1}"
824 [(set_attr "type" "icmp")
825 (set_attr "mode" "DI")])
828 (define_insn "*cmpsi_ccno_1"
829 [(set (reg FLAGS_REG)
830 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
831 (match_operand:SI 1 "const0_operand" "")))]
832 "ix86_match_ccmode (insn, CCNOmode)"
835 cmp{l}\t{%1, %0|%0, %1}"
836 [(set_attr "type" "test,icmp")
837 (set_attr "length_immediate" "0,1")
838 (set_attr "mode" "SI")])
840 (define_insn "*cmpsi_minus_1"
841 [(set (reg FLAGS_REG)
842 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
843 (match_operand:SI 1 "general_operand" "ri,mr"))
845 "ix86_match_ccmode (insn, CCGOCmode)"
846 "cmp{l}\t{%1, %0|%0, %1}"
847 [(set_attr "type" "icmp")
848 (set_attr "mode" "SI")])
850 (define_expand "cmpsi_1"
851 [(set (reg:CC FLAGS_REG)
852 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
853 (match_operand:SI 1 "general_operand" "")))]
857 (define_insn "*cmpsi_1_insn"
858 [(set (reg FLAGS_REG)
859 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
860 (match_operand:SI 1 "general_operand" "ri,mr")))]
861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
862 && ix86_match_ccmode (insn, CCmode)"
863 "cmp{l}\t{%1, %0|%0, %1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "SI")])
867 (define_insn "*cmphi_ccno_1"
868 [(set (reg FLAGS_REG)
869 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
870 (match_operand:HI 1 "const0_operand" "")))]
871 "ix86_match_ccmode (insn, CCNOmode)"
874 cmp{w}\t{%1, %0|%0, %1}"
875 [(set_attr "type" "test,icmp")
876 (set_attr "length_immediate" "0,1")
877 (set_attr "mode" "HI")])
879 (define_insn "*cmphi_minus_1"
880 [(set (reg FLAGS_REG)
881 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
882 (match_operand:HI 1 "general_operand" "rn,mr"))
884 "ix86_match_ccmode (insn, CCGOCmode)"
885 "cmp{w}\t{%1, %0|%0, %1}"
886 [(set_attr "type" "icmp")
887 (set_attr "mode" "HI")])
889 (define_insn "*cmphi_1"
890 [(set (reg FLAGS_REG)
891 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
892 (match_operand:HI 1 "general_operand" "rn,mr")))]
893 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
894 && ix86_match_ccmode (insn, CCmode)"
895 "cmp{w}\t{%1, %0|%0, %1}"
896 [(set_attr "type" "icmp")
897 (set_attr "mode" "HI")])
899 (define_insn "*cmpqi_ccno_1"
900 [(set (reg FLAGS_REG)
901 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
902 (match_operand:QI 1 "const0_operand" "")))]
903 "ix86_match_ccmode (insn, CCNOmode)"
906 cmp{b}\t{$0, %0|%0, 0}"
907 [(set_attr "type" "test,icmp")
908 (set_attr "length_immediate" "0,1")
909 (set_attr "mode" "QI")])
911 (define_insn "*cmpqi_1"
912 [(set (reg FLAGS_REG)
913 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
914 (match_operand:QI 1 "general_operand" "qn,mq")))]
915 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916 && ix86_match_ccmode (insn, CCmode)"
917 "cmp{b}\t{%1, %0|%0, %1}"
918 [(set_attr "type" "icmp")
919 (set_attr "mode" "QI")])
921 (define_insn "*cmpqi_minus_1"
922 [(set (reg FLAGS_REG)
923 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
924 (match_operand:QI 1 "general_operand" "qn,mq"))
926 "ix86_match_ccmode (insn, CCGOCmode)"
927 "cmp{b}\t{%1, %0|%0, %1}"
928 [(set_attr "type" "icmp")
929 (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_ext_1"
932 [(set (reg FLAGS_REG)
934 (match_operand:QI 0 "general_operand" "Qm")
937 (match_operand 1 "ext_register_operand" "Q")
940 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941 "cmp{b}\t{%h1, %0|%0, %h1}"
942 [(set_attr "type" "icmp")
943 (set_attr "mode" "QI")])
945 (define_insn "*cmpqi_ext_1_rex64"
946 [(set (reg FLAGS_REG)
948 (match_operand:QI 0 "register_operand" "Q")
951 (match_operand 1 "ext_register_operand" "Q")
954 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
955 "cmp{b}\t{%h1, %0|%0, %h1}"
956 [(set_attr "type" "icmp")
957 (set_attr "mode" "QI")])
959 (define_insn "*cmpqi_ext_2"
960 [(set (reg FLAGS_REG)
964 (match_operand 0 "ext_register_operand" "Q")
967 (match_operand:QI 1 "const0_operand" "")))]
968 "ix86_match_ccmode (insn, CCNOmode)"
970 [(set_attr "type" "test")
971 (set_attr "length_immediate" "0")
972 (set_attr "mode" "QI")])
974 (define_expand "cmpqi_ext_3"
975 [(set (reg:CC FLAGS_REG)
979 (match_operand 0 "ext_register_operand" "")
982 (match_operand:QI 1 "general_operand" "")))]
986 (define_insn "cmpqi_ext_3_insn"
987 [(set (reg FLAGS_REG)
991 (match_operand 0 "ext_register_operand" "Q")
994 (match_operand:QI 1 "general_operand" "Qmn")))]
995 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
996 "cmp{b}\t{%1, %h0|%h0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "QI")])
1000 (define_insn "cmpqi_ext_3_insn_rex64"
1001 [(set (reg FLAGS_REG)
1005 (match_operand 0 "ext_register_operand" "Q")
1008 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1009 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010 "cmp{b}\t{%1, %h0|%h0, %1}"
1011 [(set_attr "type" "icmp")
1012 (set_attr "mode" "QI")])
1014 (define_insn "*cmpqi_ext_4"
1015 [(set (reg FLAGS_REG)
1019 (match_operand 0 "ext_register_operand" "Q")
1024 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)) 0)))]
1027 "ix86_match_ccmode (insn, CCmode)"
1028 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "QI")])
1032 ;; These implement float point compares.
1033 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1034 ;; which would allow mix and match FP modes on the compares. Which is what
1035 ;; the old patterns did, but with many more of them.
1037 (define_expand "cmpxf"
1038 [(set (reg:CC FLAGS_REG)
1039 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1040 (match_operand:XF 1 "nonmemory_operand" "")))]
1043 ix86_compare_op0 = operands[0];
1044 ix86_compare_op1 = operands[1];
1048 (define_expand "cmp<mode>"
1049 [(set (reg:CC FLAGS_REG)
1050 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1051 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1052 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1054 ix86_compare_op0 = operands[0];
1055 ix86_compare_op1 = operands[1];
1059 ;; FP compares, step 1:
1060 ;; Set the FP condition codes.
1062 ;; CCFPmode compare with exceptions
1063 ;; CCFPUmode compare with no exceptions
1065 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1066 ;; used to manage the reg stack popping would not be preserved.
1068 (define_insn "*cmpfp_0"
1069 [(set (match_operand:HI 0 "register_operand" "=a")
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "const0_operand" ""))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077 "* return output_fp_compare (insn, operands, 0, 0);"
1078 [(set_attr "type" "multi")
1079 (set_attr "unit" "i387")
1081 (cond [(match_operand:SF 1 "" "")
1083 (match_operand:DF 1 "" "")
1086 (const_string "XF")))])
1088 (define_insn_and_split "*cmpfp_0_cc"
1089 [(set (reg:CCFP FLAGS_REG)
1091 (match_operand 1 "register_operand" "f")
1092 (match_operand 2 "const0_operand" "")))
1093 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095 && TARGET_SAHF && !TARGET_CMOVE
1096 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098 "&& reload_completed"
1101 [(compare:CCFP (match_dup 1)(match_dup 2))]
1103 (set (reg:CC FLAGS_REG)
1104 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106 [(set_attr "type" "multi")
1107 (set_attr "unit" "i387")
1109 (cond [(match_operand:SF 1 "" "")
1111 (match_operand:DF 1 "" "")
1114 (const_string "XF")))])
1116 (define_insn "*cmpfp_xf"
1117 [(set (match_operand:HI 0 "register_operand" "=a")
1120 (match_operand:XF 1 "register_operand" "f")
1121 (match_operand:XF 2 "register_operand" "f"))]
1124 "* return output_fp_compare (insn, operands, 0, 0);"
1125 [(set_attr "type" "multi")
1126 (set_attr "unit" "i387")
1127 (set_attr "mode" "XF")])
1129 (define_insn_and_split "*cmpfp_xf_cc"
1130 [(set (reg:CCFP FLAGS_REG)
1132 (match_operand:XF 1 "register_operand" "f")
1133 (match_operand:XF 2 "register_operand" "f")))
1134 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1136 && TARGET_SAHF && !TARGET_CMOVE"
1138 "&& reload_completed"
1141 [(compare:CCFP (match_dup 1)(match_dup 2))]
1143 (set (reg:CC FLAGS_REG)
1144 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1146 [(set_attr "type" "multi")
1147 (set_attr "unit" "i387")
1148 (set_attr "mode" "XF")])
1150 (define_insn "*cmpfp_<mode>"
1151 [(set (match_operand:HI 0 "register_operand" "=a")
1154 (match_operand:MODEF 1 "register_operand" "f")
1155 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1158 "* return output_fp_compare (insn, operands, 0, 0);"
1159 [(set_attr "type" "multi")
1160 (set_attr "unit" "i387")
1161 (set_attr "mode" "<MODE>")])
1163 (define_insn_and_split "*cmpfp_<mode>_cc"
1164 [(set (reg:CCFP FLAGS_REG)
1166 (match_operand:MODEF 1 "register_operand" "f")
1167 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1168 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1170 && TARGET_SAHF && !TARGET_CMOVE"
1172 "&& reload_completed"
1175 [(compare:CCFP (match_dup 1)(match_dup 2))]
1177 (set (reg:CC FLAGS_REG)
1178 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1180 [(set_attr "type" "multi")
1181 (set_attr "unit" "i387")
1182 (set_attr "mode" "<MODE>")])
1184 (define_insn "*cmpfp_u"
1185 [(set (match_operand:HI 0 "register_operand" "=a")
1188 (match_operand 1 "register_operand" "f")
1189 (match_operand 2 "register_operand" "f"))]
1191 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1192 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1193 "* return output_fp_compare (insn, operands, 0, 1);"
1194 [(set_attr "type" "multi")
1195 (set_attr "unit" "i387")
1197 (cond [(match_operand:SF 1 "" "")
1199 (match_operand:DF 1 "" "")
1202 (const_string "XF")))])
1204 (define_insn_and_split "*cmpfp_u_cc"
1205 [(set (reg:CCFPU FLAGS_REG)
1207 (match_operand 1 "register_operand" "f")
1208 (match_operand 2 "register_operand" "f")))
1209 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1210 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211 && TARGET_SAHF && !TARGET_CMOVE
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214 "&& reload_completed"
1217 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1219 (set (reg:CC FLAGS_REG)
1220 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1222 [(set_attr "type" "multi")
1223 (set_attr "unit" "i387")
1225 (cond [(match_operand:SF 1 "" "")
1227 (match_operand:DF 1 "" "")
1230 (const_string "XF")))])
1232 (define_insn "*cmpfp_<mode>"
1233 [(set (match_operand:HI 0 "register_operand" "=a")
1236 (match_operand 1 "register_operand" "f")
1237 (match_operator 3 "float_operator"
1238 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1240 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1241 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1242 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1243 "* return output_fp_compare (insn, operands, 0, 0);"
1244 [(set_attr "type" "multi")
1245 (set_attr "unit" "i387")
1246 (set_attr "fp_int_src" "true")
1247 (set_attr "mode" "<MODE>")])
1249 (define_insn_and_split "*cmpfp_<mode>_cc"
1250 [(set (reg:CCFP FLAGS_REG)
1252 (match_operand 1 "register_operand" "f")
1253 (match_operator 3 "float_operator"
1254 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1255 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257 && TARGET_SAHF && !TARGET_CMOVE
1258 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1259 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1261 "&& reload_completed"
1266 (match_op_dup 3 [(match_dup 2)]))]
1268 (set (reg:CC FLAGS_REG)
1269 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1271 [(set_attr "type" "multi")
1272 (set_attr "unit" "i387")
1273 (set_attr "fp_int_src" "true")
1274 (set_attr "mode" "<MODE>")])
1276 ;; FP compares, step 2
1277 ;; Move the fpsw to ax.
1279 (define_insn "x86_fnstsw_1"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1281 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1284 [(set_attr "length" "2")
1285 (set_attr "mode" "SI")
1286 (set_attr "unit" "i387")])
1288 ;; FP compares, step 3
1289 ;; Get ax into flags, general case.
1291 (define_insn "x86_sahf_1"
1292 [(set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1297 #ifdef HAVE_AS_IX86_SAHF
1300 return ".byte\t0x9e";
1303 [(set_attr "length" "1")
1304 (set_attr "athlon_decode" "vector")
1305 (set_attr "amdfam10_decode" "direct")
1306 (set_attr "mode" "SI")])
1308 ;; Pentium Pro can do steps 1 through 3 in one go.
1309 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1310 (define_insn "*cmpfp_i_mixed"
1311 [(set (reg:CCFP FLAGS_REG)
1312 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1313 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1314 "TARGET_MIX_SSE_I387
1315 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1316 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1317 "* return output_fp_compare (insn, operands, 1, 0);"
1318 [(set_attr "type" "fcmp,ssecomi")
1319 (set_attr "prefix" "orig,maybe_vex")
1321 (if_then_else (match_operand:SF 1 "" "")
1323 (const_string "DF")))
1324 (set_attr "athlon_decode" "vector")
1325 (set_attr "amdfam10_decode" "direct")])
1327 (define_insn "*cmpfp_i_sse"
1328 [(set (reg:CCFP FLAGS_REG)
1329 (compare:CCFP (match_operand 0 "register_operand" "x")
1330 (match_operand 1 "nonimmediate_operand" "xm")))]
1332 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1333 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1334 "* return output_fp_compare (insn, operands, 1, 0);"
1335 [(set_attr "type" "ssecomi")
1336 (set_attr "prefix" "maybe_vex")
1338 (if_then_else (match_operand:SF 1 "" "")
1340 (const_string "DF")))
1341 (set_attr "athlon_decode" "vector")
1342 (set_attr "amdfam10_decode" "direct")])
1344 (define_insn "*cmpfp_i_i387"
1345 [(set (reg:CCFP FLAGS_REG)
1346 (compare:CCFP (match_operand 0 "register_operand" "f")
1347 (match_operand 1 "register_operand" "f")))]
1348 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1350 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1351 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1352 "* return output_fp_compare (insn, operands, 1, 0);"
1353 [(set_attr "type" "fcmp")
1355 (cond [(match_operand:SF 1 "" "")
1357 (match_operand:DF 1 "" "")
1360 (const_string "XF")))
1361 (set_attr "athlon_decode" "vector")
1362 (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_iu_mixed"
1365 [(set (reg:CCFPU FLAGS_REG)
1366 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1367 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1368 "TARGET_MIX_SSE_I387
1369 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1370 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1371 "* return output_fp_compare (insn, operands, 1, 1);"
1372 [(set_attr "type" "fcmp,ssecomi")
1373 (set_attr "prefix" "orig,maybe_vex")
1375 (if_then_else (match_operand:SF 1 "" "")
1377 (const_string "DF")))
1378 (set_attr "athlon_decode" "vector")
1379 (set_attr "amdfam10_decode" "direct")])
1381 (define_insn "*cmpfp_iu_sse"
1382 [(set (reg:CCFPU FLAGS_REG)
1383 (compare:CCFPU (match_operand 0 "register_operand" "x")
1384 (match_operand 1 "nonimmediate_operand" "xm")))]
1386 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1387 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1388 "* return output_fp_compare (insn, operands, 1, 1);"
1389 [(set_attr "type" "ssecomi")
1390 (set_attr "prefix" "maybe_vex")
1392 (if_then_else (match_operand:SF 1 "" "")
1394 (const_string "DF")))
1395 (set_attr "athlon_decode" "vector")
1396 (set_attr "amdfam10_decode" "direct")])
1398 (define_insn "*cmpfp_iu_387"
1399 [(set (reg:CCFPU FLAGS_REG)
1400 (compare:CCFPU (match_operand 0 "register_operand" "f")
1401 (match_operand 1 "register_operand" "f")))]
1402 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1405 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1406 "* return output_fp_compare (insn, operands, 1, 1);"
1407 [(set_attr "type" "fcmp")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 ;; Move instructions.
1420 ;; General case of fullword move.
1422 (define_expand "movsi"
1423 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1424 (match_operand:SI 1 "general_operand" ""))]
1426 "ix86_expand_move (SImode, operands); DONE;")
1428 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1431 ;; %%% We don't use a post-inc memory reference because x86 is not a
1432 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1433 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1434 ;; targets without our curiosities, and it is just as easy to represent
1435 ;; this differently.
1437 (define_insn "*pushsi2"
1438 [(set (match_operand:SI 0 "push_operand" "=<")
1439 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1442 [(set_attr "type" "push")
1443 (set_attr "mode" "SI")])
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushsi2_rex64"
1447 [(set (match_operand:SI 0 "push_operand" "=X")
1448 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1451 [(set_attr "type" "push")
1452 (set_attr "mode" "SI")])
1454 (define_insn "*pushsi2_prologue"
1455 [(set (match_operand:SI 0 "push_operand" "=<")
1456 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1457 (clobber (mem:BLK (scratch)))]
1460 [(set_attr "type" "push")
1461 (set_attr "mode" "SI")])
1463 (define_insn "*popsi1_epilogue"
1464 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1465 (mem:SI (reg:SI SP_REG)))
1466 (set (reg:SI SP_REG)
1467 (plus:SI (reg:SI SP_REG) (const_int 4)))
1468 (clobber (mem:BLK (scratch)))]
1471 [(set_attr "type" "pop")
1472 (set_attr "mode" "SI")])
1474 (define_insn "popsi1"
1475 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1476 (mem:SI (reg:SI SP_REG)))
1477 (set (reg:SI SP_REG)
1478 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1481 [(set_attr "type" "pop")
1482 (set_attr "mode" "SI")])
1484 (define_insn "*movsi_xor"
1485 [(set (match_operand:SI 0 "register_operand" "=r")
1486 (match_operand:SI 1 "const0_operand" ""))
1487 (clobber (reg:CC FLAGS_REG))]
1490 [(set_attr "type" "alu1")
1491 (set_attr "mode" "SI")
1492 (set_attr "length_immediate" "0")])
1494 (define_insn "*movsi_or"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (match_operand:SI 1 "immediate_operand" "i"))
1497 (clobber (reg:CC FLAGS_REG))]
1499 && operands[1] == constm1_rtx"
1501 operands[1] = constm1_rtx;
1502 return "or{l}\t{%1, %0|%0, %1}";
1504 [(set_attr "type" "alu1")
1505 (set_attr "mode" "SI")
1506 (set_attr "length_immediate" "1")])
1508 (define_insn "*movsi_1"
1509 [(set (match_operand:SI 0 "nonimmediate_operand"
1510 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1511 (match_operand:SI 1 "general_operand"
1512 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1513 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1515 switch (get_attr_type (insn))
1518 if (get_attr_mode (insn) == MODE_TI)
1519 return "%vpxor\t%0, %d0";
1520 return "%vxorps\t%0, %d0";
1523 switch (get_attr_mode (insn))
1526 return "%vmovdqa\t{%1, %0|%0, %1}";
1528 return "%vmovaps\t{%1, %0|%0, %1}";
1530 return "%vmovd\t{%1, %0|%0, %1}";
1532 return "%vmovss\t{%1, %0|%0, %1}";
1538 return "pxor\t%0, %0";
1541 if (get_attr_mode (insn) == MODE_DI)
1542 return "movq\t{%1, %0|%0, %1}";
1543 return "movd\t{%1, %0|%0, %1}";
1546 return "lea{l}\t{%1, %0|%0, %1}";
1549 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1550 return "mov{l}\t{%1, %0|%0, %1}";
1554 (cond [(eq_attr "alternative" "2")
1555 (const_string "mmx")
1556 (eq_attr "alternative" "3,4,5")
1557 (const_string "mmxmov")
1558 (eq_attr "alternative" "6")
1559 (const_string "sselog1")
1560 (eq_attr "alternative" "7,8,9,10,11")
1561 (const_string "ssemov")
1562 (match_operand:DI 1 "pic_32bit_operand" "")
1563 (const_string "lea")
1565 (const_string "imov")))
1566 (set (attr "prefix")
1567 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1568 (const_string "orig")
1569 (const_string "maybe_vex")))
1571 (cond [(eq_attr "alternative" "2,3")
1573 (eq_attr "alternative" "6,7")
1575 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1576 (const_string "V4SF")
1577 (const_string "TI"))
1578 (and (eq_attr "alternative" "8,9,10,11")
1579 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1582 (const_string "SI")))])
1584 ;; Stores and loads of ax to arbitrary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabssi_1_rex64"
1588 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1589 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1590 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1592 movabs{l}\t{%1, %P0|%P0, %1}
1593 mov{l}\t{%1, %a0|%a0, %1}"
1594 [(set_attr "type" "imov")
1595 (set_attr "modrm" "0,*")
1596 (set_attr "length_address" "8,0")
1597 (set_attr "length_immediate" "0,*")
1598 (set_attr "memory" "store")
1599 (set_attr "mode" "SI")])
1601 (define_insn "*movabssi_2_rex64"
1602 [(set (match_operand:SI 0 "register_operand" "=a,r")
1603 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1604 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1606 movabs{l}\t{%P1, %0|%0, %P1}
1607 mov{l}\t{%a1, %0|%0, %a1}"
1608 [(set_attr "type" "imov")
1609 (set_attr "modrm" "0,*")
1610 (set_attr "length_address" "8,0")
1611 (set_attr "length_immediate" "0")
1612 (set_attr "memory" "load")
1613 (set_attr "mode" "SI")])
1615 (define_insn "*swapsi"
1616 [(set (match_operand:SI 0 "register_operand" "+r")
1617 (match_operand:SI 1 "register_operand" "+r"))
1622 [(set_attr "type" "imov")
1623 (set_attr "mode" "SI")
1624 (set_attr "pent_pair" "np")
1625 (set_attr "athlon_decode" "vector")
1626 (set_attr "amdfam10_decode" "double")])
1628 (define_expand "movhi"
1629 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1630 (match_operand:HI 1 "general_operand" ""))]
1632 "ix86_expand_move (HImode, operands); DONE;")
1634 (define_insn "*pushhi2"
1635 [(set (match_operand:HI 0 "push_operand" "=X")
1636 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1639 [(set_attr "type" "push")
1640 (set_attr "mode" "SI")])
1642 ;; For 64BIT abi we always round up to 8 bytes.
1643 (define_insn "*pushhi2_rex64"
1644 [(set (match_operand:HI 0 "push_operand" "=X")
1645 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1648 [(set_attr "type" "push")
1649 (set_attr "mode" "DI")])
1651 (define_insn "*movhi_1"
1652 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1653 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1654 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656 switch (get_attr_type (insn))
1659 /* movzwl is faster than movw on p2 due to partial word stalls,
1660 though not as fast as an aligned movl. */
1661 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1663 if (get_attr_mode (insn) == MODE_SI)
1664 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1666 return "mov{w}\t{%1, %0|%0, %1}";
1670 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1671 (const_string "imov")
1672 (and (eq_attr "alternative" "0")
1673 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1675 (eq (symbol_ref "TARGET_HIMODE_MATH")
1677 (const_string "imov")
1678 (and (eq_attr "alternative" "1,2")
1679 (match_operand:HI 1 "aligned_operand" ""))
1680 (const_string "imov")
1681 (and (ne (symbol_ref "TARGET_MOVX")
1683 (eq_attr "alternative" "0,2"))
1684 (const_string "imovx")
1686 (const_string "imov")))
1688 (cond [(eq_attr "type" "imovx")
1690 (and (eq_attr "alternative" "1,2")
1691 (match_operand:HI 1 "aligned_operand" ""))
1693 (and (eq_attr "alternative" "0")
1694 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696 (eq (symbol_ref "TARGET_HIMODE_MATH")
1700 (const_string "HI")))])
1702 ;; Stores and loads of ax to arbitrary constant address.
1703 ;; We fake an second form of instruction to force reload to load address
1704 ;; into register when rax is not available
1705 (define_insn "*movabshi_1_rex64"
1706 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1707 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1708 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710 movabs{w}\t{%1, %P0|%P0, %1}
1711 mov{w}\t{%1, %a0|%a0, %1}"
1712 [(set_attr "type" "imov")
1713 (set_attr "modrm" "0,*")
1714 (set_attr "length_address" "8,0")
1715 (set_attr "length_immediate" "0,*")
1716 (set_attr "memory" "store")
1717 (set_attr "mode" "HI")])
1719 (define_insn "*movabshi_2_rex64"
1720 [(set (match_operand:HI 0 "register_operand" "=a,r")
1721 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1722 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724 movabs{w}\t{%P1, %0|%0, %P1}
1725 mov{w}\t{%a1, %0|%0, %a1}"
1726 [(set_attr "type" "imov")
1727 (set_attr "modrm" "0,*")
1728 (set_attr "length_address" "8,0")
1729 (set_attr "length_immediate" "0")
1730 (set_attr "memory" "load")
1731 (set_attr "mode" "HI")])
1733 (define_insn "*swaphi_1"
1734 [(set (match_operand:HI 0 "register_operand" "+r")
1735 (match_operand:HI 1 "register_operand" "+r"))
1738 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1740 [(set_attr "type" "imov")
1741 (set_attr "mode" "SI")
1742 (set_attr "pent_pair" "np")
1743 (set_attr "athlon_decode" "vector")
1744 (set_attr "amdfam10_decode" "double")])
1746 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1747 (define_insn "*swaphi_2"
1748 [(set (match_operand:HI 0 "register_operand" "+r")
1749 (match_operand:HI 1 "register_operand" "+r"))
1752 "TARGET_PARTIAL_REG_STALL"
1754 [(set_attr "type" "imov")
1755 (set_attr "mode" "HI")
1756 (set_attr "pent_pair" "np")
1757 (set_attr "athlon_decode" "vector")])
1759 (define_expand "movstricthi"
1760 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1761 (match_operand:HI 1 "general_operand" ""))]
1764 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1766 /* Don't generate memory->memory moves, go through a register */
1767 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1768 operands[1] = force_reg (HImode, operands[1]);
1771 (define_insn "*movstricthi_1"
1772 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1773 (match_operand:HI 1 "general_operand" "rn,m"))]
1774 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1776 "mov{w}\t{%1, %0|%0, %1}"
1777 [(set_attr "type" "imov")
1778 (set_attr "mode" "HI")])
1780 (define_insn "*movstricthi_xor"
1781 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1782 (match_operand:HI 1 "const0_operand" ""))
1783 (clobber (reg:CC FLAGS_REG))]
1786 [(set_attr "type" "alu1")
1787 (set_attr "mode" "HI")
1788 (set_attr "length_immediate" "0")])
1790 (define_expand "movqi"
1791 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1792 (match_operand:QI 1 "general_operand" ""))]
1794 "ix86_expand_move (QImode, operands); DONE;")
1796 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1797 ;; "push a byte". But actually we use pushl, which has the effect
1798 ;; of rounding the amount pushed up to a word.
1800 (define_insn "*pushqi2"
1801 [(set (match_operand:QI 0 "push_operand" "=X")
1802 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1805 [(set_attr "type" "push")
1806 (set_attr "mode" "SI")])
1808 ;; For 64BIT abi we always round up to 8 bytes.
1809 (define_insn "*pushqi2_rex64"
1810 [(set (match_operand:QI 0 "push_operand" "=X")
1811 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1814 [(set_attr "type" "push")
1815 (set_attr "mode" "DI")])
1817 ;; Situation is quite tricky about when to choose full sized (SImode) move
1818 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1819 ;; partial register dependency machines (such as AMD Athlon), where QImode
1820 ;; moves issue extra dependency and for partial register stalls machines
1821 ;; that don't use QImode patterns (and QImode move cause stall on the next
1824 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1825 ;; register stall machines with, where we use QImode instructions, since
1826 ;; partial register stall can be caused there. Then we use movzx.
1827 (define_insn "*movqi_1"
1828 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1829 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1830 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 switch (get_attr_type (insn))
1835 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1836 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1838 if (get_attr_mode (insn) == MODE_SI)
1839 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1841 return "mov{b}\t{%1, %0|%0, %1}";
1845 (cond [(and (eq_attr "alternative" "5")
1846 (not (match_operand:QI 1 "aligned_operand" "")))
1847 (const_string "imovx")
1848 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1849 (const_string "imov")
1850 (and (eq_attr "alternative" "3")
1851 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1853 (eq (symbol_ref "TARGET_QIMODE_MATH")
1855 (const_string "imov")
1856 (eq_attr "alternative" "3,5")
1857 (const_string "imovx")
1858 (and (ne (symbol_ref "TARGET_MOVX")
1860 (eq_attr "alternative" "2"))
1861 (const_string "imovx")
1863 (const_string "imov")))
1865 (cond [(eq_attr "alternative" "3,4,5")
1867 (eq_attr "alternative" "6")
1869 (eq_attr "type" "imovx")
1871 (and (eq_attr "type" "imov")
1872 (and (eq_attr "alternative" "0,1")
1873 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1875 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1877 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1880 ;; Avoid partial register stalls when not using QImode arithmetic
1881 (and (eq_attr "type" "imov")
1882 (and (eq_attr "alternative" "0,1")
1883 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1885 (eq (symbol_ref "TARGET_QIMODE_MATH")
1889 (const_string "QI")))])
1891 (define_insn "*swapqi_1"
1892 [(set (match_operand:QI 0 "register_operand" "+r")
1893 (match_operand:QI 1 "register_operand" "+r"))
1896 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1898 [(set_attr "type" "imov")
1899 (set_attr "mode" "SI")
1900 (set_attr "pent_pair" "np")
1901 (set_attr "athlon_decode" "vector")
1902 (set_attr "amdfam10_decode" "vector")])
1904 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1905 (define_insn "*swapqi_2"
1906 [(set (match_operand:QI 0 "register_operand" "+q")
1907 (match_operand:QI 1 "register_operand" "+q"))
1910 "TARGET_PARTIAL_REG_STALL"
1912 [(set_attr "type" "imov")
1913 (set_attr "mode" "QI")
1914 (set_attr "pent_pair" "np")
1915 (set_attr "athlon_decode" "vector")])
1917 (define_expand "movstrictqi"
1918 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1919 (match_operand:QI 1 "general_operand" ""))]
1922 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1924 /* Don't generate memory->memory moves, go through a register. */
1925 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1926 operands[1] = force_reg (QImode, operands[1]);
1929 (define_insn "*movstrictqi_1"
1930 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1931 (match_operand:QI 1 "general_operand" "*qn,m"))]
1932 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934 "mov{b}\t{%1, %0|%0, %1}"
1935 [(set_attr "type" "imov")
1936 (set_attr "mode" "QI")])
1938 (define_insn "*movstrictqi_xor"
1939 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1940 (match_operand:QI 1 "const0_operand" ""))
1941 (clobber (reg:CC FLAGS_REG))]
1944 [(set_attr "type" "alu1")
1945 (set_attr "mode" "QI")
1946 (set_attr "length_immediate" "0")])
1948 (define_insn "*movsi_extv_1"
1949 [(set (match_operand:SI 0 "register_operand" "=R")
1950 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1954 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1955 [(set_attr "type" "imovx")
1956 (set_attr "mode" "SI")])
1958 (define_insn "*movhi_extv_1"
1959 [(set (match_operand:HI 0 "register_operand" "=R")
1960 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1964 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1965 [(set_attr "type" "imovx")
1966 (set_attr "mode" "SI")])
1968 (define_insn "*movqi_extv_1"
1969 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1970 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1975 switch (get_attr_type (insn))
1978 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1980 return "mov{b}\t{%h1, %0|%0, %h1}";
1984 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1985 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986 (ne (symbol_ref "TARGET_MOVX")
1988 (const_string "imovx")
1989 (const_string "imov")))
1991 (if_then_else (eq_attr "type" "imovx")
1993 (const_string "QI")))])
1995 (define_insn "*movqi_extv_1_rex64"
1996 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1997 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2002 switch (get_attr_type (insn))
2005 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007 return "mov{b}\t{%h1, %0|%0, %h1}";
2011 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2012 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2013 (ne (symbol_ref "TARGET_MOVX")
2015 (const_string "imovx")
2016 (const_string "imov")))
2018 (if_then_else (eq_attr "type" "imovx")
2020 (const_string "QI")))])
2022 ;; Stores and loads of ax to arbitrary constant address.
2023 ;; We fake an second form of instruction to force reload to load address
2024 ;; into register when rax is not available
2025 (define_insn "*movabsqi_1_rex64"
2026 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2027 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2028 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030 movabs{b}\t{%1, %P0|%P0, %1}
2031 mov{b}\t{%1, %a0|%a0, %1}"
2032 [(set_attr "type" "imov")
2033 (set_attr "modrm" "0,*")
2034 (set_attr "length_address" "8,0")
2035 (set_attr "length_immediate" "0,*")
2036 (set_attr "memory" "store")
2037 (set_attr "mode" "QI")])
2039 (define_insn "*movabsqi_2_rex64"
2040 [(set (match_operand:QI 0 "register_operand" "=a,r")
2041 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2042 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044 movabs{b}\t{%P1, %0|%0, %P1}
2045 mov{b}\t{%a1, %0|%0, %a1}"
2046 [(set_attr "type" "imov")
2047 (set_attr "modrm" "0,*")
2048 (set_attr "length_address" "8,0")
2049 (set_attr "length_immediate" "0")
2050 (set_attr "memory" "load")
2051 (set_attr "mode" "QI")])
2053 (define_insn "*movdi_extzv_1"
2054 [(set (match_operand:DI 0 "register_operand" "=R")
2055 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2059 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2060 [(set_attr "type" "imovx")
2061 (set_attr "mode" "DI")])
2063 (define_insn "*movsi_extzv_1"
2064 [(set (match_operand:SI 0 "register_operand" "=R")
2065 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2069 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2070 [(set_attr "type" "imovx")
2071 (set_attr "mode" "SI")])
2073 (define_insn "*movqi_extzv_2"
2074 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2075 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2080 switch (get_attr_type (insn))
2083 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2085 return "mov{b}\t{%h1, %0|%0, %h1}";
2089 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091 (ne (symbol_ref "TARGET_MOVX")
2093 (const_string "imovx")
2094 (const_string "imov")))
2096 (if_then_else (eq_attr "type" "imovx")
2098 (const_string "QI")))])
2100 (define_insn "*movqi_extzv_2_rex64"
2101 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2107 switch (get_attr_type (insn))
2110 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112 return "mov{b}\t{%h1, %0|%0, %h1}";
2116 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2117 (ne (symbol_ref "TARGET_MOVX")
2119 (const_string "imovx")
2120 (const_string "imov")))
2122 (if_then_else (eq_attr "type" "imovx")
2124 (const_string "QI")))])
2126 (define_insn "movsi_insv_1"
2127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2130 (match_operand:SI 1 "general_operand" "Qmn"))]
2132 "mov{b}\t{%b1, %h0|%h0, %b1}"
2133 [(set_attr "type" "imov")
2134 (set_attr "mode" "QI")])
2136 (define_insn "*movsi_insv_1_rex64"
2137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2140 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2142 "mov{b}\t{%b1, %h0|%h0, %b1}"
2143 [(set_attr "type" "imov")
2144 (set_attr "mode" "QI")])
2146 (define_insn "movdi_insv_1_rex64"
2147 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2150 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2152 "mov{b}\t{%b1, %h0|%h0, %b1}"
2153 [(set_attr "type" "imov")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movqi_insv_2"
2157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2163 "mov{b}\t{%h1, %h0|%h0, %h1}"
2164 [(set_attr "type" "imov")
2165 (set_attr "mode" "QI")])
2167 (define_expand "movdi"
2168 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169 (match_operand:DI 1 "general_operand" ""))]
2171 "ix86_expand_move (DImode, operands); DONE;")
2173 (define_insn "*pushdi"
2174 [(set (match_operand:DI 0 "push_operand" "=<")
2175 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2179 (define_insn "*pushdi2_rex64"
2180 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2181 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2186 [(set_attr "type" "push,multi")
2187 (set_attr "mode" "DI")])
2189 ;; Convert impossible pushes of immediate to existing instructions.
2190 ;; First try to get scratch register and go through it. In case this
2191 ;; fails, push sign extended lower part first and then overwrite
2192 ;; upper part by 32bit move.
2194 [(match_scratch:DI 2 "r")
2195 (set (match_operand:DI 0 "push_operand" "")
2196 (match_operand:DI 1 "immediate_operand" ""))]
2197 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2198 && !x86_64_immediate_operand (operands[1], DImode)"
2199 [(set (match_dup 2) (match_dup 1))
2200 (set (match_dup 0) (match_dup 2))]
2203 ;; We need to define this as both peepholer and splitter for case
2204 ;; peephole2 pass is not run.
2205 ;; "&& 1" is needed to keep it from matching the previous pattern.
2207 [(set (match_operand:DI 0 "push_operand" "")
2208 (match_operand:DI 1 "immediate_operand" ""))]
2209 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2210 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2211 [(set (match_dup 0) (match_dup 1))
2212 (set (match_dup 2) (match_dup 3))]
2213 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2214 operands[1] = gen_lowpart (DImode, operands[2]);
2215 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2220 [(set (match_operand:DI 0 "push_operand" "")
2221 (match_operand:DI 1 "immediate_operand" ""))]
2222 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2223 ? epilogue_completed : reload_completed)
2224 && !symbolic_operand (operands[1], DImode)
2225 && !x86_64_immediate_operand (operands[1], DImode)"
2226 [(set (match_dup 0) (match_dup 1))
2227 (set (match_dup 2) (match_dup 3))]
2228 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2229 operands[1] = gen_lowpart (DImode, operands[2]);
2230 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2234 (define_insn "*pushdi2_prologue_rex64"
2235 [(set (match_operand:DI 0 "push_operand" "=<")
2236 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2237 (clobber (mem:BLK (scratch)))]
2240 [(set_attr "type" "push")
2241 (set_attr "mode" "DI")])
2243 (define_insn "*popdi1_epilogue_rex64"
2244 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2245 (mem:DI (reg:DI SP_REG)))
2246 (set (reg:DI SP_REG)
2247 (plus:DI (reg:DI SP_REG) (const_int 8)))
2248 (clobber (mem:BLK (scratch)))]
2251 [(set_attr "type" "pop")
2252 (set_attr "mode" "DI")])
2254 (define_insn "popdi1"
2255 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2256 (mem:DI (reg:DI SP_REG)))
2257 (set (reg:DI SP_REG)
2258 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2261 [(set_attr "type" "pop")
2262 (set_attr "mode" "DI")])
2264 (define_insn "*movdi_xor_rex64"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (match_operand:DI 1 "const0_operand" ""))
2267 (clobber (reg:CC FLAGS_REG))]
2269 && reload_completed"
2271 [(set_attr "type" "alu1")
2272 (set_attr "mode" "SI")
2273 (set_attr "length_immediate" "0")])
2275 (define_insn "*movdi_or_rex64"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2277 (match_operand:DI 1 "const_int_operand" "i"))
2278 (clobber (reg:CC FLAGS_REG))]
2281 && operands[1] == constm1_rtx"
2283 operands[1] = constm1_rtx;
2284 return "or{q}\t{%1, %0|%0, %1}";
2286 [(set_attr "type" "alu1")
2287 (set_attr "mode" "DI")
2288 (set_attr "length_immediate" "1")])
2290 (define_insn "*movdi_2"
2291 [(set (match_operand:DI 0 "nonimmediate_operand"
2292 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2293 (match_operand:DI 1 "general_operand"
2294 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2295 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2300 movq\t{%1, %0|%0, %1}
2301 movq\t{%1, %0|%0, %1}
2303 %vmovq\t{%1, %0|%0, %1}
2304 %vmovdqa\t{%1, %0|%0, %1}
2305 %vmovq\t{%1, %0|%0, %1}
2307 movlps\t{%1, %0|%0, %1}
2308 movaps\t{%1, %0|%0, %1}
2309 movlps\t{%1, %0|%0, %1}"
2310 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2311 (set (attr "prefix")
2312 (if_then_else (eq_attr "alternative" "5,6,7,8")
2313 (const_string "vex")
2314 (const_string "orig")))
2315 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2318 [(set (match_operand:DI 0 "push_operand" "")
2319 (match_operand:DI 1 "general_operand" ""))]
2320 "!TARGET_64BIT && reload_completed
2321 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2323 "ix86_split_long_move (operands); DONE;")
2325 ;; %%% This multiword shite has got to go.
2327 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2328 (match_operand:DI 1 "general_operand" ""))]
2329 "!TARGET_64BIT && reload_completed
2330 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2331 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2333 "ix86_split_long_move (operands); DONE;")
2335 (define_insn "*movdi_1_rex64"
2336 [(set (match_operand:DI 0 "nonimmediate_operand"
2337 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2338 (match_operand:DI 1 "general_operand"
2339 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2340 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 switch (get_attr_type (insn))
2345 if (SSE_REG_P (operands[0]))
2346 return "movq2dq\t{%1, %0|%0, %1}";
2348 return "movdq2q\t{%1, %0|%0, %1}";
2353 if (get_attr_mode (insn) == MODE_TI)
2354 return "vmovdqa\t{%1, %0|%0, %1}";
2356 return "vmovq\t{%1, %0|%0, %1}";
2359 if (get_attr_mode (insn) == MODE_TI)
2360 return "movdqa\t{%1, %0|%0, %1}";
2364 /* Moves from and into integer register is done using movd
2365 opcode with REX prefix. */
2366 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2367 return "movd\t{%1, %0|%0, %1}";
2368 return "movq\t{%1, %0|%0, %1}";
2371 return "%vpxor\t%0, %d0";
2374 return "pxor\t%0, %0";
2380 return "lea{q}\t{%a1, %0|%0, %a1}";
2383 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2384 if (get_attr_mode (insn) == MODE_SI)
2385 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2386 else if (which_alternative == 2)
2387 return "movabs{q}\t{%1, %0|%0, %1}";
2389 return "mov{q}\t{%1, %0|%0, %1}";
2393 (cond [(eq_attr "alternative" "5")
2394 (const_string "mmx")
2395 (eq_attr "alternative" "6,7,8,9,10")
2396 (const_string "mmxmov")
2397 (eq_attr "alternative" "11")
2398 (const_string "sselog1")
2399 (eq_attr "alternative" "12,13,14,15,16")
2400 (const_string "ssemov")
2401 (eq_attr "alternative" "17,18")
2402 (const_string "ssecvt")
2403 (eq_attr "alternative" "4")
2404 (const_string "multi")
2405 (match_operand:DI 1 "pic_32bit_operand" "")
2406 (const_string "lea")
2408 (const_string "imov")))
2409 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2410 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411 (set (attr "prefix")
2412 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2413 (const_string "maybe_vex")
2414 (const_string "orig")))
2415 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2417 ;; Stores and loads of ax to arbitrary constant address.
2418 ;; We fake an second form of instruction to force reload to load address
2419 ;; into register when rax is not available
2420 (define_insn "*movabsdi_1_rex64"
2421 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2422 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2423 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2425 movabs{q}\t{%1, %P0|%P0, %1}
2426 mov{q}\t{%1, %a0|%a0, %1}"
2427 [(set_attr "type" "imov")
2428 (set_attr "modrm" "0,*")
2429 (set_attr "length_address" "8,0")
2430 (set_attr "length_immediate" "0,*")
2431 (set_attr "memory" "store")
2432 (set_attr "mode" "DI")])
2434 (define_insn "*movabsdi_2_rex64"
2435 [(set (match_operand:DI 0 "register_operand" "=a,r")
2436 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2437 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2439 movabs{q}\t{%P1, %0|%0, %P1}
2440 mov{q}\t{%a1, %0|%0, %a1}"
2441 [(set_attr "type" "imov")
2442 (set_attr "modrm" "0,*")
2443 (set_attr "length_address" "8,0")
2444 (set_attr "length_immediate" "0")
2445 (set_attr "memory" "load")
2446 (set_attr "mode" "DI")])
2448 ;; Convert impossible stores of immediate to existing instructions.
2449 ;; First try to get scratch register and go through it. In case this
2450 ;; fails, move by 32bit parts.
2452 [(match_scratch:DI 2 "r")
2453 (set (match_operand:DI 0 "memory_operand" "")
2454 (match_operand:DI 1 "immediate_operand" ""))]
2455 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2456 && !x86_64_immediate_operand (operands[1], DImode)"
2457 [(set (match_dup 2) (match_dup 1))
2458 (set (match_dup 0) (match_dup 2))]
2461 ;; We need to define this as both peepholer and splitter for case
2462 ;; peephole2 pass is not run.
2463 ;; "&& 1" is needed to keep it from matching the previous pattern.
2465 [(set (match_operand:DI 0 "memory_operand" "")
2466 (match_operand:DI 1 "immediate_operand" ""))]
2467 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2468 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2469 [(set (match_dup 2) (match_dup 3))
2470 (set (match_dup 4) (match_dup 5))]
2471 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2474 [(set (match_operand:DI 0 "memory_operand" "")
2475 (match_operand:DI 1 "immediate_operand" ""))]
2476 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2477 ? epilogue_completed : reload_completed)
2478 && !symbolic_operand (operands[1], DImode)
2479 && !x86_64_immediate_operand (operands[1], DImode)"
2480 [(set (match_dup 2) (match_dup 3))
2481 (set (match_dup 4) (match_dup 5))]
2482 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2484 (define_insn "*swapdi_rex64"
2485 [(set (match_operand:DI 0 "register_operand" "+r")
2486 (match_operand:DI 1 "register_operand" "+r"))
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "DI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")])
2497 (define_expand "movoi"
2498 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2499 (match_operand:OI 1 "general_operand" ""))]
2501 "ix86_expand_move (OImode, operands); DONE;")
2503 (define_insn "*movoi_internal"
2504 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2505 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2507 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2509 switch (which_alternative)
2512 return "vxorps\t%0, %0, %0";
2515 if (misaligned_operand (operands[0], OImode)
2516 || misaligned_operand (operands[1], OImode))
2517 return "vmovdqu\t{%1, %0|%0, %1}";
2519 return "vmovdqa\t{%1, %0|%0, %1}";
2524 [(set_attr "type" "sselog1,ssemov,ssemov")
2525 (set_attr "prefix" "vex")
2526 (set_attr "mode" "OI")])
2528 (define_expand "movti"
2529 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2530 (match_operand:TI 1 "nonimmediate_operand" ""))]
2531 "TARGET_SSE || TARGET_64BIT"
2534 ix86_expand_move (TImode, operands);
2535 else if (push_operand (operands[0], TImode))
2536 ix86_expand_push (TImode, operands[1]);
2538 ix86_expand_vector_move (TImode, operands);
2542 (define_insn "*movti_internal"
2543 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2544 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2545 "TARGET_SSE && !TARGET_64BIT
2546 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2548 switch (which_alternative)
2551 if (get_attr_mode (insn) == MODE_V4SF)
2552 return "%vxorps\t%0, %d0";
2554 return "%vpxor\t%0, %d0";
2557 /* TDmode values are passed as TImode on the stack. Moving them
2558 to stack may result in unaligned memory access. */
2559 if (misaligned_operand (operands[0], TImode)
2560 || misaligned_operand (operands[1], TImode))
2562 if (get_attr_mode (insn) == MODE_V4SF)
2563 return "%vmovups\t{%1, %0|%0, %1}";
2565 return "%vmovdqu\t{%1, %0|%0, %1}";
2569 if (get_attr_mode (insn) == MODE_V4SF)
2570 return "%vmovaps\t{%1, %0|%0, %1}";
2572 return "%vmovdqa\t{%1, %0|%0, %1}";
2578 [(set_attr "type" "sselog1,ssemov,ssemov")
2579 (set_attr "prefix" "maybe_vex")
2581 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2583 (const_string "V4SF")
2584 (and (eq_attr "alternative" "2")
2585 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2587 (const_string "V4SF")]
2588 (const_string "TI")))])
2590 (define_insn "*movti_rex64"
2591 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2592 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2594 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2596 switch (which_alternative)
2602 if (get_attr_mode (insn) == MODE_V4SF)
2603 return "%vxorps\t%0, %d0";
2605 return "%vpxor\t%0, %d0";
2608 /* TDmode values are passed as TImode on the stack. Moving them
2609 to stack may result in unaligned memory access. */
2610 if (misaligned_operand (operands[0], TImode)
2611 || misaligned_operand (operands[1], TImode))
2613 if (get_attr_mode (insn) == MODE_V4SF)
2614 return "%vmovups\t{%1, %0|%0, %1}";
2616 return "%vmovdqu\t{%1, %0|%0, %1}";
2620 if (get_attr_mode (insn) == MODE_V4SF)
2621 return "%vmovaps\t{%1, %0|%0, %1}";
2623 return "%vmovdqa\t{%1, %0|%0, %1}";
2629 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2630 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2632 (cond [(eq_attr "alternative" "2,3")
2634 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2636 (const_string "V4SF")
2637 (const_string "TI"))
2638 (eq_attr "alternative" "4")
2640 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2644 (const_string "V4SF")
2645 (const_string "TI"))]
2646 (const_string "DI")))])
2649 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2650 (match_operand:TI 1 "general_operand" ""))]
2651 "reload_completed && !SSE_REG_P (operands[0])
2652 && !SSE_REG_P (operands[1])"
2654 "ix86_split_long_move (operands); DONE;")
2656 ;; This expands to what emit_move_complex would generate if we didn't
2657 ;; have a movti pattern. Having this avoids problems with reload on
2658 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2659 ;; to have around all the time.
2660 (define_expand "movcdi"
2661 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2662 (match_operand:CDI 1 "general_operand" ""))]
2665 if (push_operand (operands[0], CDImode))
2666 emit_move_complex_push (CDImode, operands[0], operands[1]);
2668 emit_move_complex_parts (operands[0], operands[1]);
2672 (define_expand "movsf"
2673 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2674 (match_operand:SF 1 "general_operand" ""))]
2676 "ix86_expand_move (SFmode, operands); DONE;")
2678 (define_insn "*pushsf"
2679 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2680 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2683 /* Anything else should be already split before reg-stack. */
2684 gcc_assert (which_alternative == 1);
2685 return "push{l}\t%1";
2687 [(set_attr "type" "multi,push,multi")
2688 (set_attr "unit" "i387,*,*")
2689 (set_attr "mode" "SF,SI,SF")])
2691 (define_insn "*pushsf_rex64"
2692 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2693 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2696 /* Anything else should be already split before reg-stack. */
2697 gcc_assert (which_alternative == 1);
2698 return "push{q}\t%q1";
2700 [(set_attr "type" "multi,push,multi")
2701 (set_attr "unit" "i387,*,*")
2702 (set_attr "mode" "SF,DI,SF")])
2705 [(set (match_operand:SF 0 "push_operand" "")
2706 (match_operand:SF 1 "memory_operand" ""))]
2708 && MEM_P (operands[1])
2709 && (operands[2] = find_constant_src (insn))"
2714 ;; %%% Kill this when call knows how to work this out.
2716 [(set (match_operand:SF 0 "push_operand" "")
2717 (match_operand:SF 1 "any_fp_register_operand" ""))]
2719 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2720 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2723 [(set (match_operand:SF 0 "push_operand" "")
2724 (match_operand:SF 1 "any_fp_register_operand" ""))]
2726 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2727 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2729 (define_insn "*movsf_1"
2730 [(set (match_operand:SF 0 "nonimmediate_operand"
2731 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2732 (match_operand:SF 1 "general_operand"
2733 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2734 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2735 && (reload_in_progress || reload_completed
2736 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2737 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2738 && standard_80387_constant_p (operands[1]))
2739 || GET_CODE (operands[1]) != CONST_DOUBLE
2740 || memory_operand (operands[0], SFmode))"
2742 switch (which_alternative)
2746 return output_387_reg_move (insn, operands);
2749 return standard_80387_constant_opcode (operands[1]);
2753 return "mov{l}\t{%1, %0|%0, %1}";
2755 if (get_attr_mode (insn) == MODE_TI)
2756 return "%vpxor\t%0, %d0";
2758 return "%vxorps\t%0, %d0";
2760 if (get_attr_mode (insn) == MODE_V4SF)
2761 return "%vmovaps\t{%1, %0|%0, %1}";
2763 return "%vmovss\t{%1, %d0|%d0, %1}";
2766 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2767 : "vmovss\t{%1, %0|%0, %1}";
2769 return "movss\t{%1, %0|%0, %1}";
2771 return "%vmovss\t{%1, %0|%0, %1}";
2773 case 9: case 10: case 14: case 15:
2774 return "movd\t{%1, %0|%0, %1}";
2776 return "%vmovd\t{%1, %0|%0, %1}";
2779 return "movq\t{%1, %0|%0, %1}";
2785 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2786 (set (attr "prefix")
2787 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2788 (const_string "maybe_vex")
2789 (const_string "orig")))
2791 (cond [(eq_attr "alternative" "3,4,9,10")
2793 (eq_attr "alternative" "5")
2795 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2797 (ne (symbol_ref "TARGET_SSE2")
2799 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2802 (const_string "V4SF"))
2803 /* For architectures resolving dependencies on
2804 whole SSE registers use APS move to break dependency
2805 chains, otherwise use short move to avoid extra work.
2807 Do the same for architectures resolving dependencies on
2808 the parts. While in DF mode it is better to always handle
2809 just register parts, the SF mode is different due to lack
2810 of instructions to load just part of the register. It is
2811 better to maintain the whole registers in single format
2812 to avoid problems on using packed logical operations. */
2813 (eq_attr "alternative" "6")
2815 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2817 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2819 (const_string "V4SF")
2820 (const_string "SF"))
2821 (eq_attr "alternative" "11")
2822 (const_string "DI")]
2823 (const_string "SF")))])
2825 (define_insn "*swapsf"
2826 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2827 (match_operand:SF 1 "fp_register_operand" "+f"))
2830 "reload_completed || TARGET_80387"
2832 if (STACK_TOP_P (operands[0]))
2837 [(set_attr "type" "fxch")
2838 (set_attr "mode" "SF")])
2840 (define_expand "movdf"
2841 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2842 (match_operand:DF 1 "general_operand" ""))]
2844 "ix86_expand_move (DFmode, operands); DONE;")
2846 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2847 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2848 ;; On the average, pushdf using integers can be still shorter. Allow this
2849 ;; pattern for optimize_size too.
2851 (define_insn "*pushdf_nointeger"
2852 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2853 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2854 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2856 /* This insn should be already split before reg-stack. */
2859 [(set_attr "type" "multi")
2860 (set_attr "unit" "i387,*,*,*")
2861 (set_attr "mode" "DF,SI,SI,DF")])
2863 (define_insn "*pushdf_integer"
2864 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2865 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2866 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2868 /* This insn should be already split before reg-stack. */
2871 [(set_attr "type" "multi")
2872 (set_attr "unit" "i387,*,*")
2873 (set_attr "mode" "DF,SI,DF")])
2875 ;; %%% Kill this when call knows how to work this out.
2877 [(set (match_operand:DF 0 "push_operand" "")
2878 (match_operand:DF 1 "any_fp_register_operand" ""))]
2880 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2881 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2885 [(set (match_operand:DF 0 "push_operand" "")
2886 (match_operand:DF 1 "general_operand" ""))]
2889 "ix86_split_long_move (operands); DONE;")
2891 ;; Moving is usually shorter when only FP registers are used. This separate
2892 ;; movdf pattern avoids the use of integer registers for FP operations
2893 ;; when optimizing for size.
2895 (define_insn "*movdf_nointeger"
2896 [(set (match_operand:DF 0 "nonimmediate_operand"
2897 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2898 (match_operand:DF 1 "general_operand"
2899 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2900 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && ((optimize_function_for_size_p (cfun)
2902 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2903 && (reload_in_progress || reload_completed
2904 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906 && optimize_function_for_size_p (cfun)
2907 && !memory_operand (operands[0], DFmode)
2908 && standard_80387_constant_p (operands[1]))
2909 || GET_CODE (operands[1]) != CONST_DOUBLE
2910 || ((optimize_function_for_size_p (cfun)
2911 || !TARGET_MEMORY_MISMATCH_STALL
2912 || reload_in_progress || reload_completed)
2913 && memory_operand (operands[0], DFmode)))"
2915 switch (which_alternative)
2919 return output_387_reg_move (insn, operands);
2922 return standard_80387_constant_opcode (operands[1]);
2928 switch (get_attr_mode (insn))
2931 return "%vxorps\t%0, %d0";
2933 return "%vxorpd\t%0, %d0";
2935 return "%vpxor\t%0, %d0";
2942 switch (get_attr_mode (insn))
2945 return "%vmovaps\t{%1, %0|%0, %1}";
2947 return "%vmovapd\t{%1, %0|%0, %1}";
2949 return "%vmovdqa\t{%1, %0|%0, %1}";
2951 return "%vmovq\t{%1, %0|%0, %1}";
2955 if (REG_P (operands[0]) && REG_P (operands[1]))
2956 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958 return "vmovsd\t{%1, %0|%0, %1}";
2961 return "movsd\t{%1, %0|%0, %1}";
2965 if (REG_P (operands[0]))
2966 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2968 return "vmovlpd\t{%1, %0|%0, %1}";
2971 return "movlpd\t{%1, %0|%0, %1}";
2975 if (REG_P (operands[0]))
2976 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2978 return "vmovlps\t{%1, %0|%0, %1}";
2981 return "movlps\t{%1, %0|%0, %1}";
2990 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2991 (set (attr "prefix")
2992 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993 (const_string "orig")
2994 (const_string "maybe_vex")))
2996 (cond [(eq_attr "alternative" "0,1,2")
2998 (eq_attr "alternative" "3,4")
3001 /* For SSE1, we have many fewer alternatives. */
3002 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3003 (cond [(eq_attr "alternative" "5,6")
3004 (const_string "V4SF")
3006 (const_string "V2SF"))
3008 /* xorps is one byte shorter. */
3009 (eq_attr "alternative" "5")
3010 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_string "V4SF")
3013 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3017 (const_string "V2DF"))
3019 /* For architectures resolving dependencies on
3020 whole SSE registers use APD move to break dependency
3021 chains, otherwise use short move to avoid extra work.
3023 movaps encodes one byte shorter. */
3024 (eq_attr "alternative" "6")
3026 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028 (const_string "V4SF")
3029 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031 (const_string "V2DF")
3033 (const_string "DF"))
3034 /* For architectures resolving dependencies on register
3035 parts we may avoid extra work to zero out upper part
3037 (eq_attr "alternative" "7")
3039 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041 (const_string "V1DF")
3042 (const_string "DF"))
3044 (const_string "DF")))])
3046 (define_insn "*movdf_integer_rex64"
3047 [(set (match_operand:DF 0 "nonimmediate_operand"
3048 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3049 (match_operand:DF 1 "general_operand"
3050 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3051 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3052 && (reload_in_progress || reload_completed
3053 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3054 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && optimize_function_for_size_p (cfun)
3056 && standard_80387_constant_p (operands[1]))
3057 || GET_CODE (operands[1]) != CONST_DOUBLE
3058 || memory_operand (operands[0], DFmode))"
3060 switch (which_alternative)
3064 return output_387_reg_move (insn, operands);
3067 return standard_80387_constant_opcode (operands[1]);
3074 switch (get_attr_mode (insn))
3077 return "%vxorps\t%0, %d0";
3079 return "%vxorpd\t%0, %d0";
3081 return "%vpxor\t%0, %d0";
3088 switch (get_attr_mode (insn))
3091 return "%vmovaps\t{%1, %0|%0, %1}";
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3095 return "%vmovdqa\t{%1, %0|%0, %1}";
3097 return "%vmovq\t{%1, %0|%0, %1}";
3101 if (REG_P (operands[0]) && REG_P (operands[1]))
3102 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 return "vmovsd\t{%1, %0|%0, %1}";
3107 return "movsd\t{%1, %0|%0, %1}";
3109 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3111 return "%vmovlps\t{%1, %d0|%d0, %1}";
3118 return "%vmovd\t{%1, %0|%0, %1}";
3124 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3125 (set (attr "prefix")
3126 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3127 (const_string "orig")
3128 (const_string "maybe_vex")))
3130 (cond [(eq_attr "alternative" "0,1,2")
3132 (eq_attr "alternative" "3,4,9,10")
3135 /* For SSE1, we have many fewer alternatives. */
3136 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3137 (cond [(eq_attr "alternative" "5,6")
3138 (const_string "V4SF")
3140 (const_string "V2SF"))
3142 /* xorps is one byte shorter. */
3143 (eq_attr "alternative" "5")
3144 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146 (const_string "V4SF")
3147 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3151 (const_string "V2DF"))
3153 /* For architectures resolving dependencies on
3154 whole SSE registers use APD move to break dependency
3155 chains, otherwise use short move to avoid extra work.
3157 movaps encodes one byte shorter. */
3158 (eq_attr "alternative" "6")
3160 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165 (const_string "V2DF")
3167 (const_string "DF"))
3168 /* For architectures resolving dependencies on register
3169 parts we may avoid extra work to zero out upper part
3171 (eq_attr "alternative" "7")
3173 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175 (const_string "V1DF")
3176 (const_string "DF"))
3178 (const_string "DF")))])
3180 (define_insn "*movdf_integer"
3181 [(set (match_operand:DF 0 "nonimmediate_operand"
3182 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3183 (match_operand:DF 1 "general_operand"
3184 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3185 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3186 && optimize_function_for_speed_p (cfun)
3187 && TARGET_INTEGER_DFMODE_MOVES
3188 && (reload_in_progress || reload_completed
3189 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3190 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3191 && optimize_function_for_size_p (cfun)
3192 && standard_80387_constant_p (operands[1]))
3193 || GET_CODE (operands[1]) != CONST_DOUBLE
3194 || memory_operand (operands[0], DFmode))"
3196 switch (which_alternative)
3200 return output_387_reg_move (insn, operands);
3203 return standard_80387_constant_opcode (operands[1]);
3210 switch (get_attr_mode (insn))
3213 return "xorps\t%0, %0";
3215 return "xorpd\t%0, %0";
3217 return "pxor\t%0, %0";
3224 switch (get_attr_mode (insn))
3227 return "movaps\t{%1, %0|%0, %1}";
3229 return "movapd\t{%1, %0|%0, %1}";
3231 return "movdqa\t{%1, %0|%0, %1}";
3233 return "movq\t{%1, %0|%0, %1}";
3235 return "movsd\t{%1, %0|%0, %1}";
3237 return "movlpd\t{%1, %0|%0, %1}";
3239 return "movlps\t{%1, %0|%0, %1}";
3248 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3250 (cond [(eq_attr "alternative" "0,1,2")
3252 (eq_attr "alternative" "3,4")
3255 /* For SSE1, we have many fewer alternatives. */
3256 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257 (cond [(eq_attr "alternative" "5,6")
3258 (const_string "V4SF")
3260 (const_string "V2SF"))
3262 /* xorps is one byte shorter. */
3263 (eq_attr "alternative" "5")
3264 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266 (const_string "V4SF")
3267 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3271 (const_string "V2DF"))
3273 /* For architectures resolving dependencies on
3274 whole SSE registers use APD move to break dependency
3275 chains, otherwise use short move to avoid extra work.
3277 movaps encodes one byte shorter. */
3278 (eq_attr "alternative" "6")
3280 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282 (const_string "V4SF")
3283 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (const_string "V2DF")
3287 (const_string "DF"))
3288 /* For architectures resolving dependencies on register
3289 parts we may avoid extra work to zero out upper part
3291 (eq_attr "alternative" "7")
3293 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295 (const_string "V1DF")
3296 (const_string "DF"))
3298 (const_string "DF")))])
3301 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3302 (match_operand:DF 1 "general_operand" ""))]
3304 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3305 && ! (ANY_FP_REG_P (operands[0]) ||
3306 (GET_CODE (operands[0]) == SUBREG
3307 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3308 && ! (ANY_FP_REG_P (operands[1]) ||
3309 (GET_CODE (operands[1]) == SUBREG
3310 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3312 "ix86_split_long_move (operands); DONE;")
3314 (define_insn "*swapdf"
3315 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3316 (match_operand:DF 1 "fp_register_operand" "+f"))
3319 "reload_completed || TARGET_80387"
3321 if (STACK_TOP_P (operands[0]))
3326 [(set_attr "type" "fxch")
3327 (set_attr "mode" "DF")])
3329 (define_expand "movxf"
3330 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3331 (match_operand:XF 1 "general_operand" ""))]
3333 "ix86_expand_move (XFmode, operands); DONE;")
3335 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3336 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3337 ;; Pushing using integer instructions is longer except for constants
3338 ;; and direct memory references.
3339 ;; (assuming that any given constant is pushed only once, but this ought to be
3340 ;; handled elsewhere).
3342 (define_insn "*pushxf_nointeger"
3343 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3344 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3345 "optimize_function_for_size_p (cfun)"
3347 /* This insn should be already split before reg-stack. */
3350 [(set_attr "type" "multi")
3351 (set_attr "unit" "i387,*,*")
3352 (set_attr "mode" "XF,SI,SI")])
3354 (define_insn "*pushxf_integer"
3355 [(set (match_operand:XF 0 "push_operand" "=<,<")
3356 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3357 "optimize_function_for_speed_p (cfun)"
3359 /* This insn should be already split before reg-stack. */
3362 [(set_attr "type" "multi")
3363 (set_attr "unit" "i387,*")
3364 (set_attr "mode" "XF,SI")])
3367 [(set (match_operand 0 "push_operand" "")
3368 (match_operand 1 "general_operand" ""))]
3370 && (GET_MODE (operands[0]) == XFmode
3371 || GET_MODE (operands[0]) == DFmode)
3372 && !ANY_FP_REG_P (operands[1])"
3374 "ix86_split_long_move (operands); DONE;")
3377 [(set (match_operand:XF 0 "push_operand" "")
3378 (match_operand:XF 1 "any_fp_register_operand" ""))]
3380 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3381 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3382 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3384 ;; Do not use integer registers when optimizing for size
3385 (define_insn "*movxf_nointeger"
3386 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3387 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3388 "optimize_function_for_size_p (cfun)
3389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3390 && (reload_in_progress || reload_completed
3391 || standard_80387_constant_p (operands[1])
3392 || GET_CODE (operands[1]) != CONST_DOUBLE
3393 || memory_operand (operands[0], XFmode))"
3395 switch (which_alternative)
3399 return output_387_reg_move (insn, operands);
3402 return standard_80387_constant_opcode (operands[1]);
3410 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3411 (set_attr "mode" "XF,XF,XF,SI,SI")])
3413 (define_insn "*movxf_integer"
3414 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3415 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3416 "optimize_function_for_speed_p (cfun)
3417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3418 && (reload_in_progress || reload_completed
3419 || GET_CODE (operands[1]) != CONST_DOUBLE
3420 || memory_operand (operands[0], XFmode))"
3422 switch (which_alternative)
3426 return output_387_reg_move (insn, operands);
3429 return standard_80387_constant_opcode (operands[1]);
3438 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3439 (set_attr "mode" "XF,XF,XF,SI,SI")])
3441 (define_expand "movtf"
3442 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3443 (match_operand:TF 1 "nonimmediate_operand" ""))]
3446 ix86_expand_move (TFmode, operands);
3450 (define_insn "*movtf_internal"
3451 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3452 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3456 switch (which_alternative)
3460 if (get_attr_mode (insn) == MODE_V4SF)
3461 return "%vmovaps\t{%1, %0|%0, %1}";
3463 return "%vmovdqa\t{%1, %0|%0, %1}";
3465 if (get_attr_mode (insn) == MODE_V4SF)
3466 return "%vxorps\t%0, %d0";
3468 return "%vpxor\t%0, %d0";
3476 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3477 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3479 (cond [(eq_attr "alternative" "0,2")
3481 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483 (const_string "V4SF")
3484 (const_string "TI"))
3485 (eq_attr "alternative" "1")
3487 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3489 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3491 (const_string "V4SF")
3492 (const_string "TI"))]
3493 (const_string "DI")))])
3495 (define_insn "*pushtf_sse"
3496 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3497 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3500 /* This insn should be already split before reg-stack. */
3503 [(set_attr "type" "multi")
3504 (set_attr "unit" "sse,*,*")
3505 (set_attr "mode" "TF,SI,SI")])
3508 [(set (match_operand:TF 0 "push_operand" "")
3509 (match_operand:TF 1 "general_operand" ""))]
3510 "TARGET_SSE2 && reload_completed
3511 && !SSE_REG_P (operands[1])"
3513 "ix86_split_long_move (operands); DONE;")
3516 [(set (match_operand:TF 0 "push_operand" "")
3517 (match_operand:TF 1 "any_fp_register_operand" ""))]
3519 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3520 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3524 [(set (match_operand 0 "nonimmediate_operand" "")
3525 (match_operand 1 "general_operand" ""))]
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && GET_MODE (operands[0]) == XFmode
3529 && ! (ANY_FP_REG_P (operands[0]) ||
3530 (GET_CODE (operands[0]) == SUBREG
3531 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3532 && ! (ANY_FP_REG_P (operands[1]) ||
3533 (GET_CODE (operands[1]) == SUBREG
3534 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536 "ix86_split_long_move (operands); DONE;")
3539 [(set (match_operand 0 "register_operand" "")
3540 (match_operand 1 "memory_operand" ""))]
3542 && MEM_P (operands[1])
3543 && (GET_MODE (operands[0]) == TFmode
3544 || GET_MODE (operands[0]) == XFmode
3545 || GET_MODE (operands[0]) == SFmode
3546 || GET_MODE (operands[0]) == DFmode)
3547 && (operands[2] = find_constant_src (insn))"
3548 [(set (match_dup 0) (match_dup 2))]
3550 rtx c = operands[2];
3551 rtx r = operands[0];
3553 if (GET_CODE (r) == SUBREG)
3558 if (!standard_sse_constant_p (c))
3561 else if (FP_REG_P (r))
3563 if (!standard_80387_constant_p (c))
3566 else if (MMX_REG_P (r))
3571 [(set (match_operand 0 "register_operand" "")
3572 (float_extend (match_operand 1 "memory_operand" "")))]
3574 && MEM_P (operands[1])
3575 && (GET_MODE (operands[0]) == TFmode
3576 || GET_MODE (operands[0]) == XFmode
3577 || GET_MODE (operands[0]) == SFmode
3578 || GET_MODE (operands[0]) == DFmode)
3579 && (operands[2] = find_constant_src (insn))"
3580 [(set (match_dup 0) (match_dup 2))]
3582 rtx c = operands[2];
3583 rtx r = operands[0];
3585 if (GET_CODE (r) == SUBREG)
3590 if (!standard_sse_constant_p (c))
3593 else if (FP_REG_P (r))
3595 if (!standard_80387_constant_p (c))
3598 else if (MMX_REG_P (r))
3602 (define_insn "swapxf"
3603 [(set (match_operand:XF 0 "register_operand" "+f")
3604 (match_operand:XF 1 "register_operand" "+f"))
3609 if (STACK_TOP_P (operands[0]))
3614 [(set_attr "type" "fxch")
3615 (set_attr "mode" "XF")])
3617 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3619 [(set (match_operand:X87MODEF 0 "register_operand" "")
3620 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3621 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3622 && (standard_80387_constant_p (operands[1]) == 8
3623 || standard_80387_constant_p (operands[1]) == 9)"
3624 [(set (match_dup 0)(match_dup 1))
3626 (neg:X87MODEF (match_dup 0)))]
3630 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3631 if (real_isnegzero (&r))
3632 operands[1] = CONST0_RTX (<MODE>mode);
3634 operands[1] = CONST1_RTX (<MODE>mode);
3638 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3639 (match_operand:TF 1 "general_operand" ""))]
3641 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3643 "ix86_split_long_move (operands); DONE;")
3645 ;; Zero extension instructions
3647 (define_expand "zero_extendhisi2"
3648 [(set (match_operand:SI 0 "register_operand" "")
3649 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3652 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 operands[1] = force_reg (HImode, operands[1]);
3655 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 (define_insn "zero_extendhisi2_and"
3661 [(set (match_operand:SI 0 "register_operand" "=r")
3662 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663 (clobber (reg:CC FLAGS_REG))]
3664 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 [(set_attr "type" "alu1")
3667 (set_attr "mode" "SI")])
3670 [(set (match_operand:SI 0 "register_operand" "")
3671 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3672 (clobber (reg:CC FLAGS_REG))]
3673 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3674 && optimize_function_for_speed_p (cfun)"
3675 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3676 (clobber (reg:CC FLAGS_REG))])]
3679 (define_insn "*zero_extendhisi2_movzwl"
3680 [(set (match_operand:SI 0 "register_operand" "=r")
3681 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3682 "!TARGET_ZERO_EXTEND_WITH_AND
3683 || optimize_function_for_size_p (cfun)"
3684 "movz{wl|x}\t{%1, %0|%0, %1}"
3685 [(set_attr "type" "imovx")
3686 (set_attr "mode" "SI")])
3688 (define_expand "zero_extendqihi2"
3690 [(set (match_operand:HI 0 "register_operand" "")
3691 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))])]
3696 (define_insn "*zero_extendqihi2_and"
3697 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3698 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3699 (clobber (reg:CC FLAGS_REG))]
3700 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702 [(set_attr "type" "alu1")
3703 (set_attr "mode" "HI")])
3705 (define_insn "*zero_extendqihi2_movzbw_and"
3706 [(set (match_operand:HI 0 "register_operand" "=r,r")
3707 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3708 (clobber (reg:CC FLAGS_REG))]
3709 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3711 [(set_attr "type" "imovx,alu1")
3712 (set_attr "mode" "HI")])
3714 ; zero extend to SImode here to avoid partial register stalls
3715 (define_insn "*zero_extendqihi2_movzbl"
3716 [(set (match_operand:HI 0 "register_operand" "=r")
3717 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3718 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3719 && reload_completed"
3720 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3721 [(set_attr "type" "imovx")
3722 (set_attr "mode" "SI")])
3724 ;; For the movzbw case strip only the clobber
3726 [(set (match_operand:HI 0 "register_operand" "")
3727 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3728 (clobber (reg:CC FLAGS_REG))]
3730 && (!TARGET_ZERO_EXTEND_WITH_AND
3731 || optimize_function_for_size_p (cfun))
3732 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733 [(set (match_operand:HI 0 "register_operand" "")
3734 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3736 ;; When source and destination does not overlap, clear destination
3737 ;; first and then do the movb
3739 [(set (match_operand:HI 0 "register_operand" "")
3740 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3741 (clobber (reg:CC FLAGS_REG))]
3743 && ANY_QI_REG_P (operands[0])
3744 && (TARGET_ZERO_EXTEND_WITH_AND
3745 && optimize_function_for_speed_p (cfun))
3746 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3747 [(set (match_dup 0) (const_int 0))
3748 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3749 "operands[2] = gen_lowpart (QImode, operands[0]);")
3751 ;; Rest is handled by single and.
3753 [(set (match_operand:HI 0 "register_operand" "")
3754 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3755 (clobber (reg:CC FLAGS_REG))]
3757 && true_regnum (operands[0]) == true_regnum (operands[1])"
3758 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3759 (clobber (reg:CC FLAGS_REG))])]
3762 (define_expand "zero_extendqisi2"
3764 [(set (match_operand:SI 0 "register_operand" "")
3765 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3766 (clobber (reg:CC FLAGS_REG))])]
3770 (define_insn "*zero_extendqisi2_and"
3771 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3772 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3773 (clobber (reg:CC FLAGS_REG))]
3774 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3776 [(set_attr "type" "alu1")
3777 (set_attr "mode" "SI")])
3779 (define_insn "*zero_extendqisi2_movzbw_and"
3780 [(set (match_operand:SI 0 "register_operand" "=r,r")
3781 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3782 (clobber (reg:CC FLAGS_REG))]
3783 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785 [(set_attr "type" "imovx,alu1")
3786 (set_attr "mode" "SI")])
3788 (define_insn "*zero_extendqisi2_movzbw"
3789 [(set (match_operand:SI 0 "register_operand" "=r")
3790 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3791 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3792 && reload_completed"
3793 "movz{bl|x}\t{%1, %0|%0, %1}"
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")])
3797 ;; For the movzbl case strip only the clobber
3799 [(set (match_operand:SI 0 "register_operand" "")
3800 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3801 (clobber (reg:CC FLAGS_REG))]
3803 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3804 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3806 (zero_extend:SI (match_dup 1)))])
3808 ;; When source and destination does not overlap, clear destination
3809 ;; first and then do the movb
3811 [(set (match_operand:SI 0 "register_operand" "")
3812 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3813 (clobber (reg:CC FLAGS_REG))]
3815 && ANY_QI_REG_P (operands[0])
3816 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3817 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3818 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3819 [(set (match_dup 0) (const_int 0))
3820 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3821 "operands[2] = gen_lowpart (QImode, operands[0]);")
3823 ;; Rest is handled by single and.
3825 [(set (match_operand:SI 0 "register_operand" "")
3826 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3827 (clobber (reg:CC FLAGS_REG))]
3829 && true_regnum (operands[0]) == true_regnum (operands[1])"
3830 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3831 (clobber (reg:CC FLAGS_REG))])]
3834 ;; %%% Kill me once multi-word ops are sane.
3835 (define_expand "zero_extendsidi2"
3836 [(set (match_operand:DI 0 "register_operand" "")
3837 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3842 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3847 (define_insn "zero_extendsidi2_32"
3848 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3850 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3851 (clobber (reg:CC FLAGS_REG))]
3857 movd\t{%1, %0|%0, %1}
3858 movd\t{%1, %0|%0, %1}
3859 %vmovd\t{%1, %0|%0, %1}
3860 %vmovd\t{%1, %0|%0, %1}"
3861 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3862 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3863 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3865 (define_insn "zero_extendsidi2_rex64"
3866 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3868 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3871 mov\t{%k1, %k0|%k0, %k1}
3873 movd\t{%1, %0|%0, %1}
3874 movd\t{%1, %0|%0, %1}
3875 %vmovd\t{%1, %0|%0, %1}
3876 %vmovd\t{%1, %0|%0, %1}"
3877 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3878 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3879 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3882 [(set (match_operand:DI 0 "memory_operand" "")
3883 (zero_extend:DI (match_dup 0)))]
3885 [(set (match_dup 4) (const_int 0))]
3886 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3889 [(set (match_operand:DI 0 "register_operand" "")
3890 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3891 (clobber (reg:CC FLAGS_REG))]
3892 "!TARGET_64BIT && reload_completed
3893 && true_regnum (operands[0]) == true_regnum (operands[1])"
3894 [(set (match_dup 4) (const_int 0))]
3895 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3898 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3899 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3900 (clobber (reg:CC FLAGS_REG))]
3901 "!TARGET_64BIT && reload_completed
3902 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3903 [(set (match_dup 3) (match_dup 1))
3904 (set (match_dup 4) (const_int 0))]
3905 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907 (define_insn "zero_extendhidi2"
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3909 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3912 [(set_attr "type" "imovx")
3913 (set_attr "mode" "DI")])
3915 (define_insn "zero_extendqidi2"
3916 [(set (match_operand:DI 0 "register_operand" "=r")
3917 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3919 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3920 [(set_attr "type" "imovx")
3921 (set_attr "mode" "DI")])
3923 ;; Sign extension instructions
3925 (define_expand "extendsidi2"
3926 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3927 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3928 (clobber (reg:CC FLAGS_REG))
3929 (clobber (match_scratch:SI 2 ""))])]
3934 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3939 (define_insn "*extendsidi2_1"
3940 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3941 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3942 (clobber (reg:CC FLAGS_REG))
3943 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3947 (define_insn "extendsidi2_rex64"
3948 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3949 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3953 movs{lq|x}\t{%1,%0|%0, %1}"
3954 [(set_attr "type" "imovx")
3955 (set_attr "mode" "DI")
3956 (set_attr "prefix_0f" "0")
3957 (set_attr "modrm" "0,1")])
3959 (define_insn "extendhidi2"
3960 [(set (match_operand:DI 0 "register_operand" "=r")
3961 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3963 "movs{wq|x}\t{%1,%0|%0, %1}"
3964 [(set_attr "type" "imovx")
3965 (set_attr "mode" "DI")])
3967 (define_insn "extendqidi2"
3968 [(set (match_operand:DI 0 "register_operand" "=r")
3969 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3971 "movs{bq|x}\t{%1,%0|%0, %1}"
3972 [(set_attr "type" "imovx")
3973 (set_attr "mode" "DI")])
3975 ;; Extend to memory case when source register does die.
3977 [(set (match_operand:DI 0 "memory_operand" "")
3978 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3979 (clobber (reg:CC FLAGS_REG))
3980 (clobber (match_operand:SI 2 "register_operand" ""))]
3982 && dead_or_set_p (insn, operands[1])
3983 && !reg_mentioned_p (operands[1], operands[0]))"
3984 [(set (match_dup 3) (match_dup 1))
3985 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3986 (clobber (reg:CC FLAGS_REG))])
3987 (set (match_dup 4) (match_dup 1))]
3988 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3990 ;; Extend to memory case when source register does not die.
3992 [(set (match_operand:DI 0 "memory_operand" "")
3993 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3994 (clobber (reg:CC FLAGS_REG))
3995 (clobber (match_operand:SI 2 "register_operand" ""))]
3999 split_di (&operands[0], 1, &operands[3], &operands[4]);
4001 emit_move_insn (operands[3], operands[1]);
4003 /* Generate a cltd if possible and doing so it profitable. */
4004 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4005 && true_regnum (operands[1]) == AX_REG
4006 && true_regnum (operands[2]) == DX_REG)
4008 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4012 emit_move_insn (operands[2], operands[1]);
4013 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4015 emit_move_insn (operands[4], operands[2]);
4019 ;; Extend to register case. Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4022 [(set (match_operand:DI 0 "register_operand" "")
4023 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4024 (clobber (reg:CC FLAGS_REG))
4025 (clobber (match_scratch:SI 2 ""))]
4029 split_di (&operands[0], 1, &operands[3], &operands[4]);
4031 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032 emit_move_insn (operands[3], operands[1]);
4034 /* Generate a cltd if possible and doing so it profitable. */
4035 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036 && true_regnum (operands[3]) == AX_REG)
4038 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4042 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4043 emit_move_insn (operands[4], operands[1]);
4045 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4049 (define_insn "extendhisi2"
4050 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4051 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4054 switch (get_attr_prefix_0f (insn))
4057 return "{cwtl|cwde}";
4059 return "movs{wl|x}\t{%1,%0|%0, %1}";
4062 [(set_attr "type" "imovx")
4063 (set_attr "mode" "SI")
4064 (set (attr "prefix_0f")
4065 ;; movsx is short decodable while cwtl is vector decoded.
4066 (if_then_else (and (eq_attr "cpu" "!k6")
4067 (eq_attr "alternative" "0"))
4069 (const_string "1")))
4071 (if_then_else (eq_attr "prefix_0f" "0")
4073 (const_string "1")))])
4075 (define_insn "*extendhisi2_zext"
4076 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4081 switch (get_attr_prefix_0f (insn))
4084 return "{cwtl|cwde}";
4086 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4089 [(set_attr "type" "imovx")
4090 (set_attr "mode" "SI")
4091 (set (attr "prefix_0f")
4092 ;; movsx is short decodable while cwtl is vector decoded.
4093 (if_then_else (and (eq_attr "cpu" "!k6")
4094 (eq_attr "alternative" "0"))
4096 (const_string "1")))
4098 (if_then_else (eq_attr "prefix_0f" "0")
4100 (const_string "1")))])
4102 (define_insn "extendqihi2"
4103 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4104 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4107 switch (get_attr_prefix_0f (insn))
4110 return "{cbtw|cbw}";
4112 return "movs{bw|x}\t{%1,%0|%0, %1}";
4115 [(set_attr "type" "imovx")
4116 (set_attr "mode" "HI")
4117 (set (attr "prefix_0f")
4118 ;; movsx is short decodable while cwtl is vector decoded.
4119 (if_then_else (and (eq_attr "cpu" "!k6")
4120 (eq_attr "alternative" "0"))
4122 (const_string "1")))
4124 (if_then_else (eq_attr "prefix_0f" "0")
4126 (const_string "1")))])
4128 (define_insn "extendqisi2"
4129 [(set (match_operand:SI 0 "register_operand" "=r")
4130 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4132 "movs{bl|x}\t{%1,%0|%0, %1}"
4133 [(set_attr "type" "imovx")
4134 (set_attr "mode" "SI")])
4136 (define_insn "*extendqisi2_zext"
4137 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4141 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4142 [(set_attr "type" "imovx")
4143 (set_attr "mode" "SI")])
4145 ;; Conversions between float and double.
4147 ;; These are all no-ops in the model used for the 80387. So just
4150 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4151 (define_insn "*dummy_extendsfdf2"
4152 [(set (match_operand:DF 0 "push_operand" "=<")
4153 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4158 [(set (match_operand:DF 0 "push_operand" "")
4159 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4161 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4162 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4164 (define_insn "*dummy_extendsfxf2"
4165 [(set (match_operand:XF 0 "push_operand" "=<")
4166 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4171 [(set (match_operand:XF 0 "push_operand" "")
4172 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4174 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4175 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4176 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4179 [(set (match_operand:XF 0 "push_operand" "")
4180 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4182 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4183 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4184 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4186 (define_expand "extendsfdf2"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4188 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4189 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4191 /* ??? Needed for compress_float_constant since all fp constants
4192 are LEGITIMATE_CONSTANT_P. */
4193 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4195 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4196 && standard_80387_constant_p (operands[1]) > 0)
4198 operands[1] = simplify_const_unary_operation
4199 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4200 emit_move_insn_1 (operands[0], operands[1]);
4203 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4207 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4209 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4211 We do the conversion post reload to avoid producing of 128bit spills
4212 that might lead to ICE on 32bit target. The sequence unlikely combine
4215 [(set (match_operand:DF 0 "register_operand" "")
4217 (match_operand:SF 1 "nonimmediate_operand" "")))]
4218 "TARGET_USE_VECTOR_FP_CONVERTS
4219 && optimize_insn_for_speed_p ()
4220 && reload_completed && SSE_REG_P (operands[0])"
4225 (parallel [(const_int 0) (const_int 1)]))))]
4227 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4228 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4229 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4230 Try to avoid move when unpacking can be done in source. */
4231 if (REG_P (operands[1]))
4233 /* If it is unsafe to overwrite upper half of source, we need
4234 to move to destination and unpack there. */
4235 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4236 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4237 && true_regnum (operands[0]) != true_regnum (operands[1]))
4239 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4240 emit_move_insn (tmp, operands[1]);
4243 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4244 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4247 emit_insn (gen_vec_setv4sf_0 (operands[3],
4248 CONST0_RTX (V4SFmode), operands[1]));
4251 (define_insn "*extendsfdf2_mixed"
4252 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4254 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4255 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4257 switch (which_alternative)
4261 return output_387_reg_move (insn, operands);
4264 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4270 [(set_attr "type" "fmov,fmov,ssecvt")
4271 (set_attr "prefix" "orig,orig,maybe_vex")
4272 (set_attr "mode" "SF,XF,DF")])
4274 (define_insn "*extendsfdf2_sse"
4275 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4276 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277 "TARGET_SSE2 && TARGET_SSE_MATH"
4278 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4279 [(set_attr "type" "ssecvt")
4280 (set_attr "prefix" "maybe_vex")
4281 (set_attr "mode" "DF")])
4283 (define_insn "*extendsfdf2_i387"
4284 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4285 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4287 "* return output_387_reg_move (insn, operands);"
4288 [(set_attr "type" "fmov")
4289 (set_attr "mode" "SF,XF")])
4291 (define_expand "extend<mode>xf2"
4292 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4293 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4296 /* ??? Needed for compress_float_constant since all fp constants
4297 are LEGITIMATE_CONSTANT_P. */
4298 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4300 if (standard_80387_constant_p (operands[1]) > 0)
4302 operands[1] = simplify_const_unary_operation
4303 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4304 emit_move_insn_1 (operands[0], operands[1]);
4307 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4311 (define_insn "*extend<mode>xf2_i387"
4312 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4314 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4316 "* return output_387_reg_move (insn, operands);"
4317 [(set_attr "type" "fmov")
4318 (set_attr "mode" "<MODE>,XF")])
4320 ;; %%% This seems bad bad news.
4321 ;; This cannot output into an f-reg because there is no way to be sure
4322 ;; of truncating in that case. Otherwise this is just like a simple move
4323 ;; insn. So we pretend we can output to a reg in order to get better
4324 ;; register preferencing, but we really use a stack slot.
4326 ;; Conversion from DFmode to SFmode.
4328 (define_expand "truncdfsf2"
4329 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4331 (match_operand:DF 1 "nonimmediate_operand" "")))]
4332 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4336 else if (flag_unsafe_math_optimizations)
4340 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4341 rtx temp = assign_386_stack_local (SFmode, slot);
4342 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4347 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4349 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4351 We do the conversion post reload to avoid producing of 128bit spills
4352 that might lead to ICE on 32bit target. The sequence unlikely combine
4355 [(set (match_operand:SF 0 "register_operand" "")
4357 (match_operand:DF 1 "nonimmediate_operand" "")))]
4358 "TARGET_USE_VECTOR_FP_CONVERTS
4359 && optimize_insn_for_speed_p ()
4360 && reload_completed && SSE_REG_P (operands[0])"
4363 (float_truncate:V2SF
4367 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4368 operands[3] = CONST0_RTX (V2SFmode);
4369 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4370 /* Use movsd for loading from memory, unpcklpd for registers.
4371 Try to avoid move when unpacking can be done in source, or SSE3
4372 movddup is available. */
4373 if (REG_P (operands[1]))
4376 && true_regnum (operands[0]) != true_regnum (operands[1])
4377 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4380 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4381 emit_move_insn (tmp, operands[1]);
4384 else if (!TARGET_SSE3)
4385 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4386 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4389 emit_insn (gen_sse2_loadlpd (operands[4],
4390 CONST0_RTX (V2DFmode), operands[1]));
4393 (define_expand "truncdfsf2_with_temp"
4394 [(parallel [(set (match_operand:SF 0 "" "")
4395 (float_truncate:SF (match_operand:DF 1 "" "")))
4396 (clobber (match_operand:SF 2 "" ""))])]
4399 (define_insn "*truncdfsf_fast_mixed"
4400 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4402 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4403 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4405 switch (which_alternative)
4408 return output_387_reg_move (insn, operands);
4410 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4415 [(set_attr "type" "fmov,ssecvt")
4416 (set_attr "prefix" "orig,maybe_vex")
4417 (set_attr "mode" "SF")])
4419 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4420 ;; because nothing we do here is unsafe.
4421 (define_insn "*truncdfsf_fast_sse"
4422 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4424 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4425 "TARGET_SSE2 && TARGET_SSE_MATH"
4426 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4427 [(set_attr "type" "ssecvt")
4428 (set_attr "prefix" "maybe_vex")
4429 (set_attr "mode" "SF")])
4431 (define_insn "*truncdfsf_fast_i387"
4432 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4434 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4435 "TARGET_80387 && flag_unsafe_math_optimizations"
4436 "* return output_387_reg_move (insn, operands);"
4437 [(set_attr "type" "fmov")
4438 (set_attr "mode" "SF")])
4440 (define_insn "*truncdfsf_mixed"
4441 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4443 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4444 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4445 "TARGET_MIX_SSE_I387"
4447 switch (which_alternative)
4450 return output_387_reg_move (insn, operands);
4455 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4460 [(set_attr "type" "fmov,multi,ssecvt")
4461 (set_attr "unit" "*,i387,*")
4462 (set_attr "prefix" "orig,orig,maybe_vex")
4463 (set_attr "mode" "SF")])
4465 (define_insn "*truncdfsf_i387"
4466 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4468 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4469 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4472 switch (which_alternative)
4475 return output_387_reg_move (insn, operands);
4483 [(set_attr "type" "fmov,multi")
4484 (set_attr "unit" "*,i387")
4485 (set_attr "mode" "SF")])
4487 (define_insn "*truncdfsf2_i387_1"
4488 [(set (match_operand:SF 0 "memory_operand" "=m")
4490 (match_operand:DF 1 "register_operand" "f")))]
4492 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4493 && !TARGET_MIX_SSE_I387"
4494 "* return output_387_reg_move (insn, operands);"
4495 [(set_attr "type" "fmov")
4496 (set_attr "mode" "SF")])
4499 [(set (match_operand:SF 0 "register_operand" "")
4501 (match_operand:DF 1 "fp_register_operand" "")))
4502 (clobber (match_operand 2 "" ""))]
4504 [(set (match_dup 2) (match_dup 1))
4505 (set (match_dup 0) (match_dup 2))]
4507 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4510 ;; Conversion from XFmode to {SF,DF}mode
4512 (define_expand "truncxf<mode>2"
4513 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4514 (float_truncate:MODEF
4515 (match_operand:XF 1 "register_operand" "")))
4516 (clobber (match_dup 2))])]
4519 if (flag_unsafe_math_optimizations)
4521 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4522 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4523 if (reg != operands[0])
4524 emit_move_insn (operands[0], reg);
4529 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4530 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4534 (define_insn "*truncxfsf2_mixed"
4535 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4537 (match_operand:XF 1 "register_operand" "f,f")))
4538 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4541 gcc_assert (!which_alternative);
4542 return output_387_reg_move (insn, operands);
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "unit" "*,i387")
4546 (set_attr "mode" "SF")])
4548 (define_insn "*truncxfdf2_mixed"
4549 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4551 (match_operand:XF 1 "register_operand" "f,f")))
4552 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4555 gcc_assert (!which_alternative);
4556 return output_387_reg_move (insn, operands);
4558 [(set_attr "type" "fmov,multi")
4559 (set_attr "unit" "*,i387")
4560 (set_attr "mode" "DF")])
4562 (define_insn "truncxf<mode>2_i387_noop"
4563 [(set (match_operand:MODEF 0 "register_operand" "=f")
4564 (float_truncate:MODEF
4565 (match_operand:XF 1 "register_operand" "f")))]
4566 "TARGET_80387 && flag_unsafe_math_optimizations"
4567 "* return output_387_reg_move (insn, operands);"
4568 [(set_attr "type" "fmov")
4569 (set_attr "mode" "<MODE>")])
4571 (define_insn "*truncxf<mode>2_i387"
4572 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4573 (float_truncate:MODEF
4574 (match_operand:XF 1 "register_operand" "f")))]
4576 "* return output_387_reg_move (insn, operands);"
4577 [(set_attr "type" "fmov")
4578 (set_attr "mode" "<MODE>")])
4581 [(set (match_operand:MODEF 0 "register_operand" "")
4582 (float_truncate:MODEF
4583 (match_operand:XF 1 "register_operand" "")))
4584 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4585 "TARGET_80387 && reload_completed"
4586 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4587 (set (match_dup 0) (match_dup 2))]
4591 [(set (match_operand:MODEF 0 "memory_operand" "")
4592 (float_truncate:MODEF
4593 (match_operand:XF 1 "register_operand" "")))
4594 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4596 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4599 ;; Signed conversion to DImode.
4601 (define_expand "fix_truncxfdi2"
4602 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4603 (fix:DI (match_operand:XF 1 "register_operand" "")))
4604 (clobber (reg:CC FLAGS_REG))])]
4609 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4614 (define_expand "fix_trunc<mode>di2"
4615 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4616 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4617 (clobber (reg:CC FLAGS_REG))])]
4618 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4623 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4626 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4628 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4629 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4630 if (out != operands[0])
4631 emit_move_insn (operands[0], out);
4636 ;; Signed conversion to SImode.
4638 (define_expand "fix_truncxfsi2"
4639 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4640 (fix:SI (match_operand:XF 1 "register_operand" "")))
4641 (clobber (reg:CC FLAGS_REG))])]
4646 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4651 (define_expand "fix_trunc<mode>si2"
4652 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4653 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4654 (clobber (reg:CC FLAGS_REG))])]
4655 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4658 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4660 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4663 if (SSE_FLOAT_MODE_P (<MODE>mode))
4665 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4666 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4667 if (out != operands[0])
4668 emit_move_insn (operands[0], out);
4673 ;; Signed conversion to HImode.
4675 (define_expand "fix_trunc<mode>hi2"
4676 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4677 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4678 (clobber (reg:CC FLAGS_REG))])]
4680 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4684 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4689 ;; Unsigned conversion to SImode.
4691 (define_expand "fixuns_trunc<mode>si2"
4693 [(set (match_operand:SI 0 "register_operand" "")
4695 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4697 (clobber (match_scratch:<ssevecmode> 3 ""))
4698 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4699 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 enum machine_mode mode = <MODE>mode;
4702 enum machine_mode vecmode = <ssevecmode>mode;
4703 REAL_VALUE_TYPE TWO31r;
4706 if (optimize_insn_for_size_p ())
4709 real_ldexp (&TWO31r, &dconst1, 31);
4710 two31 = const_double_from_real_value (TWO31r, mode);
4711 two31 = ix86_build_const_vector (mode, true, two31);
4712 operands[2] = force_reg (vecmode, two31);
4715 (define_insn_and_split "*fixuns_trunc<mode>_1"
4716 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4718 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4719 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4720 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4721 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4722 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4723 && optimize_function_for_speed_p (cfun)"
4725 "&& reload_completed"
4728 ix86_split_convert_uns_si_sse (operands);
4732 ;; Unsigned conversion to HImode.
4733 ;; Without these patterns, we'll try the unsigned SI conversion which
4734 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4736 (define_expand "fixuns_trunc<mode>hi2"
4738 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4739 (set (match_operand:HI 0 "nonimmediate_operand" "")
4740 (subreg:HI (match_dup 2) 0))]
4741 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4742 "operands[2] = gen_reg_rtx (SImode);")
4744 ;; When SSE is available, it is always faster to use it!
4745 (define_insn "fix_trunc<mode>di_sse"
4746 [(set (match_operand:DI 0 "register_operand" "=r,r")
4747 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4748 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4749 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4750 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4751 [(set_attr "type" "sseicvt")
4752 (set_attr "prefix" "maybe_vex")
4753 (set_attr "mode" "<MODE>")
4754 (set_attr "athlon_decode" "double,vector")
4755 (set_attr "amdfam10_decode" "double,double")])
4757 (define_insn "fix_trunc<mode>si_sse"
4758 [(set (match_operand:SI 0 "register_operand" "=r,r")
4759 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4760 "SSE_FLOAT_MODE_P (<MODE>mode)
4761 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4762 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4763 [(set_attr "type" "sseicvt")
4764 (set_attr "prefix" "maybe_vex")
4765 (set_attr "mode" "<MODE>")
4766 (set_attr "athlon_decode" "double,vector")
4767 (set_attr "amdfam10_decode" "double,double")])
4769 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4771 [(set (match_operand:MODEF 0 "register_operand" "")
4772 (match_operand:MODEF 1 "memory_operand" ""))
4773 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4774 (fix:SSEMODEI24 (match_dup 0)))]
4775 "TARGET_SHORTEN_X87_SSE
4776 && peep2_reg_dead_p (2, operands[0])"
4777 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4780 ;; Avoid vector decoded forms of the instruction.
4782 [(match_scratch:DF 2 "Y2")
4783 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4784 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4785 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4786 [(set (match_dup 2) (match_dup 1))
4787 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4791 [(match_scratch:SF 2 "x")
4792 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4793 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4794 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4795 [(set (match_dup 2) (match_dup 1))
4796 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4799 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4800 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4801 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4802 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4805 && (TARGET_64BIT || <MODE>mode != DImode))
4807 && !(reload_completed || reload_in_progress)"
4812 if (memory_operand (operands[0], VOIDmode))
4813 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4816 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4817 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4823 [(set_attr "type" "fisttp")
4824 (set_attr "mode" "<MODE>")])
4826 (define_insn "fix_trunc<mode>_i387_fisttp"
4827 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4828 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4829 (clobber (match_scratch:XF 2 "=&1f"))]
4830 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4832 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4833 && (TARGET_64BIT || <MODE>mode != DImode))
4834 && TARGET_SSE_MATH)"
4835 "* return output_fix_trunc (insn, operands, 1);"
4836 [(set_attr "type" "fisttp")
4837 (set_attr "mode" "<MODE>")])
4839 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4840 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4841 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4842 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4843 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4844 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4846 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4847 && (TARGET_64BIT || <MODE>mode != DImode))
4848 && TARGET_SSE_MATH)"
4850 [(set_attr "type" "fisttp")
4851 (set_attr "mode" "<MODE>")])
4854 [(set (match_operand:X87MODEI 0 "register_operand" "")
4855 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4856 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4857 (clobber (match_scratch 3 ""))]
4859 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4860 (clobber (match_dup 3))])
4861 (set (match_dup 0) (match_dup 2))]
4865 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4866 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4867 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4868 (clobber (match_scratch 3 ""))]
4870 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4871 (clobber (match_dup 3))])]
4874 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4875 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4876 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4877 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4878 ;; function in i386.c.
4879 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4880 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4881 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4882 (clobber (reg:CC FLAGS_REG))]
4883 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4885 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4886 && (TARGET_64BIT || <MODE>mode != DImode))
4887 && !(reload_completed || reload_in_progress)"
4892 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4894 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4895 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4896 if (memory_operand (operands[0], VOIDmode))
4897 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4898 operands[2], operands[3]));
4901 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4902 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4903 operands[2], operands[3],
4908 [(set_attr "type" "fistp")
4909 (set_attr "i387_cw" "trunc")
4910 (set_attr "mode" "<MODE>")])
4912 (define_insn "fix_truncdi_i387"
4913 [(set (match_operand:DI 0 "memory_operand" "=m")
4914 (fix:DI (match_operand 1 "register_operand" "f")))
4915 (use (match_operand:HI 2 "memory_operand" "m"))
4916 (use (match_operand:HI 3 "memory_operand" "m"))
4917 (clobber (match_scratch:XF 4 "=&1f"))]
4918 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4920 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4921 "* return output_fix_trunc (insn, operands, 0);"
4922 [(set_attr "type" "fistp")
4923 (set_attr "i387_cw" "trunc")
4924 (set_attr "mode" "DI")])
4926 (define_insn "fix_truncdi_i387_with_temp"
4927 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4928 (fix:DI (match_operand 1 "register_operand" "f,f")))
4929 (use (match_operand:HI 2 "memory_operand" "m,m"))
4930 (use (match_operand:HI 3 "memory_operand" "m,m"))
4931 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4932 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4933 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937 [(set_attr "type" "fistp")
4938 (set_attr "i387_cw" "trunc")
4939 (set_attr "mode" "DI")])
4942 [(set (match_operand:DI 0 "register_operand" "")
4943 (fix:DI (match_operand 1 "register_operand" "")))
4944 (use (match_operand:HI 2 "memory_operand" ""))
4945 (use (match_operand:HI 3 "memory_operand" ""))
4946 (clobber (match_operand:DI 4 "memory_operand" ""))
4947 (clobber (match_scratch 5 ""))]
4949 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4952 (clobber (match_dup 5))])
4953 (set (match_dup 0) (match_dup 4))]
4957 [(set (match_operand:DI 0 "memory_operand" "")
4958 (fix:DI (match_operand 1 "register_operand" "")))
4959 (use (match_operand:HI 2 "memory_operand" ""))
4960 (use (match_operand:HI 3 "memory_operand" ""))
4961 (clobber (match_operand:DI 4 "memory_operand" ""))
4962 (clobber (match_scratch 5 ""))]
4964 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4967 (clobber (match_dup 5))])]
4970 (define_insn "fix_trunc<mode>_i387"
4971 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4972 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4973 (use (match_operand:HI 2 "memory_operand" "m"))
4974 (use (match_operand:HI 3 "memory_operand" "m"))]
4975 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4978 "* return output_fix_trunc (insn, operands, 0);"
4979 [(set_attr "type" "fistp")
4980 (set_attr "i387_cw" "trunc")
4981 (set_attr "mode" "<MODE>")])
4983 (define_insn "fix_trunc<mode>_i387_with_temp"
4984 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4985 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4986 (use (match_operand:HI 2 "memory_operand" "m,m"))
4987 (use (match_operand:HI 3 "memory_operand" "m,m"))
4988 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4989 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993 [(set_attr "type" "fistp")
4994 (set_attr "i387_cw" "trunc")
4995 (set_attr "mode" "<MODE>")])
4998 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4999 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5000 (use (match_operand:HI 2 "memory_operand" ""))
5001 (use (match_operand:HI 3 "memory_operand" ""))
5002 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5004 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5006 (use (match_dup 3))])
5007 (set (match_dup 0) (match_dup 4))]
5011 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5012 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5013 (use (match_operand:HI 2 "memory_operand" ""))
5014 (use (match_operand:HI 3 "memory_operand" ""))
5015 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5017 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5019 (use (match_dup 3))])]
5022 (define_insn "x86_fnstcw_1"
5023 [(set (match_operand:HI 0 "memory_operand" "=m")
5024 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5027 [(set_attr "length" "2")
5028 (set_attr "mode" "HI")
5029 (set_attr "unit" "i387")])
5031 (define_insn "x86_fldcw_1"
5032 [(set (reg:HI FPCR_REG)
5033 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5036 [(set_attr "length" "2")
5037 (set_attr "mode" "HI")
5038 (set_attr "unit" "i387")
5039 (set_attr "athlon_decode" "vector")
5040 (set_attr "amdfam10_decode" "vector")])
5042 ;; Conversion between fixed point and floating point.
5044 ;; Even though we only accept memory inputs, the backend _really_
5045 ;; wants to be able to do this between registers.
5047 (define_expand "floathi<mode>2"
5048 [(set (match_operand:X87MODEF 0 "register_operand" "")
5049 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052 || TARGET_MIX_SSE_I387)"
5055 ;; Pre-reload splitter to add memory clobber to the pattern.
5056 (define_insn_and_split "*floathi<mode>2_1"
5057 [(set (match_operand:X87MODEF 0 "register_operand" "")
5058 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5061 || TARGET_MIX_SSE_I387)
5062 && !(reload_completed || reload_in_progress)"
5065 [(parallel [(set (match_dup 0)
5066 (float:X87MODEF (match_dup 1)))
5067 (clobber (match_dup 2))])]
5068 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5070 (define_insn "*floathi<mode>2_i387_with_temp"
5071 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5072 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5073 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5076 || TARGET_MIX_SSE_I387)"
5078 [(set_attr "type" "fmov,multi")
5079 (set_attr "mode" "<MODE>")
5080 (set_attr "unit" "*,i387")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*floathi<mode>2_i387"
5084 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5085 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5088 || TARGET_MIX_SSE_I387)"
5090 [(set_attr "type" "fmov")
5091 (set_attr "mode" "<MODE>")
5092 (set_attr "fp_int_src" "true")])
5095 [(set (match_operand:X87MODEF 0 "register_operand" "")
5096 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5097 (clobber (match_operand:HI 2 "memory_operand" ""))]
5099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5100 || TARGET_MIX_SSE_I387)
5101 && reload_completed"
5102 [(set (match_dup 2) (match_dup 1))
5103 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5107 [(set (match_operand:X87MODEF 0 "register_operand" "")
5108 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5109 (clobber (match_operand:HI 2 "memory_operand" ""))]
5111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5112 || TARGET_MIX_SSE_I387)
5113 && reload_completed"
5114 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5117 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5118 [(set (match_operand:X87MODEF 0 "register_operand" "")
5120 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5122 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5126 ;; Pre-reload splitter to add memory clobber to the pattern.
5127 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5128 [(set (match_operand:X87MODEF 0 "register_operand" "")
5129 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5131 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5132 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5133 || TARGET_MIX_SSE_I387))
5134 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5135 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5136 && ((<SSEMODEI24:MODE>mode == SImode
5137 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5138 && optimize_function_for_speed_p (cfun)
5139 && flag_trapping_math)
5140 || !(TARGET_INTER_UNIT_CONVERSIONS
5141 || optimize_function_for_size_p (cfun)))))
5142 && !(reload_completed || reload_in_progress)"
5145 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5146 (clobber (match_dup 2))])]
5148 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5150 /* Avoid store forwarding (partial memory) stall penalty
5151 by passing DImode value through XMM registers. */
5152 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5153 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5154 && optimize_function_for_speed_p (cfun))
5156 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5163 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5164 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5166 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5167 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5168 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5169 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5171 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5172 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5173 (set_attr "unit" "*,i387,*,*,*")
5174 (set_attr "athlon_decode" "*,*,double,direct,double")
5175 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5176 (set_attr "fp_int_src" "true")])
5178 (define_insn "*floatsi<mode>2_vector_mixed"
5179 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5180 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5181 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5182 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5186 [(set_attr "type" "fmov,sseicvt")
5187 (set_attr "mode" "<MODE>,<ssevecmode>")
5188 (set_attr "unit" "i387,*")
5189 (set_attr "athlon_decode" "*,direct")
5190 (set_attr "amdfam10_decode" "*,double")
5191 (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5194 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5196 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5197 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5198 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5201 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5202 (set_attr "mode" "<MODEF:MODE>")
5203 (set_attr "unit" "*,i387,*,*")
5204 (set_attr "athlon_decode" "*,*,double,direct")
5205 (set_attr "amdfam10_decode" "*,*,vector,double")
5206 (set_attr "fp_int_src" "true")])
5209 [(set (match_operand:MODEF 0 "register_operand" "")
5210 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5214 && TARGET_INTER_UNIT_CONVERSIONS
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (operands[0])))"
5219 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5225 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5228 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5230 && (SSE_REG_P (operands[0])
5231 || (GET_CODE (operands[0]) == SUBREG
5232 && SSE_REG_P (operands[0])))"
5233 [(set (match_dup 2) (match_dup 1))
5234 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5238 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5240 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5241 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5246 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5247 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5248 [(set_attr "type" "fmov,sseicvt,sseicvt")
5249 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5250 (set_attr "mode" "<MODEF:MODE>")
5251 (set_attr "unit" "i387,*,*")
5252 (set_attr "athlon_decode" "*,double,direct")
5253 (set_attr "amdfam10_decode" "*,vector,double")
5254 (set_attr "fp_int_src" "true")])
5256 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5257 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5259 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5260 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5261 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5262 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5265 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266 [(set_attr "type" "fmov,sseicvt")
5267 (set_attr "prefix" "orig,maybe_vex")
5268 (set_attr "mode" "<MODEF:MODE>")
5269 (set_attr "athlon_decode" "*,direct")
5270 (set_attr "amdfam10_decode" "*,double")
5271 (set_attr "fp_int_src" "true")])
5273 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5274 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5276 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5277 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5278 "TARGET_SSE2 && TARGET_SSE_MATH
5279 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281 [(set_attr "type" "sseicvt")
5282 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5283 (set_attr "athlon_decode" "double,direct,double")
5284 (set_attr "amdfam10_decode" "vector,double,double")
5285 (set_attr "fp_int_src" "true")])
5287 (define_insn "*floatsi<mode>2_vector_sse"
5288 [(set (match_operand:MODEF 0 "register_operand" "=x")
5289 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5290 "TARGET_SSE2 && TARGET_SSE_MATH
5291 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5293 [(set_attr "type" "sseicvt")
5294 (set_attr "mode" "<MODE>")
5295 (set_attr "athlon_decode" "direct")
5296 (set_attr "amdfam10_decode" "double")
5297 (set_attr "fp_int_src" "true")])
5300 [(set (match_operand:MODEF 0 "register_operand" "")
5301 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5302 (clobber (match_operand:SI 2 "memory_operand" ""))]
5303 "TARGET_SSE2 && TARGET_SSE_MATH
5304 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306 && (SSE_REG_P (operands[0])
5307 || (GET_CODE (operands[0]) == SUBREG
5308 && SSE_REG_P (operands[0])))"
5311 rtx op1 = operands[1];
5313 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315 if (GET_CODE (op1) == SUBREG)
5316 op1 = SUBREG_REG (op1);
5318 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[1]));
5324 /* We can ignore possible trapping value in the
5325 high part of SSE register for non-trapping math. */
5326 else if (SSE_REG_P (op1) && !flag_trapping_math)
5327 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5330 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5331 emit_move_insn (operands[2], operands[1]);
5332 emit_insn (gen_sse2_loadld (operands[4],
5333 CONST0_RTX (V4SImode), operands[2]));
5336 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5341 [(set (match_operand:MODEF 0 "register_operand" "")
5342 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5343 (clobber (match_operand:SI 2 "memory_operand" ""))]
5344 "TARGET_SSE2 && TARGET_SSE_MATH
5345 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5347 && (SSE_REG_P (operands[0])
5348 || (GET_CODE (operands[0]) == SUBREG
5349 && SSE_REG_P (operands[0])))"
5352 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5354 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5356 emit_insn (gen_sse2_loadld (operands[4],
5357 CONST0_RTX (V4SImode), operands[1]));
5359 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5364 [(set (match_operand:MODEF 0 "register_operand" "")
5365 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5366 "TARGET_SSE2 && TARGET_SSE_MATH
5367 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5369 && (SSE_REG_P (operands[0])
5370 || (GET_CODE (operands[0]) == SUBREG
5371 && SSE_REG_P (operands[0])))"
5374 rtx op1 = operands[1];
5376 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5378 if (GET_CODE (op1) == SUBREG)
5379 op1 = SUBREG_REG (op1);
5381 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5383 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5384 emit_insn (gen_sse2_loadld (operands[4],
5385 CONST0_RTX (V4SImode), operands[1]));
5387 /* We can ignore possible trapping value in the
5388 high part of SSE register for non-trapping math. */
5389 else if (SSE_REG_P (op1) && !flag_trapping_math)
5390 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5394 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5399 [(set (match_operand:MODEF 0 "register_operand" "")
5400 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5401 "TARGET_SSE2 && TARGET_SSE_MATH
5402 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5404 && (SSE_REG_P (operands[0])
5405 || (GET_CODE (operands[0]) == SUBREG
5406 && SSE_REG_P (operands[0])))"
5409 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5413 emit_insn (gen_sse2_loadld (operands[4],
5414 CONST0_RTX (V4SImode), operands[1]));
5416 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5421 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5424 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5425 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5428 [(set_attr "type" "sseicvt")
5429 (set_attr "mode" "<MODEF:MODE>")
5430 (set_attr "athlon_decode" "double,direct")
5431 (set_attr "amdfam10_decode" "vector,double")
5432 (set_attr "fp_int_src" "true")])
5434 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5435 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5437 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5438 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5439 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5440 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5441 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5442 [(set_attr "type" "sseicvt")
5443 (set_attr "prefix" "maybe_vex")
5444 (set_attr "mode" "<MODEF:MODE>")
5445 (set_attr "athlon_decode" "double,direct")
5446 (set_attr "amdfam10_decode" "vector,double")
5447 (set_attr "fp_int_src" "true")])
5450 [(set (match_operand:MODEF 0 "register_operand" "")
5451 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5452 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5453 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5454 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5455 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5457 && (SSE_REG_P (operands[0])
5458 || (GET_CODE (operands[0]) == SUBREG
5459 && SSE_REG_P (operands[0])))"
5460 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5463 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5464 [(set (match_operand:MODEF 0 "register_operand" "=x")
5466 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5467 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5469 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5470 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5471 [(set_attr "type" "sseicvt")
5472 (set_attr "prefix" "maybe_vex")
5473 (set_attr "mode" "<MODEF:MODE>")
5474 (set_attr "athlon_decode" "direct")
5475 (set_attr "amdfam10_decode" "double")
5476 (set_attr "fp_int_src" "true")])
5479 [(set (match_operand:MODEF 0 "register_operand" "")
5480 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5481 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5482 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5483 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5484 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486 && (SSE_REG_P (operands[0])
5487 || (GET_CODE (operands[0]) == SUBREG
5488 && SSE_REG_P (operands[0])))"
5489 [(set (match_dup 2) (match_dup 1))
5490 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5494 [(set (match_operand:MODEF 0 "register_operand" "")
5495 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5496 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5497 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5498 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && (SSE_REG_P (operands[0])
5501 || (GET_CODE (operands[0]) == SUBREG
5502 && SSE_REG_P (operands[0])))"
5503 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5506 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5507 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5510 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5515 [(set_attr "type" "fmov,multi")
5516 (set_attr "mode" "<X87MODEF:MODE>")
5517 (set_attr "unit" "*,i387")
5518 (set_attr "fp_int_src" "true")])
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5526 [(set_attr "type" "fmov")
5527 (set_attr "mode" "<X87MODEF:MODE>")
5528 (set_attr "fp_int_src" "true")])
5531 [(set (match_operand:X87MODEF 0 "register_operand" "")
5532 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5533 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5536 && FP_REG_P (operands[0])"
5537 [(set (match_dup 2) (match_dup 1))
5538 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5542 [(set (match_operand:X87MODEF 0 "register_operand" "")
5543 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5547 && FP_REG_P (operands[0])"
5548 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5551 ;; Avoid store forwarding (partial memory) stall penalty
5552 ;; by passing DImode value through XMM registers. */
5554 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5555 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5558 (clobber (match_scratch:V4SI 3 "=X,x"))
5559 (clobber (match_scratch:V4SI 4 "=X,x"))
5560 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5561 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5562 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5564 [(set_attr "type" "multi")
5565 (set_attr "mode" "<X87MODEF:MODE>")
5566 (set_attr "unit" "i387")
5567 (set_attr "fp_int_src" "true")])
5570 [(set (match_operand:X87MODEF 0 "register_operand" "")
5571 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5572 (clobber (match_scratch:V4SI 3 ""))
5573 (clobber (match_scratch:V4SI 4 ""))
5574 (clobber (match_operand:DI 2 "memory_operand" ""))]
5575 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5576 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5578 && FP_REG_P (operands[0])"
5579 [(set (match_dup 2) (match_dup 3))
5580 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5582 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5583 Assemble the 64-bit DImode value in an xmm register. */
5584 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5585 gen_rtx_SUBREG (SImode, operands[1], 0)));
5586 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5587 gen_rtx_SUBREG (SImode, operands[1], 4)));
5588 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5590 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5594 [(set (match_operand:X87MODEF 0 "register_operand" "")
5595 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5596 (clobber (match_scratch:V4SI 3 ""))
5597 (clobber (match_scratch:V4SI 4 ""))
5598 (clobber (match_operand:DI 2 "memory_operand" ""))]
5599 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5600 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5602 && FP_REG_P (operands[0])"
5603 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5606 ;; Avoid store forwarding (partial memory) stall penalty by extending
5607 ;; SImode value to DImode through XMM register instead of pushing two
5608 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5609 ;; targets benefit from this optimization. Also note that fild
5610 ;; loads from memory only.
5612 (define_insn "*floatunssi<mode>2_1"
5613 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5614 (unsigned_float:X87MODEF
5615 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5616 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5617 (clobber (match_scratch:SI 3 "=X,x"))]
5619 && TARGET_80387 && TARGET_SSE"
5621 [(set_attr "type" "multi")
5622 (set_attr "mode" "<MODE>")])
5625 [(set (match_operand:X87MODEF 0 "register_operand" "")
5626 (unsigned_float:X87MODEF
5627 (match_operand:SI 1 "register_operand" "")))
5628 (clobber (match_operand:DI 2 "memory_operand" ""))
5629 (clobber (match_scratch:SI 3 ""))]
5631 && TARGET_80387 && TARGET_SSE
5632 && reload_completed"
5633 [(set (match_dup 2) (match_dup 1))
5635 (float:X87MODEF (match_dup 2)))]
5636 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5639 [(set (match_operand:X87MODEF 0 "register_operand" "")
5640 (unsigned_float:X87MODEF
5641 (match_operand:SI 1 "memory_operand" "")))
5642 (clobber (match_operand:DI 2 "memory_operand" ""))
5643 (clobber (match_scratch:SI 3 ""))]
5645 && TARGET_80387 && TARGET_SSE
5646 && reload_completed"
5647 [(set (match_dup 2) (match_dup 3))
5649 (float:X87MODEF (match_dup 2)))]
5651 emit_move_insn (operands[3], operands[1]);
5652 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5655 (define_expand "floatunssi<mode>2"
5657 [(set (match_operand:X87MODEF 0 "register_operand" "")
5658 (unsigned_float:X87MODEF
5659 (match_operand:SI 1 "nonimmediate_operand" "")))
5660 (clobber (match_dup 2))
5661 (clobber (match_scratch:SI 3 ""))])]
5663 && ((TARGET_80387 && TARGET_SSE)
5664 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5666 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5668 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5673 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5674 operands[2] = assign_386_stack_local (DImode, slot);
5678 (define_expand "floatunsdisf2"
5679 [(use (match_operand:SF 0 "register_operand" ""))
5680 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5681 "TARGET_64BIT && TARGET_SSE_MATH"
5682 "x86_emit_floatuns (operands); DONE;")
5684 (define_expand "floatunsdidf2"
5685 [(use (match_operand:DF 0 "register_operand" ""))
5686 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5687 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5688 && TARGET_SSE2 && TARGET_SSE_MATH"
5691 x86_emit_floatuns (operands);
5693 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5699 ;; %%% splits for addditi3
5701 (define_expand "addti3"
5702 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5703 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5704 (match_operand:TI 2 "x86_64_general_operand" "")))]
5706 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5708 (define_insn "*addti3_1"
5709 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5710 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5711 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5712 (clobber (reg:CC FLAGS_REG))]
5713 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5717 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5718 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5719 (match_operand:TI 2 "x86_64_general_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "TARGET_64BIT && reload_completed"
5722 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5724 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5725 (parallel [(set (match_dup 3)
5726 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5729 (clobber (reg:CC FLAGS_REG))])]
5730 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5732 ;; %%% splits for addsidi3
5733 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5734 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5735 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5737 (define_expand "adddi3"
5738 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5739 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5740 (match_operand:DI 2 "x86_64_general_operand" "")))]
5742 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5744 (define_insn "*adddi3_1"
5745 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5746 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5747 (match_operand:DI 2 "general_operand" "roiF,riF")))
5748 (clobber (reg:CC FLAGS_REG))]
5749 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5753 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5755 (match_operand:DI 2 "general_operand" "")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "!TARGET_64BIT && reload_completed"
5758 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5760 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5761 (parallel [(set (match_dup 3)
5762 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5765 (clobber (reg:CC FLAGS_REG))])]
5766 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5768 (define_insn "adddi3_carry_rex64"
5769 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5770 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5771 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5772 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775 "adc{q}\t{%2, %0|%0, %2}"
5776 [(set_attr "type" "alu")
5777 (set_attr "pent_pair" "pu")
5778 (set_attr "mode" "DI")])
5780 (define_insn "*adddi3_cc_rex64"
5781 [(set (reg:CC FLAGS_REG)
5782 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5783 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5785 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786 (plus:DI (match_dup 1) (match_dup 2)))]
5787 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5788 "add{q}\t{%2, %0|%0, %2}"
5789 [(set_attr "type" "alu")
5790 (set_attr "mode" "DI")])
5792 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5793 [(set (reg:CCC FLAGS_REG)
5796 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5797 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5799 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5800 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5801 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5802 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5803 [(set_attr "type" "alu")
5804 (set_attr "mode" "<MODE>")])
5806 (define_insn "*add<mode>3_cconly_overflow"
5807 [(set (reg:CCC FLAGS_REG)
5809 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5810 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5812 (clobber (match_scratch:SWI 0 "=<r>"))]
5813 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5814 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5815 [(set_attr "type" "alu")
5816 (set_attr "mode" "<MODE>")])
5818 (define_insn "*sub<mode>3_cconly_overflow"
5819 [(set (reg:CCC FLAGS_REG)
5821 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5822 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5825 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5826 [(set_attr "type" "icmp")
5827 (set_attr "mode" "<MODE>")])
5829 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5830 [(set (reg:CCC FLAGS_REG)
5832 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5833 (match_operand:SI 2 "general_operand" "g"))
5835 (set (match_operand:DI 0 "register_operand" "=r")
5836 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5837 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5838 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5839 [(set_attr "type" "alu")
5840 (set_attr "mode" "SI")])
5842 (define_insn "addqi3_carry"
5843 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5844 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5845 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5846 (match_operand:QI 2 "general_operand" "qn,qm")))
5847 (clobber (reg:CC FLAGS_REG))]
5848 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5849 "adc{b}\t{%2, %0|%0, %2}"
5850 [(set_attr "type" "alu")
5851 (set_attr "pent_pair" "pu")
5852 (set_attr "mode" "QI")])
5854 (define_insn "addhi3_carry"
5855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5856 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5857 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5858 (match_operand:HI 2 "general_operand" "rn,rm")))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5861 "adc{w}\t{%2, %0|%0, %2}"
5862 [(set_attr "type" "alu")
5863 (set_attr "pent_pair" "pu")
5864 (set_attr "mode" "HI")])
5866 (define_insn "addsi3_carry"
5867 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5868 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5869 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5870 (match_operand:SI 2 "general_operand" "ri,rm")))
5871 (clobber (reg:CC FLAGS_REG))]
5872 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5873 "adc{l}\t{%2, %0|%0, %2}"
5874 [(set_attr "type" "alu")
5875 (set_attr "pent_pair" "pu")
5876 (set_attr "mode" "SI")])
5878 (define_insn "*addsi3_carry_zext"
5879 [(set (match_operand:DI 0 "register_operand" "=r")
5881 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5882 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5883 (match_operand:SI 2 "general_operand" "g"))))
5884 (clobber (reg:CC FLAGS_REG))]
5885 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886 "adc{l}\t{%2, %k0|%k0, %2}"
5887 [(set_attr "type" "alu")
5888 (set_attr "pent_pair" "pu")
5889 (set_attr "mode" "SI")])
5891 (define_insn "*addsi3_cc"
5892 [(set (reg:CC FLAGS_REG)
5893 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5894 (match_operand:SI 2 "general_operand" "ri,rm")]
5896 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5897 (plus:SI (match_dup 1) (match_dup 2)))]
5898 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5899 "add{l}\t{%2, %0|%0, %2}"
5900 [(set_attr "type" "alu")
5901 (set_attr "mode" "SI")])
5903 (define_insn "addqi3_cc"
5904 [(set (reg:CC FLAGS_REG)
5905 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5906 (match_operand:QI 2 "general_operand" "qn,qm")]
5908 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5909 (plus:QI (match_dup 1) (match_dup 2)))]
5910 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5911 "add{b}\t{%2, %0|%0, %2}"
5912 [(set_attr "type" "alu")
5913 (set_attr "mode" "QI")])
5915 (define_expand "addsi3"
5916 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5917 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5918 (match_operand:SI 2 "general_operand" "")))]
5920 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5922 (define_insn "*lea_1"
5923 [(set (match_operand:SI 0 "register_operand" "=r")
5924 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5926 "lea{l}\t{%a1, %0|%0, %a1}"
5927 [(set_attr "type" "lea")
5928 (set_attr "mode" "SI")])
5930 (define_insn "*lea_1_rex64"
5931 [(set (match_operand:SI 0 "register_operand" "=r")
5932 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5934 "lea{l}\t{%a1, %0|%0, %a1}"
5935 [(set_attr "type" "lea")
5936 (set_attr "mode" "SI")])
5938 (define_insn "*lea_1_zext"
5939 [(set (match_operand:DI 0 "register_operand" "=r")
5941 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5943 "lea{l}\t{%a1, %k0|%k0, %a1}"
5944 [(set_attr "type" "lea")
5945 (set_attr "mode" "SI")])
5947 (define_insn "*lea_2_rex64"
5948 [(set (match_operand:DI 0 "register_operand" "=r")
5949 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5951 "lea{q}\t{%a1, %0|%0, %a1}"
5952 [(set_attr "type" "lea")
5953 (set_attr "mode" "DI")])
5955 ;; The lea patterns for non-Pmodes needs to be matched by several
5956 ;; insns converted to real lea by splitters.
5958 (define_insn_and_split "*lea_general_1"
5959 [(set (match_operand 0 "register_operand" "=r")
5960 (plus (plus (match_operand 1 "index_register_operand" "l")
5961 (match_operand 2 "register_operand" "r"))
5962 (match_operand 3 "immediate_operand" "i")))]
5963 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5964 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5965 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5968 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5969 || GET_MODE (operands[3]) == VOIDmode)"
5971 "&& reload_completed"
5975 operands[0] = gen_lowpart (SImode, operands[0]);
5976 operands[1] = gen_lowpart (Pmode, operands[1]);
5977 operands[2] = gen_lowpart (Pmode, operands[2]);
5978 operands[3] = gen_lowpart (Pmode, operands[3]);
5979 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5981 if (Pmode != SImode)
5982 pat = gen_rtx_SUBREG (SImode, pat, 0);
5983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5986 [(set_attr "type" "lea")
5987 (set_attr "mode" "SI")])
5989 (define_insn_and_split "*lea_general_1_zext"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5992 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5993 (match_operand:SI 2 "register_operand" "r"))
5994 (match_operand:SI 3 "immediate_operand" "i"))))]
5997 "&& reload_completed"
5999 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6001 (match_dup 3)) 0)))]
6003 operands[1] = gen_lowpart (Pmode, operands[1]);
6004 operands[2] = gen_lowpart (Pmode, operands[2]);
6005 operands[3] = gen_lowpart (Pmode, operands[3]);
6007 [(set_attr "type" "lea")
6008 (set_attr "mode" "SI")])
6010 (define_insn_and_split "*lea_general_2"
6011 [(set (match_operand 0 "register_operand" "=r")
6012 (plus (mult (match_operand 1 "index_register_operand" "l")
6013 (match_operand 2 "const248_operand" "i"))
6014 (match_operand 3 "nonmemory_operand" "ri")))]
6015 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6016 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6017 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6018 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6019 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6020 || GET_MODE (operands[3]) == VOIDmode)"
6022 "&& reload_completed"
6026 operands[0] = gen_lowpart (SImode, operands[0]);
6027 operands[1] = gen_lowpart (Pmode, operands[1]);
6028 operands[3] = gen_lowpart (Pmode, operands[3]);
6029 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6031 if (Pmode != SImode)
6032 pat = gen_rtx_SUBREG (SImode, pat, 0);
6033 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6036 [(set_attr "type" "lea")
6037 (set_attr "mode" "SI")])
6039 (define_insn_and_split "*lea_general_2_zext"
6040 [(set (match_operand:DI 0 "register_operand" "=r")
6042 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6043 (match_operand:SI 2 "const248_operand" "n"))
6044 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6047 "&& reload_completed"
6049 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6051 (match_dup 3)) 0)))]
6053 operands[1] = gen_lowpart (Pmode, operands[1]);
6054 operands[3] = gen_lowpart (Pmode, operands[3]);
6056 [(set_attr "type" "lea")
6057 (set_attr "mode" "SI")])
6059 (define_insn_and_split "*lea_general_3"
6060 [(set (match_operand 0 "register_operand" "=r")
6061 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6062 (match_operand 2 "const248_operand" "i"))
6063 (match_operand 3 "register_operand" "r"))
6064 (match_operand 4 "immediate_operand" "i")))]
6065 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6066 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6067 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6068 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6069 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6071 "&& reload_completed"
6075 operands[0] = gen_lowpart (SImode, operands[0]);
6076 operands[1] = gen_lowpart (Pmode, operands[1]);
6077 operands[3] = gen_lowpart (Pmode, operands[3]);
6078 operands[4] = gen_lowpart (Pmode, operands[4]);
6079 pat = gen_rtx_PLUS (Pmode,
6080 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6084 if (Pmode != SImode)
6085 pat = gen_rtx_SUBREG (SImode, pat, 0);
6086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6089 [(set_attr "type" "lea")
6090 (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_3_zext"
6093 [(set (match_operand:DI 0 "register_operand" "=r")
6095 (plus:SI (plus:SI (mult:SI
6096 (match_operand:SI 1 "index_register_operand" "l")
6097 (match_operand:SI 2 "const248_operand" "n"))
6098 (match_operand:SI 3 "register_operand" "r"))
6099 (match_operand:SI 4 "immediate_operand" "i"))))]
6102 "&& reload_completed"
6104 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6107 (match_dup 4)) 0)))]
6109 operands[1] = gen_lowpart (Pmode, operands[1]);
6110 operands[3] = gen_lowpart (Pmode, operands[3]);
6111 operands[4] = gen_lowpart (Pmode, operands[4]);
6113 [(set_attr "type" "lea")
6114 (set_attr "mode" "SI")])
6116 (define_insn "*adddi_1_rex64"
6117 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6118 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6119 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6120 (clobber (reg:CC FLAGS_REG))]
6121 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123 switch (get_attr_type (insn))
6126 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6127 return "lea{q}\t{%a2, %0|%0, %a2}";
6130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6131 if (operands[2] == const1_rtx)
6132 return "inc{q}\t%0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{q}\t%0";
6140 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6143 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6144 if (CONST_INT_P (operands[2])
6145 /* Avoid overflows. */
6146 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6147 && (INTVAL (operands[2]) == 128
6148 || (INTVAL (operands[2]) < 0
6149 && INTVAL (operands[2]) != -128)))
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "sub{q}\t{%2, %0|%0, %2}";
6154 return "add{q}\t{%2, %0|%0, %2}";
6158 (cond [(eq_attr "alternative" "2")
6159 (const_string "lea")
6160 ; Current assemblers are broken and do not allow @GOTOFF in
6161 ; ought but a memory context.
6162 (match_operand:DI 2 "pic_symbolic_operand" "")
6163 (const_string "lea")
6164 (match_operand:DI 2 "incdec_operand" "")
6165 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "mode" "DI")])
6170 ;; Convert lea to the lea pattern to avoid flags dependency.
6172 [(set (match_operand:DI 0 "register_operand" "")
6173 (plus:DI (match_operand:DI 1 "register_operand" "")
6174 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6175 (clobber (reg:CC FLAGS_REG))]
6176 "TARGET_64BIT && reload_completed
6177 && true_regnum (operands[0]) != true_regnum (operands[1])"
6179 (plus:DI (match_dup 1)
6183 (define_insn "*adddi_2_rex64"
6184 [(set (reg FLAGS_REG)
6186 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6187 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6189 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6190 (plus:DI (match_dup 1) (match_dup 2)))]
6191 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6192 && ix86_binary_operator_ok (PLUS, DImode, operands)
6193 /* Current assemblers are broken and do not allow @GOTOFF in
6194 ought but a memory context. */
6195 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197 switch (get_attr_type (insn))
6200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201 if (operands[2] == const1_rtx)
6202 return "inc{q}\t%0";
6205 gcc_assert (operands[2] == constm1_rtx);
6206 return "dec{q}\t%0";
6210 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211 /* ???? We ought to handle there the 32bit case too
6212 - do we need new constraint? */
6213 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6214 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6215 if (CONST_INT_P (operands[2])
6216 /* Avoid overflows. */
6217 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6218 && (INTVAL (operands[2]) == 128
6219 || (INTVAL (operands[2]) < 0
6220 && INTVAL (operands[2]) != -128)))
6222 operands[2] = GEN_INT (-INTVAL (operands[2]));
6223 return "sub{q}\t{%2, %0|%0, %2}";
6225 return "add{q}\t{%2, %0|%0, %2}";
6229 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu")))
6232 (set_attr "mode" "DI")])
6234 (define_insn "*adddi_3_rex64"
6235 [(set (reg FLAGS_REG)
6236 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6237 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6238 (clobber (match_scratch:DI 0 "=r"))]
6240 && ix86_match_ccmode (insn, CCZmode)
6241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6242 /* Current assemblers are broken and do not allow @GOTOFF in
6243 ought but a memory context. */
6244 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6246 switch (get_attr_type (insn))
6249 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250 if (operands[2] == const1_rtx)
6251 return "inc{q}\t%0";
6254 gcc_assert (operands[2] == constm1_rtx);
6255 return "dec{q}\t%0";
6259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6260 /* ???? We ought to handle there the 32bit case too
6261 - do we need new constraint? */
6262 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6263 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6264 if (CONST_INT_P (operands[2])
6265 /* Avoid overflows. */
6266 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6267 && (INTVAL (operands[2]) == 128
6268 || (INTVAL (operands[2]) < 0
6269 && INTVAL (operands[2]) != -128)))
6271 operands[2] = GEN_INT (-INTVAL (operands[2]));
6272 return "sub{q}\t{%2, %0|%0, %2}";
6274 return "add{q}\t{%2, %0|%0, %2}";
6278 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "mode" "DI")])
6283 ; For comparisons against 1, -1 and 128, we may generate better code
6284 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6285 ; is matched then. We can't accept general immediate, because for
6286 ; case of overflows, the result is messed up.
6287 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6291 (define_insn "*adddi_4_rex64"
6292 [(set (reg FLAGS_REG)
6293 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6294 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6295 (clobber (match_scratch:DI 0 "=rm"))]
6297 && ix86_match_ccmode (insn, CCGCmode)"
6299 switch (get_attr_type (insn))
6302 if (operands[2] == constm1_rtx)
6303 return "inc{q}\t%0";
6306 gcc_assert (operands[2] == const1_rtx);
6307 return "dec{q}\t%0";
6311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6313 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6314 if ((INTVAL (operands[2]) == -128
6315 || (INTVAL (operands[2]) > 0
6316 && INTVAL (operands[2]) != 128))
6317 /* Avoid overflows. */
6318 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6319 return "sub{q}\t{%2, %0|%0, %2}";
6320 operands[2] = GEN_INT (-INTVAL (operands[2]));
6321 return "add{q}\t{%2, %0|%0, %2}";
6325 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "DI")])
6330 (define_insn "*adddi_5_rex64"
6331 [(set (reg FLAGS_REG)
6333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6334 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6336 (clobber (match_scratch:DI 0 "=r"))]
6338 && ix86_match_ccmode (insn, CCGOCmode)
6339 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6340 /* Current assemblers are broken and do not allow @GOTOFF in
6341 ought but a memory context. */
6342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6344 switch (get_attr_type (insn))
6347 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348 if (operands[2] == const1_rtx)
6349 return "inc{q}\t%0";
6352 gcc_assert (operands[2] == constm1_rtx);
6353 return "dec{q}\t%0";
6357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6359 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6360 if (CONST_INT_P (operands[2])
6361 /* Avoid overflows. */
6362 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6363 && (INTVAL (operands[2]) == 128
6364 || (INTVAL (operands[2]) < 0
6365 && INTVAL (operands[2]) != -128)))
6367 operands[2] = GEN_INT (-INTVAL (operands[2]));
6368 return "sub{q}\t{%2, %0|%0, %2}";
6370 return "add{q}\t{%2, %0|%0, %2}";
6374 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6375 (const_string "incdec")
6376 (const_string "alu")))
6377 (set_attr "mode" "DI")])
6380 (define_insn "*addsi_1"
6381 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6382 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6383 (match_operand:SI 2 "general_operand" "g,ri,li")))
6384 (clobber (reg:CC FLAGS_REG))]
6385 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6387 switch (get_attr_type (insn))
6390 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6391 return "lea{l}\t{%a2, %0|%0, %a2}";
6394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395 if (operands[2] == const1_rtx)
6396 return "inc{l}\t%0";
6399 gcc_assert (operands[2] == constm1_rtx);
6400 return "dec{l}\t%0";
6404 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6406 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6407 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6408 if (CONST_INT_P (operands[2])
6409 && (INTVAL (operands[2]) == 128
6410 || (INTVAL (operands[2]) < 0
6411 && INTVAL (operands[2]) != -128)))
6413 operands[2] = GEN_INT (-INTVAL (operands[2]));
6414 return "sub{l}\t{%2, %0|%0, %2}";
6416 return "add{l}\t{%2, %0|%0, %2}";
6420 (cond [(eq_attr "alternative" "2")
6421 (const_string "lea")
6422 ; Current assemblers are broken and do not allow @GOTOFF in
6423 ; ought but a memory context.
6424 (match_operand:SI 2 "pic_symbolic_operand" "")
6425 (const_string "lea")
6426 (match_operand:SI 2 "incdec_operand" "")
6427 (const_string "incdec")
6429 (const_string "alu")))
6430 (set_attr "mode" "SI")])
6432 ;; Convert lea to the lea pattern to avoid flags dependency.
6434 [(set (match_operand 0 "register_operand" "")
6435 (plus (match_operand 1 "register_operand" "")
6436 (match_operand 2 "nonmemory_operand" "")))
6437 (clobber (reg:CC FLAGS_REG))]
6439 && true_regnum (operands[0]) != true_regnum (operands[1])"
6443 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6444 may confuse gen_lowpart. */
6445 if (GET_MODE (operands[0]) != Pmode)
6447 operands[1] = gen_lowpart (Pmode, operands[1]);
6448 operands[2] = gen_lowpart (Pmode, operands[2]);
6450 operands[0] = gen_lowpart (SImode, operands[0]);
6451 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6452 if (Pmode != SImode)
6453 pat = gen_rtx_SUBREG (SImode, pat, 0);
6454 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6458 ;; It may seem that nonimmediate operand is proper one for operand 1.
6459 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6460 ;; we take care in ix86_binary_operator_ok to not allow two memory
6461 ;; operands so proper swapping will be done in reload. This allow
6462 ;; patterns constructed from addsi_1 to match.
6463 (define_insn "addsi_1_zext"
6464 [(set (match_operand:DI 0 "register_operand" "=r,r")
6466 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6467 (match_operand:SI 2 "general_operand" "g,li"))))
6468 (clobber (reg:CC FLAGS_REG))]
6469 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6471 switch (get_attr_type (insn))
6474 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6475 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6478 if (operands[2] == const1_rtx)
6479 return "inc{l}\t%k0";
6482 gcc_assert (operands[2] == constm1_rtx);
6483 return "dec{l}\t%k0";
6487 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6489 if (CONST_INT_P (operands[2])
6490 && (INTVAL (operands[2]) == 128
6491 || (INTVAL (operands[2]) < 0
6492 && INTVAL (operands[2]) != -128)))
6494 operands[2] = GEN_INT (-INTVAL (operands[2]));
6495 return "sub{l}\t{%2, %k0|%k0, %2}";
6497 return "add{l}\t{%2, %k0|%k0, %2}";
6501 (cond [(eq_attr "alternative" "1")
6502 (const_string "lea")
6503 ; Current assemblers are broken and do not allow @GOTOFF in
6504 ; ought but a memory context.
6505 (match_operand:SI 2 "pic_symbolic_operand" "")
6506 (const_string "lea")
6507 (match_operand:SI 2 "incdec_operand" "")
6508 (const_string "incdec")
6510 (const_string "alu")))
6511 (set_attr "mode" "SI")])
6513 ;; Convert lea to the lea pattern to avoid flags dependency.
6515 [(set (match_operand:DI 0 "register_operand" "")
6517 (plus:SI (match_operand:SI 1 "register_operand" "")
6518 (match_operand:SI 2 "nonmemory_operand" ""))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && reload_completed
6521 && true_regnum (operands[0]) != true_regnum (operands[1])"
6523 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6525 operands[1] = gen_lowpart (Pmode, operands[1]);
6526 operands[2] = gen_lowpart (Pmode, operands[2]);
6529 (define_insn "*addsi_2"
6530 [(set (reg FLAGS_REG)
6532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6533 (match_operand:SI 2 "general_operand" "g,ri"))
6535 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6536 (plus:SI (match_dup 1) (match_dup 2)))]
6537 "ix86_match_ccmode (insn, CCGOCmode)
6538 && ix86_binary_operator_ok (PLUS, SImode, operands)
6539 /* Current assemblers are broken and do not allow @GOTOFF in
6540 ought but a memory context. */
6541 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6543 switch (get_attr_type (insn))
6546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6547 if (operands[2] == const1_rtx)
6548 return "inc{l}\t%0";
6551 gcc_assert (operands[2] == constm1_rtx);
6552 return "dec{l}\t%0";
6556 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6559 if (CONST_INT_P (operands[2])
6560 && (INTVAL (operands[2]) == 128
6561 || (INTVAL (operands[2]) < 0
6562 && INTVAL (operands[2]) != -128)))
6564 operands[2] = GEN_INT (-INTVAL (operands[2]));
6565 return "sub{l}\t{%2, %0|%0, %2}";
6567 return "add{l}\t{%2, %0|%0, %2}";
6571 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6572 (const_string "incdec")
6573 (const_string "alu")))
6574 (set_attr "mode" "SI")])
6576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6577 (define_insn "*addsi_2_zext"
6578 [(set (reg FLAGS_REG)
6580 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6581 (match_operand:SI 2 "general_operand" "g"))
6583 (set (match_operand:DI 0 "register_operand" "=r")
6584 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6586 && ix86_binary_operator_ok (PLUS, SImode, operands)
6587 /* Current assemblers are broken and do not allow @GOTOFF in
6588 ought but a memory context. */
6589 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591 switch (get_attr_type (insn))
6594 if (operands[2] == const1_rtx)
6595 return "inc{l}\t%k0";
6598 gcc_assert (operands[2] == constm1_rtx);
6599 return "dec{l}\t%k0";
6603 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6604 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6605 if (CONST_INT_P (operands[2])
6606 && (INTVAL (operands[2]) == 128
6607 || (INTVAL (operands[2]) < 0
6608 && INTVAL (operands[2]) != -128)))
6610 operands[2] = GEN_INT (-INTVAL (operands[2]));
6611 return "sub{l}\t{%2, %k0|%k0, %2}";
6613 return "add{l}\t{%2, %k0|%k0, %2}";
6617 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6618 (const_string "incdec")
6619 (const_string "alu")))
6620 (set_attr "mode" "SI")])
6622 (define_insn "*addsi_3"
6623 [(set (reg FLAGS_REG)
6624 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6625 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6626 (clobber (match_scratch:SI 0 "=r"))]
6627 "ix86_match_ccmode (insn, CCZmode)
6628 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6629 /* Current assemblers are broken and do not allow @GOTOFF in
6630 ought but a memory context. */
6631 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633 switch (get_attr_type (insn))
6636 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637 if (operands[2] == const1_rtx)
6638 return "inc{l}\t%0";
6641 gcc_assert (operands[2] == constm1_rtx);
6642 return "dec{l}\t%0";
6646 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6647 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6648 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6649 if (CONST_INT_P (operands[2])
6650 && (INTVAL (operands[2]) == 128
6651 || (INTVAL (operands[2]) < 0
6652 && INTVAL (operands[2]) != -128)))
6654 operands[2] = GEN_INT (-INTVAL (operands[2]));
6655 return "sub{l}\t{%2, %0|%0, %2}";
6657 return "add{l}\t{%2, %0|%0, %2}";
6661 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6662 (const_string "incdec")
6663 (const_string "alu")))
6664 (set_attr "mode" "SI")])
6666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6667 (define_insn "*addsi_3_zext"
6668 [(set (reg FLAGS_REG)
6669 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6670 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6671 (set (match_operand:DI 0 "register_operand" "=r")
6672 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6673 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6674 && ix86_binary_operator_ok (PLUS, SImode, operands)
6675 /* Current assemblers are broken and do not allow @GOTOFF in
6676 ought but a memory context. */
6677 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6679 switch (get_attr_type (insn))
6682 if (operands[2] == const1_rtx)
6683 return "inc{l}\t%k0";
6686 gcc_assert (operands[2] == constm1_rtx);
6687 return "dec{l}\t%k0";
6691 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6693 if (CONST_INT_P (operands[2])
6694 && (INTVAL (operands[2]) == 128
6695 || (INTVAL (operands[2]) < 0
6696 && INTVAL (operands[2]) != -128)))
6698 operands[2] = GEN_INT (-INTVAL (operands[2]));
6699 return "sub{l}\t{%2, %k0|%k0, %2}";
6701 return "add{l}\t{%2, %k0|%k0, %2}";
6705 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6706 (const_string "incdec")
6707 (const_string "alu")))
6708 (set_attr "mode" "SI")])
6710 ; For comparisons against 1, -1 and 128, we may generate better code
6711 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6712 ; is matched then. We can't accept general immediate, because for
6713 ; case of overflows, the result is messed up.
6714 ; This pattern also don't hold of 0x80000000, since the value overflows
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6718 (define_insn "*addsi_4"
6719 [(set (reg FLAGS_REG)
6720 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6721 (match_operand:SI 2 "const_int_operand" "n")))
6722 (clobber (match_scratch:SI 0 "=rm"))]
6723 "ix86_match_ccmode (insn, CCGCmode)
6724 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6726 switch (get_attr_type (insn))
6729 if (operands[2] == constm1_rtx)
6730 return "inc{l}\t%0";
6733 gcc_assert (operands[2] == const1_rtx);
6734 return "dec{l}\t%0";
6738 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6739 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6740 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6741 if ((INTVAL (operands[2]) == -128
6742 || (INTVAL (operands[2]) > 0
6743 && INTVAL (operands[2]) != 128)))
6744 return "sub{l}\t{%2, %0|%0, %2}";
6745 operands[2] = GEN_INT (-INTVAL (operands[2]));
6746 return "add{l}\t{%2, %0|%0, %2}";
6750 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6751 (const_string "incdec")
6752 (const_string "alu")))
6753 (set_attr "mode" "SI")])
6755 (define_insn "*addsi_5"
6756 [(set (reg FLAGS_REG)
6758 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759 (match_operand:SI 2 "general_operand" "g"))
6761 (clobber (match_scratch:SI 0 "=r"))]
6762 "ix86_match_ccmode (insn, CCGOCmode)
6763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6764 /* Current assemblers are broken and do not allow @GOTOFF in
6765 ought but a memory context. */
6766 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6768 switch (get_attr_type (insn))
6771 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772 if (operands[2] == const1_rtx)
6773 return "inc{l}\t%0";
6776 gcc_assert (operands[2] == constm1_rtx);
6777 return "dec{l}\t%0";
6781 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6782 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6783 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6784 if (CONST_INT_P (operands[2])
6785 && (INTVAL (operands[2]) == 128
6786 || (INTVAL (operands[2]) < 0
6787 && INTVAL (operands[2]) != -128)))
6789 operands[2] = GEN_INT (-INTVAL (operands[2]));
6790 return "sub{l}\t{%2, %0|%0, %2}";
6792 return "add{l}\t{%2, %0|%0, %2}";
6796 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6797 (const_string "incdec")
6798 (const_string "alu")))
6799 (set_attr "mode" "SI")])
6801 (define_expand "addhi3"
6802 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6803 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6804 (match_operand:HI 2 "general_operand" "")))]
6805 "TARGET_HIMODE_MATH"
6806 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6808 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6809 ;; type optimizations enabled by define-splits. This is not important
6810 ;; for PII, and in fact harmful because of partial register stalls.
6812 (define_insn "*addhi_1_lea"
6813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6814 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6815 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_PARTIAL_REG_STALL
6818 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6820 switch (get_attr_type (insn))
6825 if (operands[2] == const1_rtx)
6826 return "inc{w}\t%0";
6829 gcc_assert (operands[2] == constm1_rtx);
6830 return "dec{w}\t%0";
6834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6836 if (CONST_INT_P (operands[2])
6837 && (INTVAL (operands[2]) == 128
6838 || (INTVAL (operands[2]) < 0
6839 && INTVAL (operands[2]) != -128)))
6841 operands[2] = GEN_INT (-INTVAL (operands[2]));
6842 return "sub{w}\t{%2, %0|%0, %2}";
6844 return "add{w}\t{%2, %0|%0, %2}";
6848 (if_then_else (eq_attr "alternative" "2")
6849 (const_string "lea")
6850 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6851 (const_string "incdec")
6852 (const_string "alu"))))
6853 (set_attr "mode" "HI,HI,SI")])
6855 (define_insn "*addhi_1"
6856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6857 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6858 (match_operand:HI 2 "general_operand" "rn,rm")))
6859 (clobber (reg:CC FLAGS_REG))]
6860 "TARGET_PARTIAL_REG_STALL
6861 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6863 switch (get_attr_type (insn))
6866 if (operands[2] == const1_rtx)
6867 return "inc{w}\t%0";
6870 gcc_assert (operands[2] == constm1_rtx);
6871 return "dec{w}\t%0";
6875 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6876 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6877 if (CONST_INT_P (operands[2])
6878 && (INTVAL (operands[2]) == 128
6879 || (INTVAL (operands[2]) < 0
6880 && INTVAL (operands[2]) != -128)))
6882 operands[2] = GEN_INT (-INTVAL (operands[2]));
6883 return "sub{w}\t{%2, %0|%0, %2}";
6885 return "add{w}\t{%2, %0|%0, %2}";
6889 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6890 (const_string "incdec")
6891 (const_string "alu")))
6892 (set_attr "mode" "HI")])
6894 (define_insn "*addhi_2"
6895 [(set (reg FLAGS_REG)
6897 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6898 (match_operand:HI 2 "general_operand" "rmn,rn"))
6900 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6901 (plus:HI (match_dup 1) (match_dup 2)))]
6902 "ix86_match_ccmode (insn, CCGOCmode)
6903 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905 switch (get_attr_type (insn))
6908 if (operands[2] == const1_rtx)
6909 return "inc{w}\t%0";
6912 gcc_assert (operands[2] == constm1_rtx);
6913 return "dec{w}\t%0";
6917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6919 if (CONST_INT_P (operands[2])
6920 && (INTVAL (operands[2]) == 128
6921 || (INTVAL (operands[2]) < 0
6922 && INTVAL (operands[2]) != -128)))
6924 operands[2] = GEN_INT (-INTVAL (operands[2]));
6925 return "sub{w}\t{%2, %0|%0, %2}";
6927 return "add{w}\t{%2, %0|%0, %2}";
6931 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932 (const_string "incdec")
6933 (const_string "alu")))
6934 (set_attr "mode" "HI")])
6936 (define_insn "*addhi_3"
6937 [(set (reg FLAGS_REG)
6938 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6939 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6940 (clobber (match_scratch:HI 0 "=r"))]
6941 "ix86_match_ccmode (insn, CCZmode)
6942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 switch (get_attr_type (insn))
6947 if (operands[2] == const1_rtx)
6948 return "inc{w}\t%0";
6951 gcc_assert (operands[2] == constm1_rtx);
6952 return "dec{w}\t%0";
6956 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6957 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6958 if (CONST_INT_P (operands[2])
6959 && (INTVAL (operands[2]) == 128
6960 || (INTVAL (operands[2]) < 0
6961 && INTVAL (operands[2]) != -128)))
6963 operands[2] = GEN_INT (-INTVAL (operands[2]));
6964 return "sub{w}\t{%2, %0|%0, %2}";
6966 return "add{w}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set_attr "mode" "HI")])
6975 ; See comments above addsi_4 for details.
6976 (define_insn "*addhi_4"
6977 [(set (reg FLAGS_REG)
6978 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6979 (match_operand:HI 2 "const_int_operand" "n")))
6980 (clobber (match_scratch:HI 0 "=rm"))]
6981 "ix86_match_ccmode (insn, CCGCmode)
6982 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6984 switch (get_attr_type (insn))
6987 if (operands[2] == constm1_rtx)
6988 return "inc{w}\t%0";
6991 gcc_assert (operands[2] == const1_rtx);
6992 return "dec{w}\t%0";
6996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6997 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6998 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6999 if ((INTVAL (operands[2]) == -128
7000 || (INTVAL (operands[2]) > 0
7001 && INTVAL (operands[2]) != 128)))
7002 return "sub{w}\t{%2, %0|%0, %2}";
7003 operands[2] = GEN_INT (-INTVAL (operands[2]));
7004 return "add{w}\t{%2, %0|%0, %2}";
7008 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7009 (const_string "incdec")
7010 (const_string "alu")))
7011 (set_attr "mode" "SI")])
7014 (define_insn "*addhi_5"
7015 [(set (reg FLAGS_REG)
7017 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7018 (match_operand:HI 2 "general_operand" "rmn"))
7020 (clobber (match_scratch:HI 0 "=r"))]
7021 "ix86_match_ccmode (insn, CCGOCmode)
7022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 switch (get_attr_type (insn))
7027 if (operands[2] == const1_rtx)
7028 return "inc{w}\t%0";
7031 gcc_assert (operands[2] == constm1_rtx);
7032 return "dec{w}\t%0";
7036 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7037 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7038 if (CONST_INT_P (operands[2])
7039 && (INTVAL (operands[2]) == 128
7040 || (INTVAL (operands[2]) < 0
7041 && INTVAL (operands[2]) != -128)))
7043 operands[2] = GEN_INT (-INTVAL (operands[2]));
7044 return "sub{w}\t{%2, %0|%0, %2}";
7046 return "add{w}\t{%2, %0|%0, %2}";
7050 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051 (const_string "incdec")
7052 (const_string "alu")))
7053 (set_attr "mode" "HI")])
7055 (define_expand "addqi3"
7056 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))]
7059 "TARGET_QIMODE_MATH"
7060 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7062 ;; %%% Potential partial reg stall on alternative 2. What to do?
7063 (define_insn "*addqi_1_lea"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7065 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7066 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "!TARGET_PARTIAL_REG_STALL
7069 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7071 int widen = (which_alternative == 2);
7072 switch (get_attr_type (insn))
7077 if (operands[2] == const1_rtx)
7078 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7081 gcc_assert (operands[2] == constm1_rtx);
7082 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7086 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7087 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7088 if (CONST_INT_P (operands[2])
7089 && (INTVAL (operands[2]) == 128
7090 || (INTVAL (operands[2]) < 0
7091 && INTVAL (operands[2]) != -128)))
7093 operands[2] = GEN_INT (-INTVAL (operands[2]));
7095 return "sub{l}\t{%2, %k0|%k0, %2}";
7097 return "sub{b}\t{%2, %0|%0, %2}";
7100 return "add{l}\t{%k2, %k0|%k0, %k2}";
7102 return "add{b}\t{%2, %0|%0, %2}";
7106 (if_then_else (eq_attr "alternative" "3")
7107 (const_string "lea")
7108 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7109 (const_string "incdec")
7110 (const_string "alu"))))
7111 (set_attr "mode" "QI,QI,SI,SI")])
7113 (define_insn "*addqi_1"
7114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7115 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7116 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7117 (clobber (reg:CC FLAGS_REG))]
7118 "TARGET_PARTIAL_REG_STALL
7119 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7121 int widen = (which_alternative == 2);
7122 switch (get_attr_type (insn))
7125 if (operands[2] == const1_rtx)
7126 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7129 gcc_assert (operands[2] == constm1_rtx);
7130 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7136 if (CONST_INT_P (operands[2])
7137 && (INTVAL (operands[2]) == 128
7138 || (INTVAL (operands[2]) < 0
7139 && INTVAL (operands[2]) != -128)))
7141 operands[2] = GEN_INT (-INTVAL (operands[2]));
7143 return "sub{l}\t{%2, %k0|%k0, %2}";
7145 return "sub{b}\t{%2, %0|%0, %2}";
7148 return "add{l}\t{%k2, %k0|%k0, %k2}";
7150 return "add{b}\t{%2, %0|%0, %2}";
7154 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7155 (const_string "incdec")
7156 (const_string "alu")))
7157 (set_attr "mode" "QI,QI,SI")])
7159 (define_insn "*addqi_1_slp"
7160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7161 (plus:QI (match_dup 0)
7162 (match_operand:QI 1 "general_operand" "qn,qnm")))
7163 (clobber (reg:CC FLAGS_REG))]
7164 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7167 switch (get_attr_type (insn))
7170 if (operands[1] == const1_rtx)
7171 return "inc{b}\t%0";
7174 gcc_assert (operands[1] == constm1_rtx);
7175 return "dec{b}\t%0";
7179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7180 if (CONST_INT_P (operands[1])
7181 && INTVAL (operands[1]) < 0)
7183 operands[1] = GEN_INT (-INTVAL (operands[1]));
7184 return "sub{b}\t{%1, %0|%0, %1}";
7186 return "add{b}\t{%1, %0|%0, %1}";
7190 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7191 (const_string "incdec")
7192 (const_string "alu1")))
7193 (set (attr "memory")
7194 (if_then_else (match_operand 1 "memory_operand" "")
7195 (const_string "load")
7196 (const_string "none")))
7197 (set_attr "mode" "QI")])
7199 (define_insn "*addqi_2"
7200 [(set (reg FLAGS_REG)
7202 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7203 (match_operand:QI 2 "general_operand" "qmn,qn"))
7205 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7206 (plus:QI (match_dup 1) (match_dup 2)))]
7207 "ix86_match_ccmode (insn, CCGOCmode)
7208 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7210 switch (get_attr_type (insn))
7213 if (operands[2] == const1_rtx)
7214 return "inc{b}\t%0";
7217 gcc_assert (operands[2] == constm1_rtx
7218 || (CONST_INT_P (operands[2])
7219 && INTVAL (operands[2]) == 255));
7220 return "dec{b}\t%0";
7224 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7225 if (CONST_INT_P (operands[2])
7226 && INTVAL (operands[2]) < 0)
7228 operands[2] = GEN_INT (-INTVAL (operands[2]));
7229 return "sub{b}\t{%2, %0|%0, %2}";
7231 return "add{b}\t{%2, %0|%0, %2}";
7235 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7236 (const_string "incdec")
7237 (const_string "alu")))
7238 (set_attr "mode" "QI")])
7240 (define_insn "*addqi_3"
7241 [(set (reg FLAGS_REG)
7242 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7243 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7244 (clobber (match_scratch:QI 0 "=q"))]
7245 "ix86_match_ccmode (insn, CCZmode)
7246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248 switch (get_attr_type (insn))
7251 if (operands[2] == const1_rtx)
7252 return "inc{b}\t%0";
7255 gcc_assert (operands[2] == constm1_rtx
7256 || (CONST_INT_P (operands[2])
7257 && INTVAL (operands[2]) == 255));
7258 return "dec{b}\t%0";
7262 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7263 if (CONST_INT_P (operands[2])
7264 && INTVAL (operands[2]) < 0)
7266 operands[2] = GEN_INT (-INTVAL (operands[2]));
7267 return "sub{b}\t{%2, %0|%0, %2}";
7269 return "add{b}\t{%2, %0|%0, %2}";
7273 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7274 (const_string "incdec")
7275 (const_string "alu")))
7276 (set_attr "mode" "QI")])
7278 ; See comments above addsi_4 for details.
7279 (define_insn "*addqi_4"
7280 [(set (reg FLAGS_REG)
7281 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7282 (match_operand:QI 2 "const_int_operand" "n")))
7283 (clobber (match_scratch:QI 0 "=qm"))]
7284 "ix86_match_ccmode (insn, CCGCmode)
7285 && (INTVAL (operands[2]) & 0xff) != 0x80"
7287 switch (get_attr_type (insn))
7290 if (operands[2] == constm1_rtx
7291 || (CONST_INT_P (operands[2])
7292 && INTVAL (operands[2]) == 255))
7293 return "inc{b}\t%0";
7296 gcc_assert (operands[2] == const1_rtx);
7297 return "dec{b}\t%0";
7301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7302 if (INTVAL (operands[2]) < 0)
7304 operands[2] = GEN_INT (-INTVAL (operands[2]));
7305 return "add{b}\t{%2, %0|%0, %2}";
7307 return "sub{b}\t{%2, %0|%0, %2}";
7311 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7312 (const_string "incdec")
7313 (const_string "alu")))
7314 (set_attr "mode" "QI")])
7317 (define_insn "*addqi_5"
7318 [(set (reg FLAGS_REG)
7320 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321 (match_operand:QI 2 "general_operand" "qmn"))
7323 (clobber (match_scratch:QI 0 "=q"))]
7324 "ix86_match_ccmode (insn, CCGOCmode)
7325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327 switch (get_attr_type (insn))
7330 if (operands[2] == const1_rtx)
7331 return "inc{b}\t%0";
7334 gcc_assert (operands[2] == constm1_rtx
7335 || (CONST_INT_P (operands[2])
7336 && INTVAL (operands[2]) == 255));
7337 return "dec{b}\t%0";
7341 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7342 if (CONST_INT_P (operands[2])
7343 && INTVAL (operands[2]) < 0)
7345 operands[2] = GEN_INT (-INTVAL (operands[2]));
7346 return "sub{b}\t{%2, %0|%0, %2}";
7348 return "add{b}\t{%2, %0|%0, %2}";
7352 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7353 (const_string "incdec")
7354 (const_string "alu")))
7355 (set_attr "mode" "QI")])
7358 (define_insn "addqi_ext_1"
7359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7364 (match_operand 1 "ext_register_operand" "0")
7367 (match_operand:QI 2 "general_operand" "Qmn")))
7368 (clobber (reg:CC FLAGS_REG))]
7371 switch (get_attr_type (insn))
7374 if (operands[2] == const1_rtx)
7375 return "inc{b}\t%h0";
7378 gcc_assert (operands[2] == constm1_rtx
7379 || (CONST_INT_P (operands[2])
7380 && INTVAL (operands[2]) == 255));
7381 return "dec{b}\t%h0";
7385 return "add{b}\t{%2, %h0|%h0, %2}";
7389 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7390 (const_string "incdec")
7391 (const_string "alu")))
7392 (set_attr "mode" "QI")])
7394 (define_insn "*addqi_ext_1_rex64"
7395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7400 (match_operand 1 "ext_register_operand" "0")
7403 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7404 (clobber (reg:CC FLAGS_REG))]
7407 switch (get_attr_type (insn))
7410 if (operands[2] == const1_rtx)
7411 return "inc{b}\t%h0";
7414 gcc_assert (operands[2] == constm1_rtx
7415 || (CONST_INT_P (operands[2])
7416 && INTVAL (operands[2]) == 255));
7417 return "dec{b}\t%h0";
7421 return "add{b}\t{%2, %h0|%h0, %2}";
7425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7426 (const_string "incdec")
7427 (const_string "alu")))
7428 (set_attr "mode" "QI")])
7430 (define_insn "*addqi_ext_2"
7431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7436 (match_operand 1 "ext_register_operand" "%0")
7440 (match_operand 2 "ext_register_operand" "Q")
7443 (clobber (reg:CC FLAGS_REG))]
7445 "add{b}\t{%h2, %h0|%h0, %h2}"
7446 [(set_attr "type" "alu")
7447 (set_attr "mode" "QI")])
7449 ;; The patterns that match these are at the end of this file.
7451 (define_expand "addxf3"
7452 [(set (match_operand:XF 0 "register_operand" "")
7453 (plus:XF (match_operand:XF 1 "register_operand" "")
7454 (match_operand:XF 2 "register_operand" "")))]
7458 (define_expand "add<mode>3"
7459 [(set (match_operand:MODEF 0 "register_operand" "")
7460 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7461 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7462 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7465 ;; Subtract instructions
7467 ;; %%% splits for subditi3
7469 (define_expand "subti3"
7470 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7471 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7472 (match_operand:TI 2 "x86_64_general_operand" "")))]
7474 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7476 (define_insn "*subti3_1"
7477 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7478 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7479 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7485 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7486 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7487 (match_operand:TI 2 "x86_64_general_operand" "")))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "TARGET_64BIT && reload_completed"
7490 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7491 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7492 (parallel [(set (match_dup 3)
7493 (minus:DI (match_dup 4)
7494 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7496 (clobber (reg:CC FLAGS_REG))])]
7497 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7499 ;; %%% splits for subsidi3
7501 (define_expand "subdi3"
7502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7503 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7504 (match_operand:DI 2 "x86_64_general_operand" "")))]
7506 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7508 (define_insn "*subdi3_1"
7509 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7510 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7511 (match_operand:DI 2 "general_operand" "roiF,riF")))
7512 (clobber (reg:CC FLAGS_REG))]
7513 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7517 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7518 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7519 (match_operand:DI 2 "general_operand" "")))
7520 (clobber (reg:CC FLAGS_REG))]
7521 "!TARGET_64BIT && reload_completed"
7522 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7523 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7524 (parallel [(set (match_dup 3)
7525 (minus:SI (match_dup 4)
7526 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7528 (clobber (reg:CC FLAGS_REG))])]
7529 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7531 (define_insn "subdi3_carry_rex64"
7532 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7533 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7534 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7535 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7538 "sbb{q}\t{%2, %0|%0, %2}"
7539 [(set_attr "type" "alu")
7540 (set_attr "pent_pair" "pu")
7541 (set_attr "mode" "DI")])
7543 (define_insn "*subdi_1_rex64"
7544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7546 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7549 "sub{q}\t{%2, %0|%0, %2}"
7550 [(set_attr "type" "alu")
7551 (set_attr "mode" "DI")])
7553 (define_insn "*subdi_2_rex64"
7554 [(set (reg FLAGS_REG)
7556 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7557 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7559 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7560 (minus:DI (match_dup 1) (match_dup 2)))]
7561 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7562 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7563 "sub{q}\t{%2, %0|%0, %2}"
7564 [(set_attr "type" "alu")
7565 (set_attr "mode" "DI")])
7567 (define_insn "*subdi_3_rex63"
7568 [(set (reg FLAGS_REG)
7569 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7570 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7572 (minus:DI (match_dup 1) (match_dup 2)))]
7573 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7574 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7575 "sub{q}\t{%2, %0|%0, %2}"
7576 [(set_attr "type" "alu")
7577 (set_attr "mode" "DI")])
7579 (define_insn "subqi3_carry"
7580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7582 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7583 (match_operand:QI 2 "general_operand" "qn,qm"))))
7584 (clobber (reg:CC FLAGS_REG))]
7585 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7586 "sbb{b}\t{%2, %0|%0, %2}"
7587 [(set_attr "type" "alu")
7588 (set_attr "pent_pair" "pu")
7589 (set_attr "mode" "QI")])
7591 (define_insn "subhi3_carry"
7592 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7593 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7594 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7595 (match_operand:HI 2 "general_operand" "rn,rm"))))
7596 (clobber (reg:CC FLAGS_REG))]
7597 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7598 "sbb{w}\t{%2, %0|%0, %2}"
7599 [(set_attr "type" "alu")
7600 (set_attr "pent_pair" "pu")
7601 (set_attr "mode" "HI")])
7603 (define_insn "subsi3_carry"
7604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7605 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7606 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7607 (match_operand:SI 2 "general_operand" "ri,rm"))))
7608 (clobber (reg:CC FLAGS_REG))]
7609 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7610 "sbb{l}\t{%2, %0|%0, %2}"
7611 [(set_attr "type" "alu")
7612 (set_attr "pent_pair" "pu")
7613 (set_attr "mode" "SI")])
7615 (define_insn "subsi3_carry_zext"
7616 [(set (match_operand:DI 0 "register_operand" "=r")
7618 (minus:SI (match_operand:SI 1 "register_operand" "0")
7619 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7620 (match_operand:SI 2 "general_operand" "g")))))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7623 "sbb{l}\t{%2, %k0|%k0, %2}"
7624 [(set_attr "type" "alu")
7625 (set_attr "pent_pair" "pu")
7626 (set_attr "mode" "SI")])
7628 (define_expand "subsi3"
7629 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7630 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7631 (match_operand:SI 2 "general_operand" "")))]
7633 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7635 (define_insn "*subsi_1"
7636 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7637 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7638 (match_operand:SI 2 "general_operand" "ri,rm")))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7641 "sub{l}\t{%2, %0|%0, %2}"
7642 [(set_attr "type" "alu")
7643 (set_attr "mode" "SI")])
7645 (define_insn "*subsi_1_zext"
7646 [(set (match_operand:DI 0 "register_operand" "=r")
7648 (minus:SI (match_operand:SI 1 "register_operand" "0")
7649 (match_operand:SI 2 "general_operand" "g"))))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7652 "sub{l}\t{%2, %k0|%k0, %2}"
7653 [(set_attr "type" "alu")
7654 (set_attr "mode" "SI")])
7656 (define_insn "*subsi_2"
7657 [(set (reg FLAGS_REG)
7659 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7660 (match_operand:SI 2 "general_operand" "ri,rm"))
7662 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7663 (minus:SI (match_dup 1) (match_dup 2)))]
7664 "ix86_match_ccmode (insn, CCGOCmode)
7665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666 "sub{l}\t{%2, %0|%0, %2}"
7667 [(set_attr "type" "alu")
7668 (set_attr "mode" "SI")])
7670 (define_insn "*subsi_2_zext"
7671 [(set (reg FLAGS_REG)
7673 (minus:SI (match_operand:SI 1 "register_operand" "0")
7674 (match_operand:SI 2 "general_operand" "g"))
7676 (set (match_operand:DI 0 "register_operand" "=r")
7678 (minus:SI (match_dup 1)
7680 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7681 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sub{l}\t{%2, %k0|%k0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "mode" "SI")])
7686 (define_insn "*subsi_3"
7687 [(set (reg FLAGS_REG)
7688 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7689 (match_operand:SI 2 "general_operand" "ri,rm")))
7690 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7691 (minus:SI (match_dup 1) (match_dup 2)))]
7692 "ix86_match_ccmode (insn, CCmode)
7693 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7694 "sub{l}\t{%2, %0|%0, %2}"
7695 [(set_attr "type" "alu")
7696 (set_attr "mode" "SI")])
7698 (define_insn "*subsi_3_zext"
7699 [(set (reg FLAGS_REG)
7700 (compare (match_operand:SI 1 "register_operand" "0")
7701 (match_operand:SI 2 "general_operand" "g")))
7702 (set (match_operand:DI 0 "register_operand" "=r")
7704 (minus:SI (match_dup 1)
7706 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7707 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7708 "sub{l}\t{%2, %1|%1, %2}"
7709 [(set_attr "type" "alu")
7710 (set_attr "mode" "DI")])
7712 (define_expand "subhi3"
7713 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7714 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7715 (match_operand:HI 2 "general_operand" "")))]
7716 "TARGET_HIMODE_MATH"
7717 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7719 (define_insn "*subhi_1"
7720 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7721 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7722 (match_operand:HI 2 "general_operand" "rn,rm")))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7725 "sub{w}\t{%2, %0|%0, %2}"
7726 [(set_attr "type" "alu")
7727 (set_attr "mode" "HI")])
7729 (define_insn "*subhi_2"
7730 [(set (reg FLAGS_REG)
7732 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7733 (match_operand:HI 2 "general_operand" "rn,rm"))
7735 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7736 (minus:HI (match_dup 1) (match_dup 2)))]
7737 "ix86_match_ccmode (insn, CCGOCmode)
7738 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7739 "sub{w}\t{%2, %0|%0, %2}"
7740 [(set_attr "type" "alu")
7741 (set_attr "mode" "HI")])
7743 (define_insn "*subhi_3"
7744 [(set (reg FLAGS_REG)
7745 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7746 (match_operand:HI 2 "general_operand" "rn,rm")))
7747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7748 (minus:HI (match_dup 1) (match_dup 2)))]
7749 "ix86_match_ccmode (insn, CCmode)
7750 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7751 "sub{w}\t{%2, %0|%0, %2}"
7752 [(set_attr "type" "alu")
7753 (set_attr "mode" "HI")])
7755 (define_expand "subqi3"
7756 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7757 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7758 (match_operand:QI 2 "general_operand" "")))]
7759 "TARGET_QIMODE_MATH"
7760 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7762 (define_insn "*subqi_1"
7763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7764 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7765 (match_operand:QI 2 "general_operand" "qn,qm")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7768 "sub{b}\t{%2, %0|%0, %2}"
7769 [(set_attr "type" "alu")
7770 (set_attr "mode" "QI")])
7772 (define_insn "*subqi_1_slp"
7773 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7774 (minus:QI (match_dup 0)
7775 (match_operand:QI 1 "general_operand" "qn,qm")))
7776 (clobber (reg:CC FLAGS_REG))]
7777 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7779 "sub{b}\t{%1, %0|%0, %1}"
7780 [(set_attr "type" "alu1")
7781 (set_attr "mode" "QI")])
7783 (define_insn "*subqi_2"
7784 [(set (reg FLAGS_REG)
7786 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7787 (match_operand:QI 2 "general_operand" "qn,qm"))
7789 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7790 (minus:QI (match_dup 1) (match_dup 2)))]
7791 "ix86_match_ccmode (insn, CCGOCmode)
7792 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7793 "sub{b}\t{%2, %0|%0, %2}"
7794 [(set_attr "type" "alu")
7795 (set_attr "mode" "QI")])
7797 (define_insn "*subqi_3"
7798 [(set (reg FLAGS_REG)
7799 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7800 (match_operand:QI 2 "general_operand" "qn,qm")))
7801 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7802 (minus:QI (match_dup 1) (match_dup 2)))]
7803 "ix86_match_ccmode (insn, CCmode)
7804 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7805 "sub{b}\t{%2, %0|%0, %2}"
7806 [(set_attr "type" "alu")
7807 (set_attr "mode" "QI")])
7809 ;; The patterns that match these are at the end of this file.
7811 (define_expand "subxf3"
7812 [(set (match_operand:XF 0 "register_operand" "")
7813 (minus:XF (match_operand:XF 1 "register_operand" "")
7814 (match_operand:XF 2 "register_operand" "")))]
7818 (define_expand "sub<mode>3"
7819 [(set (match_operand:MODEF 0 "register_operand" "")
7820 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7821 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7822 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7825 ;; Multiply instructions
7827 (define_expand "muldi3"
7828 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7829 (mult:DI (match_operand:DI 1 "register_operand" "")
7830 (match_operand:DI 2 "x86_64_general_operand" "")))
7831 (clobber (reg:CC FLAGS_REG))])]
7836 ;; IMUL reg64, reg64, imm8 Direct
7837 ;; IMUL reg64, mem64, imm8 VectorPath
7838 ;; IMUL reg64, reg64, imm32 Direct
7839 ;; IMUL reg64, mem64, imm32 VectorPath
7840 ;; IMUL reg64, reg64 Direct
7841 ;; IMUL reg64, mem64 Direct
7843 (define_insn "*muldi3_1_rex64"
7844 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7845 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7846 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7847 (clobber (reg:CC FLAGS_REG))]
7849 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7851 imul{q}\t{%2, %1, %0|%0, %1, %2}
7852 imul{q}\t{%2, %1, %0|%0, %1, %2}
7853 imul{q}\t{%2, %0|%0, %2}"
7854 [(set_attr "type" "imul")
7855 (set_attr "prefix_0f" "0,0,1")
7856 (set (attr "athlon_decode")
7857 (cond [(eq_attr "cpu" "athlon")
7858 (const_string "vector")
7859 (eq_attr "alternative" "1")
7860 (const_string "vector")
7861 (and (eq_attr "alternative" "2")
7862 (match_operand 1 "memory_operand" ""))
7863 (const_string "vector")]
7864 (const_string "direct")))
7865 (set (attr "amdfam10_decode")
7866 (cond [(and (eq_attr "alternative" "0,1")
7867 (match_operand 1 "memory_operand" ""))
7868 (const_string "vector")]
7869 (const_string "direct")))
7870 (set_attr "mode" "DI")])
7872 (define_expand "mulsi3"
7873 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874 (mult:SI (match_operand:SI 1 "register_operand" "")
7875 (match_operand:SI 2 "general_operand" "")))
7876 (clobber (reg:CC FLAGS_REG))])]
7881 ;; IMUL reg32, reg32, imm8 Direct
7882 ;; IMUL reg32, mem32, imm8 VectorPath
7883 ;; IMUL reg32, reg32, imm32 Direct
7884 ;; IMUL reg32, mem32, imm32 VectorPath
7885 ;; IMUL reg32, reg32 Direct
7886 ;; IMUL reg32, mem32 Direct
7888 (define_insn "*mulsi3_1"
7889 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7890 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7891 (match_operand:SI 2 "general_operand" "K,i,mr")))
7892 (clobber (reg:CC FLAGS_REG))]
7893 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895 imul{l}\t{%2, %1, %0|%0, %1, %2}
7896 imul{l}\t{%2, %1, %0|%0, %1, %2}
7897 imul{l}\t{%2, %0|%0, %2}"
7898 [(set_attr "type" "imul")
7899 (set_attr "prefix_0f" "0,0,1")
7900 (set (attr "athlon_decode")
7901 (cond [(eq_attr "cpu" "athlon")
7902 (const_string "vector")
7903 (eq_attr "alternative" "1")
7904 (const_string "vector")
7905 (and (eq_attr "alternative" "2")
7906 (match_operand 1 "memory_operand" ""))
7907 (const_string "vector")]
7908 (const_string "direct")))
7909 (set (attr "amdfam10_decode")
7910 (cond [(and (eq_attr "alternative" "0,1")
7911 (match_operand 1 "memory_operand" ""))
7912 (const_string "vector")]
7913 (const_string "direct")))
7914 (set_attr "mode" "SI")])
7916 (define_insn "*mulsi3_1_zext"
7917 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7920 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7921 (clobber (reg:CC FLAGS_REG))]
7923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7926 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927 imul{l}\t{%2, %k0|%k0, %2}"
7928 [(set_attr "type" "imul")
7929 (set_attr "prefix_0f" "0,0,1")
7930 (set (attr "athlon_decode")
7931 (cond [(eq_attr "cpu" "athlon")
7932 (const_string "vector")
7933 (eq_attr "alternative" "1")
7934 (const_string "vector")
7935 (and (eq_attr "alternative" "2")
7936 (match_operand 1 "memory_operand" ""))
7937 (const_string "vector")]
7938 (const_string "direct")))
7939 (set (attr "amdfam10_decode")
7940 (cond [(and (eq_attr "alternative" "0,1")
7941 (match_operand 1 "memory_operand" ""))
7942 (const_string "vector")]
7943 (const_string "direct")))
7944 (set_attr "mode" "SI")])
7946 (define_expand "mulhi3"
7947 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7948 (mult:HI (match_operand:HI 1 "register_operand" "")
7949 (match_operand:HI 2 "general_operand" "")))
7950 (clobber (reg:CC FLAGS_REG))])]
7951 "TARGET_HIMODE_MATH"
7955 ;; IMUL reg16, reg16, imm8 VectorPath
7956 ;; IMUL reg16, mem16, imm8 VectorPath
7957 ;; IMUL reg16, reg16, imm16 VectorPath
7958 ;; IMUL reg16, mem16, imm16 VectorPath
7959 ;; IMUL reg16, reg16 Direct
7960 ;; IMUL reg16, mem16 Direct
7961 (define_insn "*mulhi3_1"
7962 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7963 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7964 (match_operand:HI 2 "general_operand" "K,n,mr")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968 imul{w}\t{%2, %1, %0|%0, %1, %2}
7969 imul{w}\t{%2, %1, %0|%0, %1, %2}
7970 imul{w}\t{%2, %0|%0, %2}"
7971 [(set_attr "type" "imul")
7972 (set_attr "prefix_0f" "0,0,1")
7973 (set (attr "athlon_decode")
7974 (cond [(eq_attr "cpu" "athlon")
7975 (const_string "vector")
7976 (eq_attr "alternative" "1,2")
7977 (const_string "vector")]
7978 (const_string "direct")))
7979 (set (attr "amdfam10_decode")
7980 (cond [(eq_attr "alternative" "0,1")
7981 (const_string "vector")]
7982 (const_string "direct")))
7983 (set_attr "mode" "HI")])
7985 (define_expand "mulqi3"
7986 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7987 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7988 (match_operand:QI 2 "register_operand" "")))
7989 (clobber (reg:CC FLAGS_REG))])]
7990 "TARGET_QIMODE_MATH"
7997 (define_insn "*mulqi3_1"
7998 [(set (match_operand:QI 0 "register_operand" "=a")
7999 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8000 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8001 (clobber (reg:CC FLAGS_REG))]
8003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 [(set_attr "type" "imul")
8006 (set_attr "length_immediate" "0")
8007 (set (attr "athlon_decode")
8008 (if_then_else (eq_attr "cpu" "athlon")
8009 (const_string "vector")
8010 (const_string "direct")))
8011 (set_attr "amdfam10_decode" "direct")
8012 (set_attr "mode" "QI")])
8014 (define_expand "umulqihi3"
8015 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8016 (mult:HI (zero_extend:HI
8017 (match_operand:QI 1 "nonimmediate_operand" ""))
8019 (match_operand:QI 2 "register_operand" ""))))
8020 (clobber (reg:CC FLAGS_REG))])]
8021 "TARGET_QIMODE_MATH"
8024 (define_insn "*umulqihi3_1"
8025 [(set (match_operand:HI 0 "register_operand" "=a")
8026 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8027 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8028 (clobber (reg:CC FLAGS_REG))]
8030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032 [(set_attr "type" "imul")
8033 (set_attr "length_immediate" "0")
8034 (set (attr "athlon_decode")
8035 (if_then_else (eq_attr "cpu" "athlon")
8036 (const_string "vector")
8037 (const_string "direct")))
8038 (set_attr "amdfam10_decode" "direct")
8039 (set_attr "mode" "QI")])
8041 (define_expand "mulqihi3"
8042 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8043 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8044 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8045 (clobber (reg:CC FLAGS_REG))])]
8046 "TARGET_QIMODE_MATH"
8049 (define_insn "*mulqihi3_insn"
8050 [(set (match_operand:HI 0 "register_operand" "=a")
8051 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8052 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8053 (clobber (reg:CC FLAGS_REG))]
8055 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8057 [(set_attr "type" "imul")
8058 (set_attr "length_immediate" "0")
8059 (set (attr "athlon_decode")
8060 (if_then_else (eq_attr "cpu" "athlon")
8061 (const_string "vector")
8062 (const_string "direct")))
8063 (set_attr "amdfam10_decode" "direct")
8064 (set_attr "mode" "QI")])
8066 (define_expand "umulditi3"
8067 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8068 (mult:TI (zero_extend:TI
8069 (match_operand:DI 1 "nonimmediate_operand" ""))
8071 (match_operand:DI 2 "register_operand" ""))))
8072 (clobber (reg:CC FLAGS_REG))])]
8076 (define_insn "*umulditi3_insn"
8077 [(set (match_operand:TI 0 "register_operand" "=A")
8078 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8079 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8080 (clobber (reg:CC FLAGS_REG))]
8082 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8084 [(set_attr "type" "imul")
8085 (set_attr "length_immediate" "0")
8086 (set (attr "athlon_decode")
8087 (if_then_else (eq_attr "cpu" "athlon")
8088 (const_string "vector")
8089 (const_string "double")))
8090 (set_attr "amdfam10_decode" "double")
8091 (set_attr "mode" "DI")])
8093 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8094 (define_expand "umulsidi3"
8095 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8096 (mult:DI (zero_extend:DI
8097 (match_operand:SI 1 "nonimmediate_operand" ""))
8099 (match_operand:SI 2 "register_operand" ""))))
8100 (clobber (reg:CC FLAGS_REG))])]
8104 (define_insn "*umulsidi3_insn"
8105 [(set (match_operand:DI 0 "register_operand" "=A")
8106 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8107 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8108 (clobber (reg:CC FLAGS_REG))]
8110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112 [(set_attr "type" "imul")
8113 (set_attr "length_immediate" "0")
8114 (set (attr "athlon_decode")
8115 (if_then_else (eq_attr "cpu" "athlon")
8116 (const_string "vector")
8117 (const_string "double")))
8118 (set_attr "amdfam10_decode" "double")
8119 (set_attr "mode" "SI")])
8121 (define_expand "mulditi3"
8122 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8123 (mult:TI (sign_extend:TI
8124 (match_operand:DI 1 "nonimmediate_operand" ""))
8126 (match_operand:DI 2 "register_operand" ""))))
8127 (clobber (reg:CC FLAGS_REG))])]
8131 (define_insn "*mulditi3_insn"
8132 [(set (match_operand:TI 0 "register_operand" "=A")
8133 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8134 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8135 (clobber (reg:CC FLAGS_REG))]
8137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 [(set_attr "type" "imul")
8140 (set_attr "length_immediate" "0")
8141 (set (attr "athlon_decode")
8142 (if_then_else (eq_attr "cpu" "athlon")
8143 (const_string "vector")
8144 (const_string "double")))
8145 (set_attr "amdfam10_decode" "double")
8146 (set_attr "mode" "DI")])
8148 (define_expand "mulsidi3"
8149 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8150 (mult:DI (sign_extend:DI
8151 (match_operand:SI 1 "nonimmediate_operand" ""))
8153 (match_operand:SI 2 "register_operand" ""))))
8154 (clobber (reg:CC FLAGS_REG))])]
8158 (define_insn "*mulsidi3_insn"
8159 [(set (match_operand:DI 0 "register_operand" "=A")
8160 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8161 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8162 (clobber (reg:CC FLAGS_REG))]
8164 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8166 [(set_attr "type" "imul")
8167 (set_attr "length_immediate" "0")
8168 (set (attr "athlon_decode")
8169 (if_then_else (eq_attr "cpu" "athlon")
8170 (const_string "vector")
8171 (const_string "double")))
8172 (set_attr "amdfam10_decode" "double")
8173 (set_attr "mode" "SI")])
8175 (define_expand "umuldi3_highpart"
8176 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8179 (mult:TI (zero_extend:TI
8180 (match_operand:DI 1 "nonimmediate_operand" ""))
8182 (match_operand:DI 2 "register_operand" "")))
8184 (clobber (match_scratch:DI 3 ""))
8185 (clobber (reg:CC FLAGS_REG))])]
8189 (define_insn "*umuldi3_highpart_rex64"
8190 [(set (match_operand:DI 0 "register_operand" "=d")
8193 (mult:TI (zero_extend:TI
8194 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8196 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8198 (clobber (match_scratch:DI 3 "=1"))
8199 (clobber (reg:CC FLAGS_REG))]
8201 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8203 [(set_attr "type" "imul")
8204 (set_attr "length_immediate" "0")
8205 (set (attr "athlon_decode")
8206 (if_then_else (eq_attr "cpu" "athlon")
8207 (const_string "vector")
8208 (const_string "double")))
8209 (set_attr "amdfam10_decode" "double")
8210 (set_attr "mode" "DI")])
8212 (define_expand "umulsi3_highpart"
8213 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8216 (mult:DI (zero_extend:DI
8217 (match_operand:SI 1 "nonimmediate_operand" ""))
8219 (match_operand:SI 2 "register_operand" "")))
8221 (clobber (match_scratch:SI 3 ""))
8222 (clobber (reg:CC FLAGS_REG))])]
8226 (define_insn "*umulsi3_highpart_insn"
8227 [(set (match_operand:SI 0 "register_operand" "=d")
8230 (mult:DI (zero_extend:DI
8231 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8233 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8235 (clobber (match_scratch:SI 3 "=1"))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8239 [(set_attr "type" "imul")
8240 (set_attr "length_immediate" "0")
8241 (set (attr "athlon_decode")
8242 (if_then_else (eq_attr "cpu" "athlon")
8243 (const_string "vector")
8244 (const_string "double")))
8245 (set_attr "amdfam10_decode" "double")
8246 (set_attr "mode" "SI")])
8248 (define_insn "*umulsi3_highpart_zext"
8249 [(set (match_operand:DI 0 "register_operand" "=d")
8250 (zero_extend:DI (truncate:SI
8252 (mult:DI (zero_extend:DI
8253 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8255 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8257 (clobber (match_scratch:SI 3 "=1"))
8258 (clobber (reg:CC FLAGS_REG))]
8260 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262 [(set_attr "type" "imul")
8263 (set_attr "length_immediate" "0")
8264 (set (attr "athlon_decode")
8265 (if_then_else (eq_attr "cpu" "athlon")
8266 (const_string "vector")
8267 (const_string "double")))
8268 (set_attr "amdfam10_decode" "double")
8269 (set_attr "mode" "SI")])
8271 (define_expand "smuldi3_highpart"
8272 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8275 (mult:TI (sign_extend:TI
8276 (match_operand:DI 1 "nonimmediate_operand" ""))
8278 (match_operand:DI 2 "register_operand" "")))
8280 (clobber (match_scratch:DI 3 ""))
8281 (clobber (reg:CC FLAGS_REG))])]
8285 (define_insn "*smuldi3_highpart_rex64"
8286 [(set (match_operand:DI 0 "register_operand" "=d")
8289 (mult:TI (sign_extend:TI
8290 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8292 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8294 (clobber (match_scratch:DI 3 "=1"))
8295 (clobber (reg:CC FLAGS_REG))]
8297 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299 [(set_attr "type" "imul")
8300 (set (attr "athlon_decode")
8301 (if_then_else (eq_attr "cpu" "athlon")
8302 (const_string "vector")
8303 (const_string "double")))
8304 (set_attr "amdfam10_decode" "double")
8305 (set_attr "mode" "DI")])
8307 (define_expand "smulsi3_highpart"
8308 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8311 (mult:DI (sign_extend:DI
8312 (match_operand:SI 1 "nonimmediate_operand" ""))
8314 (match_operand:SI 2 "register_operand" "")))
8316 (clobber (match_scratch:SI 3 ""))
8317 (clobber (reg:CC FLAGS_REG))])]
8321 (define_insn "*smulsi3_highpart_insn"
8322 [(set (match_operand:SI 0 "register_operand" "=d")
8325 (mult:DI (sign_extend:DI
8326 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8328 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8330 (clobber (match_scratch:SI 3 "=1"))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8334 [(set_attr "type" "imul")
8335 (set (attr "athlon_decode")
8336 (if_then_else (eq_attr "cpu" "athlon")
8337 (const_string "vector")
8338 (const_string "double")))
8339 (set_attr "amdfam10_decode" "double")
8340 (set_attr "mode" "SI")])
8342 (define_insn "*smulsi3_highpart_zext"
8343 [(set (match_operand:DI 0 "register_operand" "=d")
8344 (zero_extend:DI (truncate:SI
8346 (mult:DI (sign_extend:DI
8347 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8349 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8351 (clobber (match_scratch:SI 3 "=1"))
8352 (clobber (reg:CC FLAGS_REG))]
8354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8356 [(set_attr "type" "imul")
8357 (set (attr "athlon_decode")
8358 (if_then_else (eq_attr "cpu" "athlon")
8359 (const_string "vector")
8360 (const_string "double")))
8361 (set_attr "amdfam10_decode" "double")
8362 (set_attr "mode" "SI")])
8364 ;; The patterns that match these are at the end of this file.
8366 (define_expand "mulxf3"
8367 [(set (match_operand:XF 0 "register_operand" "")
8368 (mult:XF (match_operand:XF 1 "register_operand" "")
8369 (match_operand:XF 2 "register_operand" "")))]
8373 (define_expand "mul<mode>3"
8374 [(set (match_operand:MODEF 0 "register_operand" "")
8375 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8376 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8377 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8380 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8383 ;; Divide instructions
8385 (define_insn "divqi3"
8386 [(set (match_operand:QI 0 "register_operand" "=a")
8387 (div:QI (match_operand:HI 1 "register_operand" "0")
8388 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8389 (clobber (reg:CC FLAGS_REG))]
8390 "TARGET_QIMODE_MATH"
8392 [(set_attr "type" "idiv")
8393 (set_attr "mode" "QI")])
8395 (define_insn "udivqi3"
8396 [(set (match_operand:QI 0 "register_operand" "=a")
8397 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8398 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8399 (clobber (reg:CC FLAGS_REG))]
8400 "TARGET_QIMODE_MATH"
8402 [(set_attr "type" "idiv")
8403 (set_attr "mode" "QI")])
8405 ;; The patterns that match these are at the end of this file.
8407 (define_expand "divxf3"
8408 [(set (match_operand:XF 0 "register_operand" "")
8409 (div:XF (match_operand:XF 1 "register_operand" "")
8410 (match_operand:XF 2 "register_operand" "")))]
8414 (define_expand "divdf3"
8415 [(set (match_operand:DF 0 "register_operand" "")
8416 (div:DF (match_operand:DF 1 "register_operand" "")
8417 (match_operand:DF 2 "nonimmediate_operand" "")))]
8418 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8421 (define_expand "divsf3"
8422 [(set (match_operand:SF 0 "register_operand" "")
8423 (div:SF (match_operand:SF 1 "register_operand" "")
8424 (match_operand:SF 2 "nonimmediate_operand" "")))]
8425 "TARGET_80387 || TARGET_SSE_MATH"
8427 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8428 && flag_finite_math_only && !flag_trapping_math
8429 && flag_unsafe_math_optimizations)
8431 ix86_emit_swdivsf (operands[0], operands[1],
8432 operands[2], SFmode);
8437 ;; Remainder instructions.
8439 (define_expand "divmoddi4"
8440 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8441 (div:DI (match_operand:DI 1 "register_operand" "")
8442 (match_operand:DI 2 "nonimmediate_operand" "")))
8443 (set (match_operand:DI 3 "register_operand" "")
8444 (mod:DI (match_dup 1) (match_dup 2)))
8445 (clobber (reg:CC FLAGS_REG))])]
8449 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8450 ;; Penalize eax case slightly because it results in worse scheduling
8452 (define_insn "*divmoddi4_nocltd_rex64"
8453 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8454 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8455 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8456 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8457 (mod:DI (match_dup 2) (match_dup 3)))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8461 [(set_attr "type" "multi")])
8463 (define_insn "*divmoddi4_cltd_rex64"
8464 [(set (match_operand:DI 0 "register_operand" "=a")
8465 (div:DI (match_operand:DI 2 "register_operand" "a")
8466 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8467 (set (match_operand:DI 1 "register_operand" "=&d")
8468 (mod:DI (match_dup 2) (match_dup 3)))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8472 [(set_attr "type" "multi")])
8474 (define_insn "*divmoddi_noext_rex64"
8475 [(set (match_operand:DI 0 "register_operand" "=a")
8476 (div:DI (match_operand:DI 1 "register_operand" "0")
8477 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8478 (set (match_operand:DI 3 "register_operand" "=d")
8479 (mod:DI (match_dup 1) (match_dup 2)))
8480 (use (match_operand:DI 4 "register_operand" "3"))
8481 (clobber (reg:CC FLAGS_REG))]
8484 [(set_attr "type" "idiv")
8485 (set_attr "mode" "DI")])
8488 [(set (match_operand:DI 0 "register_operand" "")
8489 (div:DI (match_operand:DI 1 "register_operand" "")
8490 (match_operand:DI 2 "nonimmediate_operand" "")))
8491 (set (match_operand:DI 3 "register_operand" "")
8492 (mod:DI (match_dup 1) (match_dup 2)))
8493 (clobber (reg:CC FLAGS_REG))]
8494 "TARGET_64BIT && reload_completed"
8495 [(parallel [(set (match_dup 3)
8496 (ashiftrt:DI (match_dup 4) (const_int 63)))
8497 (clobber (reg:CC FLAGS_REG))])
8498 (parallel [(set (match_dup 0)
8499 (div:DI (reg:DI 0) (match_dup 2)))
8501 (mod:DI (reg:DI 0) (match_dup 2)))
8503 (clobber (reg:CC FLAGS_REG))])]
8505 /* Avoid use of cltd in favor of a mov+shift. */
8506 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8508 if (true_regnum (operands[1]))
8509 emit_move_insn (operands[0], operands[1]);
8511 emit_move_insn (operands[3], operands[1]);
8512 operands[4] = operands[3];
8516 gcc_assert (!true_regnum (operands[1]));
8517 operands[4] = operands[1];
8522 (define_expand "divmodsi4"
8523 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8524 (div:SI (match_operand:SI 1 "register_operand" "")
8525 (match_operand:SI 2 "nonimmediate_operand" "")))
8526 (set (match_operand:SI 3 "register_operand" "")
8527 (mod:SI (match_dup 1) (match_dup 2)))
8528 (clobber (reg:CC FLAGS_REG))])]
8532 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8533 ;; Penalize eax case slightly because it results in worse scheduling
8535 (define_insn "*divmodsi4_nocltd"
8536 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8537 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8538 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8539 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8540 (mod:SI (match_dup 2) (match_dup 3)))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8544 [(set_attr "type" "multi")])
8546 (define_insn "*divmodsi4_cltd"
8547 [(set (match_operand:SI 0 "register_operand" "=a")
8548 (div:SI (match_operand:SI 2 "register_operand" "a")
8549 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8550 (set (match_operand:SI 1 "register_operand" "=&d")
8551 (mod:SI (match_dup 2) (match_dup 3)))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8555 [(set_attr "type" "multi")])
8557 (define_insn "*divmodsi_noext"
8558 [(set (match_operand:SI 0 "register_operand" "=a")
8559 (div:SI (match_operand:SI 1 "register_operand" "0")
8560 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8561 (set (match_operand:SI 3 "register_operand" "=d")
8562 (mod:SI (match_dup 1) (match_dup 2)))
8563 (use (match_operand:SI 4 "register_operand" "3"))
8564 (clobber (reg:CC FLAGS_REG))]
8567 [(set_attr "type" "idiv")
8568 (set_attr "mode" "SI")])
8571 [(set (match_operand:SI 0 "register_operand" "")
8572 (div:SI (match_operand:SI 1 "register_operand" "")
8573 (match_operand:SI 2 "nonimmediate_operand" "")))
8574 (set (match_operand:SI 3 "register_operand" "")
8575 (mod:SI (match_dup 1) (match_dup 2)))
8576 (clobber (reg:CC FLAGS_REG))]
8578 [(parallel [(set (match_dup 3)
8579 (ashiftrt:SI (match_dup 4) (const_int 31)))
8580 (clobber (reg:CC FLAGS_REG))])
8581 (parallel [(set (match_dup 0)
8582 (div:SI (reg:SI 0) (match_dup 2)))
8584 (mod:SI (reg:SI 0) (match_dup 2)))
8586 (clobber (reg:CC FLAGS_REG))])]
8588 /* Avoid use of cltd in favor of a mov+shift. */
8589 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8591 if (true_regnum (operands[1]))
8592 emit_move_insn (operands[0], operands[1]);
8594 emit_move_insn (operands[3], operands[1]);
8595 operands[4] = operands[3];
8599 gcc_assert (!true_regnum (operands[1]));
8600 operands[4] = operands[1];
8604 (define_insn "divmodhi4"
8605 [(set (match_operand:HI 0 "register_operand" "=a")
8606 (div:HI (match_operand:HI 1 "register_operand" "0")
8607 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8608 (set (match_operand:HI 3 "register_operand" "=&d")
8609 (mod:HI (match_dup 1) (match_dup 2)))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_HIMODE_MATH"
8613 [(set_attr "type" "multi")
8614 (set_attr "length_immediate" "0")
8615 (set_attr "mode" "SI")])
8617 (define_insn "udivmoddi4"
8618 [(set (match_operand:DI 0 "register_operand" "=a")
8619 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8620 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8621 (set (match_operand:DI 3 "register_operand" "=&d")
8622 (umod:DI (match_dup 1) (match_dup 2)))
8623 (clobber (reg:CC FLAGS_REG))]
8625 "xor{q}\t%3, %3\;div{q}\t%2"
8626 [(set_attr "type" "multi")
8627 (set_attr "length_immediate" "0")
8628 (set_attr "mode" "DI")])
8630 (define_insn "*udivmoddi4_noext"
8631 [(set (match_operand:DI 0 "register_operand" "=a")
8632 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8633 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8634 (set (match_operand:DI 3 "register_operand" "=d")
8635 (umod:DI (match_dup 1) (match_dup 2)))
8637 (clobber (reg:CC FLAGS_REG))]
8640 [(set_attr "type" "idiv")
8641 (set_attr "mode" "DI")])
8644 [(set (match_operand:DI 0 "register_operand" "")
8645 (udiv:DI (match_operand:DI 1 "register_operand" "")
8646 (match_operand:DI 2 "nonimmediate_operand" "")))
8647 (set (match_operand:DI 3 "register_operand" "")
8648 (umod:DI (match_dup 1) (match_dup 2)))
8649 (clobber (reg:CC FLAGS_REG))]
8650 "TARGET_64BIT && reload_completed"
8651 [(set (match_dup 3) (const_int 0))
8652 (parallel [(set (match_dup 0)
8653 (udiv:DI (match_dup 1) (match_dup 2)))
8655 (umod:DI (match_dup 1) (match_dup 2)))
8657 (clobber (reg:CC FLAGS_REG))])]
8660 (define_insn "udivmodsi4"
8661 [(set (match_operand:SI 0 "register_operand" "=a")
8662 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8664 (set (match_operand:SI 3 "register_operand" "=&d")
8665 (umod:SI (match_dup 1) (match_dup 2)))
8666 (clobber (reg:CC FLAGS_REG))]
8668 "xor{l}\t%3, %3\;div{l}\t%2"
8669 [(set_attr "type" "multi")
8670 (set_attr "length_immediate" "0")
8671 (set_attr "mode" "SI")])
8673 (define_insn "*udivmodsi4_noext"
8674 [(set (match_operand:SI 0 "register_operand" "=a")
8675 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8677 (set (match_operand:SI 3 "register_operand" "=d")
8678 (umod:SI (match_dup 1) (match_dup 2)))
8680 (clobber (reg:CC FLAGS_REG))]
8683 [(set_attr "type" "idiv")
8684 (set_attr "mode" "SI")])
8687 [(set (match_operand:SI 0 "register_operand" "")
8688 (udiv:SI (match_operand:SI 1 "register_operand" "")
8689 (match_operand:SI 2 "nonimmediate_operand" "")))
8690 (set (match_operand:SI 3 "register_operand" "")
8691 (umod:SI (match_dup 1) (match_dup 2)))
8692 (clobber (reg:CC FLAGS_REG))]
8694 [(set (match_dup 3) (const_int 0))
8695 (parallel [(set (match_dup 0)
8696 (udiv:SI (match_dup 1) (match_dup 2)))
8698 (umod:SI (match_dup 1) (match_dup 2)))
8700 (clobber (reg:CC FLAGS_REG))])]
8703 (define_expand "udivmodhi4"
8704 [(set (match_dup 4) (const_int 0))
8705 (parallel [(set (match_operand:HI 0 "register_operand" "")
8706 (udiv:HI (match_operand:HI 1 "register_operand" "")
8707 (match_operand:HI 2 "nonimmediate_operand" "")))
8708 (set (match_operand:HI 3 "register_operand" "")
8709 (umod:HI (match_dup 1) (match_dup 2)))
8711 (clobber (reg:CC FLAGS_REG))])]
8712 "TARGET_HIMODE_MATH"
8713 "operands[4] = gen_reg_rtx (HImode);")
8715 (define_insn "*udivmodhi_noext"
8716 [(set (match_operand:HI 0 "register_operand" "=a")
8717 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8718 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8719 (set (match_operand:HI 3 "register_operand" "=d")
8720 (umod:HI (match_dup 1) (match_dup 2)))
8721 (use (match_operand:HI 4 "register_operand" "3"))
8722 (clobber (reg:CC FLAGS_REG))]
8725 [(set_attr "type" "idiv")
8726 (set_attr "mode" "HI")])
8728 ;; We cannot use div/idiv for double division, because it causes
8729 ;; "division by zero" on the overflow and that's not what we expect
8730 ;; from truncate. Because true (non truncating) double division is
8731 ;; never generated, we can't create this insn anyway.
8734 ; [(set (match_operand:SI 0 "register_operand" "=a")
8736 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8738 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8739 ; (set (match_operand:SI 3 "register_operand" "=d")
8741 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8742 ; (clobber (reg:CC FLAGS_REG))]
8744 ; "div{l}\t{%2, %0|%0, %2}"
8745 ; [(set_attr "type" "idiv")])
8747 ;;- Logical AND instructions
8749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8750 ;; Note that this excludes ah.
8752 (define_insn "*testdi_1_rex64"
8753 [(set (reg FLAGS_REG)
8755 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8756 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8758 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8761 test{l}\t{%k1, %k0|%k0, %k1}
8762 test{l}\t{%k1, %k0|%k0, %k1}
8763 test{q}\t{%1, %0|%0, %1}
8764 test{q}\t{%1, %0|%0, %1}
8765 test{q}\t{%1, %0|%0, %1}"
8766 [(set_attr "type" "test")
8767 (set_attr "modrm" "0,1,0,1,1")
8768 (set_attr "mode" "SI,SI,DI,DI,DI")
8769 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8771 (define_insn "testsi_1"
8772 [(set (reg FLAGS_REG)
8774 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8775 (match_operand:SI 1 "general_operand" "i,i,ri"))
8777 "ix86_match_ccmode (insn, CCNOmode)
8778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8779 "test{l}\t{%1, %0|%0, %1}"
8780 [(set_attr "type" "test")
8781 (set_attr "modrm" "0,1,1")
8782 (set_attr "mode" "SI")
8783 (set_attr "pent_pair" "uv,np,uv")])
8785 (define_expand "testsi_ccno_1"
8786 [(set (reg:CCNO FLAGS_REG)
8788 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8789 (match_operand:SI 1 "nonmemory_operand" ""))
8794 (define_insn "*testhi_1"
8795 [(set (reg FLAGS_REG)
8796 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8797 (match_operand:HI 1 "general_operand" "n,n,rn"))
8799 "ix86_match_ccmode (insn, CCNOmode)
8800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8801 "test{w}\t{%1, %0|%0, %1}"
8802 [(set_attr "type" "test")
8803 (set_attr "modrm" "0,1,1")
8804 (set_attr "mode" "HI")
8805 (set_attr "pent_pair" "uv,np,uv")])
8807 (define_expand "testqi_ccz_1"
8808 [(set (reg:CCZ FLAGS_REG)
8809 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8810 (match_operand:QI 1 "nonmemory_operand" ""))
8815 (define_insn "*testqi_1_maybe_si"
8816 [(set (reg FLAGS_REG)
8819 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8820 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8822 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8823 && ix86_match_ccmode (insn,
8824 CONST_INT_P (operands[1])
8825 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8827 if (which_alternative == 3)
8829 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8830 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8831 return "test{l}\t{%1, %k0|%k0, %1}";
8833 return "test{b}\t{%1, %0|%0, %1}";
8835 [(set_attr "type" "test")
8836 (set_attr "modrm" "0,1,1,1")
8837 (set_attr "mode" "QI,QI,QI,SI")
8838 (set_attr "pent_pair" "uv,np,uv,np")])
8840 (define_insn "*testqi_1"
8841 [(set (reg FLAGS_REG)
8844 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8845 (match_operand:QI 1 "general_operand" "n,n,qn"))
8847 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8848 && ix86_match_ccmode (insn, CCNOmode)"
8849 "test{b}\t{%1, %0|%0, %1}"
8850 [(set_attr "type" "test")
8851 (set_attr "modrm" "0,1,1")
8852 (set_attr "mode" "QI")
8853 (set_attr "pent_pair" "uv,np,uv")])
8855 (define_expand "testqi_ext_ccno_0"
8856 [(set (reg:CCNO FLAGS_REG)
8860 (match_operand 0 "ext_register_operand" "")
8863 (match_operand 1 "const_int_operand" ""))
8868 (define_insn "*testqi_ext_0"
8869 [(set (reg FLAGS_REG)
8873 (match_operand 0 "ext_register_operand" "Q")
8876 (match_operand 1 "const_int_operand" "n"))
8878 "ix86_match_ccmode (insn, CCNOmode)"
8879 "test{b}\t{%1, %h0|%h0, %1}"
8880 [(set_attr "type" "test")
8881 (set_attr "mode" "QI")
8882 (set_attr "length_immediate" "1")
8883 (set_attr "pent_pair" "np")])
8885 (define_insn "*testqi_ext_1"
8886 [(set (reg FLAGS_REG)
8890 (match_operand 0 "ext_register_operand" "Q")
8894 (match_operand:QI 1 "general_operand" "Qm")))
8896 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898 "test{b}\t{%1, %h0|%h0, %1}"
8899 [(set_attr "type" "test")
8900 (set_attr "mode" "QI")])
8902 (define_insn "*testqi_ext_1_rex64"
8903 [(set (reg FLAGS_REG)
8907 (match_operand 0 "ext_register_operand" "Q")
8911 (match_operand:QI 1 "register_operand" "Q")))
8913 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8914 "test{b}\t{%1, %h0|%h0, %1}"
8915 [(set_attr "type" "test")
8916 (set_attr "mode" "QI")])
8918 (define_insn "*testqi_ext_2"
8919 [(set (reg FLAGS_REG)
8923 (match_operand 0 "ext_register_operand" "Q")
8927 (match_operand 1 "ext_register_operand" "Q")
8931 "ix86_match_ccmode (insn, CCNOmode)"
8932 "test{b}\t{%h1, %h0|%h0, %h1}"
8933 [(set_attr "type" "test")
8934 (set_attr "mode" "QI")])
8936 ;; Combine likes to form bit extractions for some tests. Humor it.
8937 (define_insn "*testqi_ext_3"
8938 [(set (reg FLAGS_REG)
8939 (compare (zero_extract:SI
8940 (match_operand 0 "nonimmediate_operand" "rm")
8941 (match_operand:SI 1 "const_int_operand" "")
8942 (match_operand:SI 2 "const_int_operand" ""))
8944 "ix86_match_ccmode (insn, CCNOmode)
8945 && INTVAL (operands[1]) > 0
8946 && INTVAL (operands[2]) >= 0
8947 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8948 && (GET_MODE (operands[0]) == SImode
8949 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8950 || GET_MODE (operands[0]) == HImode
8951 || GET_MODE (operands[0]) == QImode)"
8954 (define_insn "*testqi_ext_3_rex64"
8955 [(set (reg FLAGS_REG)
8956 (compare (zero_extract:DI
8957 (match_operand 0 "nonimmediate_operand" "rm")
8958 (match_operand:DI 1 "const_int_operand" "")
8959 (match_operand:DI 2 "const_int_operand" ""))
8962 && ix86_match_ccmode (insn, CCNOmode)
8963 && INTVAL (operands[1]) > 0
8964 && INTVAL (operands[2]) >= 0
8965 /* Ensure that resulting mask is zero or sign extended operand. */
8966 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8967 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8968 && INTVAL (operands[1]) > 32))
8969 && (GET_MODE (operands[0]) == SImode
8970 || GET_MODE (operands[0]) == DImode
8971 || GET_MODE (operands[0]) == HImode
8972 || GET_MODE (operands[0]) == QImode)"
8976 [(set (match_operand 0 "flags_reg_operand" "")
8977 (match_operator 1 "compare_operator"
8979 (match_operand 2 "nonimmediate_operand" "")
8980 (match_operand 3 "const_int_operand" "")
8981 (match_operand 4 "const_int_operand" ""))
8983 "ix86_match_ccmode (insn, CCNOmode)"
8984 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8986 rtx val = operands[2];
8987 HOST_WIDE_INT len = INTVAL (operands[3]);
8988 HOST_WIDE_INT pos = INTVAL (operands[4]);
8990 enum machine_mode mode, submode;
8992 mode = GET_MODE (val);
8995 /* ??? Combine likes to put non-volatile mem extractions in QImode
8996 no matter the size of the test. So find a mode that works. */
8997 if (! MEM_VOLATILE_P (val))
8999 mode = smallest_mode_for_size (pos + len, MODE_INT);
9000 val = adjust_address (val, mode, 0);
9003 else if (GET_CODE (val) == SUBREG
9004 && (submode = GET_MODE (SUBREG_REG (val)),
9005 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9006 && pos + len <= GET_MODE_BITSIZE (submode))
9008 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9010 val = SUBREG_REG (val);
9012 else if (mode == HImode && pos + len <= 8)
9014 /* Small HImode tests can be converted to QImode. */
9016 val = gen_lowpart (QImode, val);
9019 if (len == HOST_BITS_PER_WIDE_INT)
9022 mask = ((HOST_WIDE_INT)1 << len) - 1;
9025 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9028 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9029 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9030 ;; this is relatively important trick.
9031 ;; Do the conversion only post-reload to avoid limiting of the register class
9034 [(set (match_operand 0 "flags_reg_operand" "")
9035 (match_operator 1 "compare_operator"
9036 [(and (match_operand 2 "register_operand" "")
9037 (match_operand 3 "const_int_operand" ""))
9040 && QI_REG_P (operands[2])
9041 && GET_MODE (operands[2]) != QImode
9042 && ((ix86_match_ccmode (insn, CCZmode)
9043 && !(INTVAL (operands[3]) & ~(255 << 8)))
9044 || (ix86_match_ccmode (insn, CCNOmode)
9045 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9048 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9051 "operands[2] = gen_lowpart (SImode, operands[2]);
9052 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9055 [(set (match_operand 0 "flags_reg_operand" "")
9056 (match_operator 1 "compare_operator"
9057 [(and (match_operand 2 "nonimmediate_operand" "")
9058 (match_operand 3 "const_int_operand" ""))
9061 && GET_MODE (operands[2]) != QImode
9062 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9063 && ((ix86_match_ccmode (insn, CCZmode)
9064 && !(INTVAL (operands[3]) & ~255))
9065 || (ix86_match_ccmode (insn, CCNOmode)
9066 && !(INTVAL (operands[3]) & ~127)))"
9068 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9070 "operands[2] = gen_lowpart (QImode, operands[2]);
9071 operands[3] = gen_lowpart (QImode, operands[3]);")
9074 ;; %%% This used to optimize known byte-wide and operations to memory,
9075 ;; and sometimes to QImode registers. If this is considered useful,
9076 ;; it should be done with splitters.
9078 (define_expand "anddi3"
9079 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9080 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9081 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9083 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9085 (define_insn "*anddi_1_rex64"
9086 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9087 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9089 (clobber (reg:CC FLAGS_REG))]
9090 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9092 switch (get_attr_type (insn))
9096 enum machine_mode mode;
9098 gcc_assert (CONST_INT_P (operands[2]));
9099 if (INTVAL (operands[2]) == 0xff)
9103 gcc_assert (INTVAL (operands[2]) == 0xffff);
9107 operands[1] = gen_lowpart (mode, operands[1]);
9109 return "movz{bq|x}\t{%1,%0|%0, %1}";
9111 return "movz{wq|x}\t{%1,%0|%0, %1}";
9115 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9116 if (get_attr_mode (insn) == MODE_SI)
9117 return "and{l}\t{%k2, %k0|%k0, %k2}";
9119 return "and{q}\t{%2, %0|%0, %2}";
9122 [(set_attr "type" "alu,alu,alu,imovx")
9123 (set_attr "length_immediate" "*,*,*,0")
9124 (set_attr "mode" "SI,DI,DI,DI")])
9126 (define_insn "*anddi_2"
9127 [(set (reg FLAGS_REG)
9128 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9129 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9131 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9132 (and:DI (match_dup 1) (match_dup 2)))]
9133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9134 && ix86_binary_operator_ok (AND, DImode, operands)"
9136 and{l}\t{%k2, %k0|%k0, %k2}
9137 and{q}\t{%2, %0|%0, %2}
9138 and{q}\t{%2, %0|%0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "mode" "SI,DI,DI")])
9142 (define_expand "andsi3"
9143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9144 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9145 (match_operand:SI 2 "general_operand" "")))]
9147 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9149 (define_insn "*andsi_1"
9150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9151 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9152 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9153 (clobber (reg:CC FLAGS_REG))]
9154 "ix86_binary_operator_ok (AND, SImode, operands)"
9156 switch (get_attr_type (insn))
9160 enum machine_mode mode;
9162 gcc_assert (CONST_INT_P (operands[2]));
9163 if (INTVAL (operands[2]) == 0xff)
9167 gcc_assert (INTVAL (operands[2]) == 0xffff);
9171 operands[1] = gen_lowpart (mode, operands[1]);
9173 return "movz{bl|x}\t{%1,%0|%0, %1}";
9175 return "movz{wl|x}\t{%1,%0|%0, %1}";
9179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9180 return "and{l}\t{%2, %0|%0, %2}";
9183 [(set_attr "type" "alu,alu,imovx")
9184 (set_attr "length_immediate" "*,*,0")
9185 (set_attr "mode" "SI")])
9188 [(set (match_operand 0 "register_operand" "")
9190 (const_int -65536)))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9193 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9194 "operands[1] = gen_lowpart (HImode, operands[0]);")
9197 [(set (match_operand 0 "ext_register_operand" "")
9200 (clobber (reg:CC FLAGS_REG))]
9201 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9202 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9203 "operands[1] = gen_lowpart (QImode, operands[0]);")
9206 [(set (match_operand 0 "ext_register_operand" "")
9208 (const_int -65281)))
9209 (clobber (reg:CC FLAGS_REG))]
9210 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9211 [(parallel [(set (zero_extract:SI (match_dup 0)
9215 (zero_extract:SI (match_dup 0)
9218 (zero_extract:SI (match_dup 0)
9221 (clobber (reg:CC FLAGS_REG))])]
9222 "operands[0] = gen_lowpart (SImode, operands[0]);")
9224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9225 (define_insn "*andsi_1_zext"
9226 [(set (match_operand:DI 0 "register_operand" "=r")
9228 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9229 (match_operand:SI 2 "general_operand" "g"))))
9230 (clobber (reg:CC FLAGS_REG))]
9231 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9232 "and{l}\t{%2, %k0|%k0, %2}"
9233 [(set_attr "type" "alu")
9234 (set_attr "mode" "SI")])
9236 (define_insn "*andsi_2"
9237 [(set (reg FLAGS_REG)
9238 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9239 (match_operand:SI 2 "general_operand" "g,ri"))
9241 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9242 (and:SI (match_dup 1) (match_dup 2)))]
9243 "ix86_match_ccmode (insn, CCNOmode)
9244 && ix86_binary_operator_ok (AND, SImode, operands)"
9245 "and{l}\t{%2, %0|%0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "mode" "SI")])
9249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9250 (define_insn "*andsi_2_zext"
9251 [(set (reg FLAGS_REG)
9252 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9253 (match_operand:SI 2 "general_operand" "g"))
9255 (set (match_operand:DI 0 "register_operand" "=r")
9256 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258 && ix86_binary_operator_ok (AND, SImode, operands)"
9259 "and{l}\t{%2, %k0|%k0, %2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "mode" "SI")])
9263 (define_expand "andhi3"
9264 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9265 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9266 (match_operand:HI 2 "general_operand" "")))]
9267 "TARGET_HIMODE_MATH"
9268 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9270 (define_insn "*andhi_1"
9271 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9272 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9273 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "ix86_binary_operator_ok (AND, HImode, operands)"
9277 switch (get_attr_type (insn))
9280 gcc_assert (CONST_INT_P (operands[2]));
9281 gcc_assert (INTVAL (operands[2]) == 0xff);
9282 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287 return "and{w}\t{%2, %0|%0, %2}";
9290 [(set_attr "type" "alu,alu,imovx")
9291 (set_attr "length_immediate" "*,*,0")
9292 (set_attr "mode" "HI,HI,SI")])
9294 (define_insn "*andhi_2"
9295 [(set (reg FLAGS_REG)
9296 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9297 (match_operand:HI 2 "general_operand" "rmn,rn"))
9299 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9300 (and:HI (match_dup 1) (match_dup 2)))]
9301 "ix86_match_ccmode (insn, CCNOmode)
9302 && ix86_binary_operator_ok (AND, HImode, operands)"
9303 "and{w}\t{%2, %0|%0, %2}"
9304 [(set_attr "type" "alu")
9305 (set_attr "mode" "HI")])
9307 (define_expand "andqi3"
9308 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9309 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9310 (match_operand:QI 2 "general_operand" "")))]
9311 "TARGET_QIMODE_MATH"
9312 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9314 ;; %%% Potential partial reg stall on alternative 2. What to do?
9315 (define_insn "*andqi_1"
9316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9317 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9318 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "ix86_binary_operator_ok (AND, QImode, operands)"
9322 and{b}\t{%2, %0|%0, %2}
9323 and{b}\t{%2, %0|%0, %2}
9324 and{l}\t{%k2, %k0|%k0, %k2}"
9325 [(set_attr "type" "alu")
9326 (set_attr "mode" "QI,QI,SI")])
9328 (define_insn "*andqi_1_slp"
9329 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9330 (and:QI (match_dup 0)
9331 (match_operand:QI 1 "general_operand" "qn,qmn")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9334 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9335 "and{b}\t{%1, %0|%0, %1}"
9336 [(set_attr "type" "alu1")
9337 (set_attr "mode" "QI")])
9339 (define_insn "*andqi_2_maybe_si"
9340 [(set (reg FLAGS_REG)
9342 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9343 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9345 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9346 (and:QI (match_dup 1) (match_dup 2)))]
9347 "ix86_binary_operator_ok (AND, QImode, operands)
9348 && ix86_match_ccmode (insn,
9349 CONST_INT_P (operands[2])
9350 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9352 if (which_alternative == 2)
9354 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9355 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9356 return "and{l}\t{%2, %k0|%k0, %2}";
9358 return "and{b}\t{%2, %0|%0, %2}";
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "QI,QI,SI")])
9363 (define_insn "*andqi_2"
9364 [(set (reg FLAGS_REG)
9366 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:QI 2 "general_operand" "qmn,qn"))
9369 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9370 (and:QI (match_dup 1) (match_dup 2)))]
9371 "ix86_match_ccmode (insn, CCNOmode)
9372 && ix86_binary_operator_ok (AND, QImode, operands)"
9373 "and{b}\t{%2, %0|%0, %2}"
9374 [(set_attr "type" "alu")
9375 (set_attr "mode" "QI")])
9377 (define_insn "*andqi_2_slp"
9378 [(set (reg FLAGS_REG)
9380 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9381 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9383 (set (strict_low_part (match_dup 0))
9384 (and:QI (match_dup 0) (match_dup 1)))]
9385 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9386 && ix86_match_ccmode (insn, CCNOmode)
9387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388 "and{b}\t{%1, %0|%0, %1}"
9389 [(set_attr "type" "alu1")
9390 (set_attr "mode" "QI")])
9392 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9393 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9394 ;; for a QImode operand, which of course failed.
9396 (define_insn "andqi_ext_0"
9397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9402 (match_operand 1 "ext_register_operand" "0")
9405 (match_operand 2 "const_int_operand" "n")))
9406 (clobber (reg:CC FLAGS_REG))]
9408 "and{b}\t{%2, %h0|%h0, %2}"
9409 [(set_attr "type" "alu")
9410 (set_attr "length_immediate" "1")
9411 (set_attr "mode" "QI")])
9413 ;; Generated by peephole translating test to and. This shows up
9414 ;; often in fp comparisons.
9416 (define_insn "*andqi_ext_0_cc"
9417 [(set (reg FLAGS_REG)
9421 (match_operand 1 "ext_register_operand" "0")
9424 (match_operand 2 "const_int_operand" "n"))
9426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9435 "ix86_match_ccmode (insn, CCNOmode)"
9436 "and{b}\t{%2, %h0|%h0, %2}"
9437 [(set_attr "type" "alu")
9438 (set_attr "length_immediate" "1")
9439 (set_attr "mode" "QI")])
9441 (define_insn "*andqi_ext_1"
9442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9447 (match_operand 1 "ext_register_operand" "0")
9451 (match_operand:QI 2 "general_operand" "Qm"))))
9452 (clobber (reg:CC FLAGS_REG))]
9454 "and{b}\t{%2, %h0|%h0, %2}"
9455 [(set_attr "type" "alu")
9456 (set_attr "length_immediate" "0")
9457 (set_attr "mode" "QI")])
9459 (define_insn "*andqi_ext_1_rex64"
9460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9465 (match_operand 1 "ext_register_operand" "0")
9469 (match_operand 2 "ext_register_operand" "Q"))))
9470 (clobber (reg:CC FLAGS_REG))]
9472 "and{b}\t{%2, %h0|%h0, %2}"
9473 [(set_attr "type" "alu")
9474 (set_attr "length_immediate" "0")
9475 (set_attr "mode" "QI")])
9477 (define_insn "*andqi_ext_2"
9478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (match_operand 1 "ext_register_operand" "%0")
9487 (match_operand 2 "ext_register_operand" "Q")
9490 (clobber (reg:CC FLAGS_REG))]
9492 "and{b}\t{%h2, %h0|%h0, %h2}"
9493 [(set_attr "type" "alu")
9494 (set_attr "length_immediate" "0")
9495 (set_attr "mode" "QI")])
9497 ;; Convert wide AND instructions with immediate operand to shorter QImode
9498 ;; equivalents when possible.
9499 ;; Don't do the splitting with memory operands, since it introduces risk
9500 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9501 ;; for size, but that can (should?) be handled by generic code instead.
9503 [(set (match_operand 0 "register_operand" "")
9504 (and (match_operand 1 "register_operand" "")
9505 (match_operand 2 "const_int_operand" "")))
9506 (clobber (reg:CC FLAGS_REG))]
9508 && QI_REG_P (operands[0])
9509 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9510 && !(~INTVAL (operands[2]) & ~(255 << 8))
9511 && GET_MODE (operands[0]) != QImode"
9512 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9513 (and:SI (zero_extract:SI (match_dup 1)
9514 (const_int 8) (const_int 8))
9516 (clobber (reg:CC FLAGS_REG))])]
9517 "operands[0] = gen_lowpart (SImode, operands[0]);
9518 operands[1] = gen_lowpart (SImode, operands[1]);
9519 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521 ;; Since AND can be encoded with sign extended immediate, this is only
9522 ;; profitable when 7th bit is not set.
9524 [(set (match_operand 0 "register_operand" "")
9525 (and (match_operand 1 "general_operand" "")
9526 (match_operand 2 "const_int_operand" "")))
9527 (clobber (reg:CC FLAGS_REG))]
9529 && ANY_QI_REG_P (operands[0])
9530 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9531 && !(~INTVAL (operands[2]) & ~255)
9532 && !(INTVAL (operands[2]) & 128)
9533 && GET_MODE (operands[0]) != QImode"
9534 [(parallel [(set (strict_low_part (match_dup 0))
9535 (and:QI (match_dup 1)
9537 (clobber (reg:CC FLAGS_REG))])]
9538 "operands[0] = gen_lowpart (QImode, operands[0]);
9539 operands[1] = gen_lowpart (QImode, operands[1]);
9540 operands[2] = gen_lowpart (QImode, operands[2]);")
9542 ;; Logical inclusive OR instructions
9544 ;; %%% This used to optimize known byte-wide and operations to memory.
9545 ;; If this is considered useful, it should be done with splitters.
9547 (define_expand "iordi3"
9548 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9549 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9550 (match_operand:DI 2 "x86_64_general_operand" "")))]
9552 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9554 (define_insn "*iordi_1_rex64"
9555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9556 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9557 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9558 (clobber (reg:CC FLAGS_REG))]
9560 && ix86_binary_operator_ok (IOR, DImode, operands)"
9561 "or{q}\t{%2, %0|%0, %2}"
9562 [(set_attr "type" "alu")
9563 (set_attr "mode" "DI")])
9565 (define_insn "*iordi_2_rex64"
9566 [(set (reg FLAGS_REG)
9567 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9568 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9570 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9571 (ior:DI (match_dup 1) (match_dup 2)))]
9573 && ix86_match_ccmode (insn, CCNOmode)
9574 && ix86_binary_operator_ok (IOR, DImode, operands)"
9575 "or{q}\t{%2, %0|%0, %2}"
9576 [(set_attr "type" "alu")
9577 (set_attr "mode" "DI")])
9579 (define_insn "*iordi_3_rex64"
9580 [(set (reg FLAGS_REG)
9581 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9582 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9584 (clobber (match_scratch:DI 0 "=r"))]
9586 && ix86_match_ccmode (insn, CCNOmode)
9587 && ix86_binary_operator_ok (IOR, DImode, operands)"
9588 "or{q}\t{%2, %0|%0, %2}"
9589 [(set_attr "type" "alu")
9590 (set_attr "mode" "DI")])
9593 (define_expand "iorsi3"
9594 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9595 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9596 (match_operand:SI 2 "general_operand" "")))]
9598 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9600 (define_insn "*iorsi_1"
9601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9602 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9603 (match_operand:SI 2 "general_operand" "ri,g")))
9604 (clobber (reg:CC FLAGS_REG))]
9605 "ix86_binary_operator_ok (IOR, SImode, operands)"
9606 "or{l}\t{%2, %0|%0, %2}"
9607 [(set_attr "type" "alu")
9608 (set_attr "mode" "SI")])
9610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9611 (define_insn "*iorsi_1_zext"
9612 [(set (match_operand:DI 0 "register_operand" "=r")
9614 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9615 (match_operand:SI 2 "general_operand" "g"))))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9618 "or{l}\t{%2, %k0|%k0, %2}"
9619 [(set_attr "type" "alu")
9620 (set_attr "mode" "SI")])
9622 (define_insn "*iorsi_1_zext_imm"
9623 [(set (match_operand:DI 0 "register_operand" "=r")
9624 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9625 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9626 (clobber (reg:CC FLAGS_REG))]
9628 "or{l}\t{%2, %k0|%k0, %2}"
9629 [(set_attr "type" "alu")
9630 (set_attr "mode" "SI")])
9632 (define_insn "*iorsi_2"
9633 [(set (reg FLAGS_REG)
9634 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635 (match_operand:SI 2 "general_operand" "g,ri"))
9637 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9638 (ior:SI (match_dup 1) (match_dup 2)))]
9639 "ix86_match_ccmode (insn, CCNOmode)
9640 && ix86_binary_operator_ok (IOR, SImode, operands)"
9641 "or{l}\t{%2, %0|%0, %2}"
9642 [(set_attr "type" "alu")
9643 (set_attr "mode" "SI")])
9645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9646 ;; ??? Special case for immediate operand is missing - it is tricky.
9647 (define_insn "*iorsi_2_zext"
9648 [(set (reg FLAGS_REG)
9649 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9650 (match_operand:SI 2 "general_operand" "g"))
9652 (set (match_operand:DI 0 "register_operand" "=r")
9653 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9654 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9655 && ix86_binary_operator_ok (IOR, SImode, operands)"
9656 "or{l}\t{%2, %k0|%k0, %2}"
9657 [(set_attr "type" "alu")
9658 (set_attr "mode" "SI")])
9660 (define_insn "*iorsi_2_zext_imm"
9661 [(set (reg FLAGS_REG)
9662 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9665 (set (match_operand:DI 0 "register_operand" "=r")
9666 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9668 && ix86_binary_operator_ok (IOR, SImode, operands)"
9669 "or{l}\t{%2, %k0|%k0, %2}"
9670 [(set_attr "type" "alu")
9671 (set_attr "mode" "SI")])
9673 (define_insn "*iorsi_3"
9674 [(set (reg FLAGS_REG)
9675 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9676 (match_operand:SI 2 "general_operand" "g"))
9678 (clobber (match_scratch:SI 0 "=r"))]
9679 "ix86_match_ccmode (insn, CCNOmode)
9680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9681 "or{l}\t{%2, %0|%0, %2}"
9682 [(set_attr "type" "alu")
9683 (set_attr "mode" "SI")])
9685 (define_expand "iorhi3"
9686 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9687 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9688 (match_operand:HI 2 "general_operand" "")))]
9689 "TARGET_HIMODE_MATH"
9690 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9692 (define_insn "*iorhi_1"
9693 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9694 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9695 (match_operand:HI 2 "general_operand" "rmn,rn")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "ix86_binary_operator_ok (IOR, HImode, operands)"
9698 "or{w}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "alu")
9700 (set_attr "mode" "HI")])
9702 (define_insn "*iorhi_2"
9703 [(set (reg FLAGS_REG)
9704 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9705 (match_operand:HI 2 "general_operand" "rmn,rn"))
9707 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9708 (ior:HI (match_dup 1) (match_dup 2)))]
9709 "ix86_match_ccmode (insn, CCNOmode)
9710 && ix86_binary_operator_ok (IOR, HImode, operands)"
9711 "or{w}\t{%2, %0|%0, %2}"
9712 [(set_attr "type" "alu")
9713 (set_attr "mode" "HI")])
9715 (define_insn "*iorhi_3"
9716 [(set (reg FLAGS_REG)
9717 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9718 (match_operand:HI 2 "general_operand" "rmn"))
9720 (clobber (match_scratch:HI 0 "=r"))]
9721 "ix86_match_ccmode (insn, CCNOmode)
9722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723 "or{w}\t{%2, %0|%0, %2}"
9724 [(set_attr "type" "alu")
9725 (set_attr "mode" "HI")])
9727 (define_expand "iorqi3"
9728 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9729 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9730 (match_operand:QI 2 "general_operand" "")))]
9731 "TARGET_QIMODE_MATH"
9732 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9734 ;; %%% Potential partial reg stall on alternative 2. What to do?
9735 (define_insn "*iorqi_1"
9736 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9737 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9738 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "ix86_binary_operator_ok (IOR, QImode, operands)"
9742 or{b}\t{%2, %0|%0, %2}
9743 or{b}\t{%2, %0|%0, %2}
9744 or{l}\t{%k2, %k0|%k0, %k2}"
9745 [(set_attr "type" "alu")
9746 (set_attr "mode" "QI,QI,SI")])
9748 (define_insn "*iorqi_1_slp"
9749 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9750 (ior:QI (match_dup 0)
9751 (match_operand:QI 1 "general_operand" "qmn,qn")))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9754 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9755 "or{b}\t{%1, %0|%0, %1}"
9756 [(set_attr "type" "alu1")
9757 (set_attr "mode" "QI")])
9759 (define_insn "*iorqi_2"
9760 [(set (reg FLAGS_REG)
9761 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9762 (match_operand:QI 2 "general_operand" "qmn,qn"))
9764 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9765 (ior:QI (match_dup 1) (match_dup 2)))]
9766 "ix86_match_ccmode (insn, CCNOmode)
9767 && ix86_binary_operator_ok (IOR, QImode, operands)"
9768 "or{b}\t{%2, %0|%0, %2}"
9769 [(set_attr "type" "alu")
9770 (set_attr "mode" "QI")])
9772 (define_insn "*iorqi_2_slp"
9773 [(set (reg FLAGS_REG)
9774 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9775 (match_operand:QI 1 "general_operand" "qmn,qn"))
9777 (set (strict_low_part (match_dup 0))
9778 (ior:QI (match_dup 0) (match_dup 1)))]
9779 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9780 && ix86_match_ccmode (insn, CCNOmode)
9781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9782 "or{b}\t{%1, %0|%0, %1}"
9783 [(set_attr "type" "alu1")
9784 (set_attr "mode" "QI")])
9786 (define_insn "*iorqi_3"
9787 [(set (reg FLAGS_REG)
9788 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9789 (match_operand:QI 2 "general_operand" "qmn"))
9791 (clobber (match_scratch:QI 0 "=q"))]
9792 "ix86_match_ccmode (insn, CCNOmode)
9793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9794 "or{b}\t{%2, %0|%0, %2}"
9795 [(set_attr "type" "alu")
9796 (set_attr "mode" "QI")])
9798 (define_insn "*iorqi_ext_0"
9799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9804 (match_operand 1 "ext_register_operand" "0")
9807 (match_operand 2 "const_int_operand" "n")))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9810 "or{b}\t{%2, %h0|%h0, %2}"
9811 [(set_attr "type" "alu")
9812 (set_attr "length_immediate" "1")
9813 (set_attr "mode" "QI")])
9815 (define_insn "*iorqi_ext_1"
9816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9821 (match_operand 1 "ext_register_operand" "0")
9825 (match_operand:QI 2 "general_operand" "Qm"))))
9826 (clobber (reg:CC FLAGS_REG))]
9828 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9829 "or{b}\t{%2, %h0|%h0, %2}"
9830 [(set_attr "type" "alu")
9831 (set_attr "length_immediate" "0")
9832 (set_attr "mode" "QI")])
9834 (define_insn "*iorqi_ext_1_rex64"
9835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9840 (match_operand 1 "ext_register_operand" "0")
9844 (match_operand 2 "ext_register_operand" "Q"))))
9845 (clobber (reg:CC FLAGS_REG))]
9847 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9848 "or{b}\t{%2, %h0|%h0, %2}"
9849 [(set_attr "type" "alu")
9850 (set_attr "length_immediate" "0")
9851 (set_attr "mode" "QI")])
9853 (define_insn "*iorqi_ext_2"
9854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9858 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9861 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9864 (clobber (reg:CC FLAGS_REG))]
9865 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9866 "ior{b}\t{%h2, %h0|%h0, %h2}"
9867 [(set_attr "type" "alu")
9868 (set_attr "length_immediate" "0")
9869 (set_attr "mode" "QI")])
9872 [(set (match_operand 0 "register_operand" "")
9873 (ior (match_operand 1 "register_operand" "")
9874 (match_operand 2 "const_int_operand" "")))
9875 (clobber (reg:CC FLAGS_REG))]
9877 && QI_REG_P (operands[0])
9878 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9879 && !(INTVAL (operands[2]) & ~(255 << 8))
9880 && GET_MODE (operands[0]) != QImode"
9881 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9882 (ior:SI (zero_extract:SI (match_dup 1)
9883 (const_int 8) (const_int 8))
9885 (clobber (reg:CC FLAGS_REG))])]
9886 "operands[0] = gen_lowpart (SImode, operands[0]);
9887 operands[1] = gen_lowpart (SImode, operands[1]);
9888 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9890 ;; Since OR can be encoded with sign extended immediate, this is only
9891 ;; profitable when 7th bit is set.
9893 [(set (match_operand 0 "register_operand" "")
9894 (ior (match_operand 1 "general_operand" "")
9895 (match_operand 2 "const_int_operand" "")))
9896 (clobber (reg:CC FLAGS_REG))]
9898 && ANY_QI_REG_P (operands[0])
9899 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9900 && !(INTVAL (operands[2]) & ~255)
9901 && (INTVAL (operands[2]) & 128)
9902 && GET_MODE (operands[0]) != QImode"
9903 [(parallel [(set (strict_low_part (match_dup 0))
9904 (ior:QI (match_dup 1)
9906 (clobber (reg:CC FLAGS_REG))])]
9907 "operands[0] = gen_lowpart (QImode, operands[0]);
9908 operands[1] = gen_lowpart (QImode, operands[1]);
9909 operands[2] = gen_lowpart (QImode, operands[2]);")
9911 ;; Logical XOR instructions
9913 ;; %%% This used to optimize known byte-wide and operations to memory.
9914 ;; If this is considered useful, it should be done with splitters.
9916 (define_expand "xordi3"
9917 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9918 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9919 (match_operand:DI 2 "x86_64_general_operand" "")))]
9921 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9923 (define_insn "*xordi_1_rex64"
9924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9925 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9926 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9927 (clobber (reg:CC FLAGS_REG))]
9929 && ix86_binary_operator_ok (XOR, DImode, operands)"
9930 "xor{q}\t{%2, %0|%0, %2}"
9931 [(set_attr "type" "alu")
9932 (set_attr "mode" "DI")])
9934 (define_insn "*xordi_2_rex64"
9935 [(set (reg FLAGS_REG)
9936 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9937 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9939 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9940 (xor:DI (match_dup 1) (match_dup 2)))]
9942 && ix86_match_ccmode (insn, CCNOmode)
9943 && ix86_binary_operator_ok (XOR, DImode, operands)"
9944 "xor{q}\t{%2, %0|%0, %2}"
9945 [(set_attr "type" "alu")
9946 (set_attr "mode" "DI")])
9948 (define_insn "*xordi_3_rex64"
9949 [(set (reg FLAGS_REG)
9950 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9951 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9953 (clobber (match_scratch:DI 0 "=r"))]
9955 && ix86_match_ccmode (insn, CCNOmode)
9956 && ix86_binary_operator_ok (XOR, DImode, operands)"
9957 "xor{q}\t{%2, %0|%0, %2}"
9958 [(set_attr "type" "alu")
9959 (set_attr "mode" "DI")])
9961 (define_expand "xorsi3"
9962 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9963 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9964 (match_operand:SI 2 "general_operand" "")))]
9966 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9968 (define_insn "*xorsi_1"
9969 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9970 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9971 (match_operand:SI 2 "general_operand" "ri,rm")))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "ix86_binary_operator_ok (XOR, SImode, operands)"
9974 "xor{l}\t{%2, %0|%0, %2}"
9975 [(set_attr "type" "alu")
9976 (set_attr "mode" "SI")])
9978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9979 ;; Add speccase for immediates
9980 (define_insn "*xorsi_1_zext"
9981 [(set (match_operand:DI 0 "register_operand" "=r")
9983 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9984 (match_operand:SI 2 "general_operand" "g"))))
9985 (clobber (reg:CC FLAGS_REG))]
9986 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9987 "xor{l}\t{%2, %k0|%k0, %2}"
9988 [(set_attr "type" "alu")
9989 (set_attr "mode" "SI")])
9991 (define_insn "*xorsi_1_zext_imm"
9992 [(set (match_operand:DI 0 "register_operand" "=r")
9993 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9994 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9997 "xor{l}\t{%2, %k0|%k0, %2}"
9998 [(set_attr "type" "alu")
9999 (set_attr "mode" "SI")])
10001 (define_insn "*xorsi_2"
10002 [(set (reg FLAGS_REG)
10003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10004 (match_operand:SI 2 "general_operand" "g,ri"))
10006 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10007 (xor:SI (match_dup 1) (match_dup 2)))]
10008 "ix86_match_ccmode (insn, CCNOmode)
10009 && ix86_binary_operator_ok (XOR, SImode, operands)"
10010 "xor{l}\t{%2, %0|%0, %2}"
10011 [(set_attr "type" "alu")
10012 (set_attr "mode" "SI")])
10014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10015 ;; ??? Special case for immediate operand is missing - it is tricky.
10016 (define_insn "*xorsi_2_zext"
10017 [(set (reg FLAGS_REG)
10018 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10019 (match_operand:SI 2 "general_operand" "g"))
10021 (set (match_operand:DI 0 "register_operand" "=r")
10022 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10023 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10024 && ix86_binary_operator_ok (XOR, SImode, operands)"
10025 "xor{l}\t{%2, %k0|%k0, %2}"
10026 [(set_attr "type" "alu")
10027 (set_attr "mode" "SI")])
10029 (define_insn "*xorsi_2_zext_imm"
10030 [(set (reg FLAGS_REG)
10031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10032 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10034 (set (match_operand:DI 0 "register_operand" "=r")
10035 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10036 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037 && ix86_binary_operator_ok (XOR, SImode, operands)"
10038 "xor{l}\t{%2, %k0|%k0, %2}"
10039 [(set_attr "type" "alu")
10040 (set_attr "mode" "SI")])
10042 (define_insn "*xorsi_3"
10043 [(set (reg FLAGS_REG)
10044 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10045 (match_operand:SI 2 "general_operand" "g"))
10047 (clobber (match_scratch:SI 0 "=r"))]
10048 "ix86_match_ccmode (insn, CCNOmode)
10049 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10050 "xor{l}\t{%2, %0|%0, %2}"
10051 [(set_attr "type" "alu")
10052 (set_attr "mode" "SI")])
10054 (define_expand "xorhi3"
10055 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10056 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10057 (match_operand:HI 2 "general_operand" "")))]
10058 "TARGET_HIMODE_MATH"
10059 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10061 (define_insn "*xorhi_1"
10062 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10063 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10064 (match_operand:HI 2 "general_operand" "rmn,rn")))
10065 (clobber (reg:CC FLAGS_REG))]
10066 "ix86_binary_operator_ok (XOR, HImode, operands)"
10067 "xor{w}\t{%2, %0|%0, %2}"
10068 [(set_attr "type" "alu")
10069 (set_attr "mode" "HI")])
10071 (define_insn "*xorhi_2"
10072 [(set (reg FLAGS_REG)
10073 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10074 (match_operand:HI 2 "general_operand" "rmn,rn"))
10076 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10077 (xor:HI (match_dup 1) (match_dup 2)))]
10078 "ix86_match_ccmode (insn, CCNOmode)
10079 && ix86_binary_operator_ok (XOR, HImode, operands)"
10080 "xor{w}\t{%2, %0|%0, %2}"
10081 [(set_attr "type" "alu")
10082 (set_attr "mode" "HI")])
10084 (define_insn "*xorhi_3"
10085 [(set (reg FLAGS_REG)
10086 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10087 (match_operand:HI 2 "general_operand" "rmn"))
10089 (clobber (match_scratch:HI 0 "=r"))]
10090 "ix86_match_ccmode (insn, CCNOmode)
10091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10092 "xor{w}\t{%2, %0|%0, %2}"
10093 [(set_attr "type" "alu")
10094 (set_attr "mode" "HI")])
10096 (define_expand "xorqi3"
10097 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10098 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10099 (match_operand:QI 2 "general_operand" "")))]
10100 "TARGET_QIMODE_MATH"
10101 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10103 ;; %%% Potential partial reg stall on alternative 2. What to do?
10104 (define_insn "*xorqi_1"
10105 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10106 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10107 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "ix86_binary_operator_ok (XOR, QImode, operands)"
10111 xor{b}\t{%2, %0|%0, %2}
10112 xor{b}\t{%2, %0|%0, %2}
10113 xor{l}\t{%k2, %k0|%k0, %k2}"
10114 [(set_attr "type" "alu")
10115 (set_attr "mode" "QI,QI,SI")])
10117 (define_insn "*xorqi_1_slp"
10118 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10119 (xor:QI (match_dup 0)
10120 (match_operand:QI 1 "general_operand" "qn,qmn")))
10121 (clobber (reg:CC FLAGS_REG))]
10122 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10123 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10124 "xor{b}\t{%1, %0|%0, %1}"
10125 [(set_attr "type" "alu1")
10126 (set_attr "mode" "QI")])
10128 (define_insn "*xorqi_ext_0"
10129 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10134 (match_operand 1 "ext_register_operand" "0")
10137 (match_operand 2 "const_int_operand" "n")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10140 "xor{b}\t{%2, %h0|%h0, %2}"
10141 [(set_attr "type" "alu")
10142 (set_attr "length_immediate" "1")
10143 (set_attr "mode" "QI")])
10145 (define_insn "*xorqi_ext_1"
10146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10151 (match_operand 1 "ext_register_operand" "0")
10155 (match_operand:QI 2 "general_operand" "Qm"))))
10156 (clobber (reg:CC FLAGS_REG))]
10158 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10159 "xor{b}\t{%2, %h0|%h0, %2}"
10160 [(set_attr "type" "alu")
10161 (set_attr "length_immediate" "0")
10162 (set_attr "mode" "QI")])
10164 (define_insn "*xorqi_ext_1_rex64"
10165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10170 (match_operand 1 "ext_register_operand" "0")
10174 (match_operand 2 "ext_register_operand" "Q"))))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10178 "xor{b}\t{%2, %h0|%h0, %2}"
10179 [(set_attr "type" "alu")
10180 (set_attr "length_immediate" "0")
10181 (set_attr "mode" "QI")])
10183 (define_insn "*xorqi_ext_2"
10184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10188 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10191 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10194 (clobber (reg:CC FLAGS_REG))]
10195 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10196 "xor{b}\t{%h2, %h0|%h0, %h2}"
10197 [(set_attr "type" "alu")
10198 (set_attr "length_immediate" "0")
10199 (set_attr "mode" "QI")])
10201 (define_insn "*xorqi_cc_1"
10202 [(set (reg FLAGS_REG)
10204 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10205 (match_operand:QI 2 "general_operand" "qmn,qn"))
10207 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10208 (xor:QI (match_dup 1) (match_dup 2)))]
10209 "ix86_match_ccmode (insn, CCNOmode)
10210 && ix86_binary_operator_ok (XOR, QImode, operands)"
10211 "xor{b}\t{%2, %0|%0, %2}"
10212 [(set_attr "type" "alu")
10213 (set_attr "mode" "QI")])
10215 (define_insn "*xorqi_2_slp"
10216 [(set (reg FLAGS_REG)
10217 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10218 (match_operand:QI 1 "general_operand" "qmn,qn"))
10220 (set (strict_low_part (match_dup 0))
10221 (xor:QI (match_dup 0) (match_dup 1)))]
10222 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10223 && ix86_match_ccmode (insn, CCNOmode)
10224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10225 "xor{b}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "mode" "QI")])
10229 (define_insn "*xorqi_cc_2"
10230 [(set (reg FLAGS_REG)
10232 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10233 (match_operand:QI 2 "general_operand" "qmn"))
10235 (clobber (match_scratch:QI 0 "=q"))]
10236 "ix86_match_ccmode (insn, CCNOmode)
10237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10238 "xor{b}\t{%2, %0|%0, %2}"
10239 [(set_attr "type" "alu")
10240 (set_attr "mode" "QI")])
10242 (define_insn "*xorqi_cc_ext_1"
10243 [(set (reg FLAGS_REG)
10247 (match_operand 1 "ext_register_operand" "0")
10250 (match_operand:QI 2 "general_operand" "qmn"))
10252 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10256 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10258 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10259 "xor{b}\t{%2, %h0|%h0, %2}"
10260 [(set_attr "type" "alu")
10261 (set_attr "mode" "QI")])
10263 (define_insn "*xorqi_cc_ext_1_rex64"
10264 [(set (reg FLAGS_REG)
10268 (match_operand 1 "ext_register_operand" "0")
10271 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10273 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10277 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10279 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10280 "xor{b}\t{%2, %h0|%h0, %2}"
10281 [(set_attr "type" "alu")
10282 (set_attr "mode" "QI")])
10284 (define_expand "xorqi_cc_ext_1"
10286 (set (reg:CCNO FLAGS_REG)
10290 (match_operand 1 "ext_register_operand" "")
10293 (match_operand:QI 2 "general_operand" ""))
10295 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10299 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10305 [(set (match_operand 0 "register_operand" "")
10306 (xor (match_operand 1 "register_operand" "")
10307 (match_operand 2 "const_int_operand" "")))
10308 (clobber (reg:CC FLAGS_REG))]
10310 && QI_REG_P (operands[0])
10311 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10312 && !(INTVAL (operands[2]) & ~(255 << 8))
10313 && GET_MODE (operands[0]) != QImode"
10314 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10315 (xor:SI (zero_extract:SI (match_dup 1)
10316 (const_int 8) (const_int 8))
10318 (clobber (reg:CC FLAGS_REG))])]
10319 "operands[0] = gen_lowpart (SImode, operands[0]);
10320 operands[1] = gen_lowpart (SImode, operands[1]);
10321 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10323 ;; Since XOR can be encoded with sign extended immediate, this is only
10324 ;; profitable when 7th bit is set.
10326 [(set (match_operand 0 "register_operand" "")
10327 (xor (match_operand 1 "general_operand" "")
10328 (match_operand 2 "const_int_operand" "")))
10329 (clobber (reg:CC FLAGS_REG))]
10331 && ANY_QI_REG_P (operands[0])
10332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333 && !(INTVAL (operands[2]) & ~255)
10334 && (INTVAL (operands[2]) & 128)
10335 && GET_MODE (operands[0]) != QImode"
10336 [(parallel [(set (strict_low_part (match_dup 0))
10337 (xor:QI (match_dup 1)
10339 (clobber (reg:CC FLAGS_REG))])]
10340 "operands[0] = gen_lowpart (QImode, operands[0]);
10341 operands[1] = gen_lowpart (QImode, operands[1]);
10342 operands[2] = gen_lowpart (QImode, operands[2]);")
10344 ;; Negation instructions
10346 (define_expand "negti2"
10347 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10348 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10350 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10352 (define_insn "*negti2_1"
10353 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10354 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10355 (clobber (reg:CC FLAGS_REG))]
10357 && ix86_unary_operator_ok (NEG, TImode, operands)"
10361 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10362 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && reload_completed"
10366 [(set (reg:CCZ FLAGS_REG)
10367 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10368 (set (match_dup 0) (neg:DI (match_dup 1)))])
10370 [(set (match_dup 2)
10371 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10374 (clobber (reg:CC FLAGS_REG))])
10376 [(set (match_dup 2)
10377 (neg:DI (match_dup 2)))
10378 (clobber (reg:CC FLAGS_REG))])]
10379 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10381 (define_expand "negdi2"
10382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10387 (define_insn "*negdi2_1"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10389 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10390 (clobber (reg:CC FLAGS_REG))]
10392 && ix86_unary_operator_ok (NEG, DImode, operands)"
10396 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10397 (neg:DI (match_operand:DI 1 "general_operand" "")))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "!TARGET_64BIT && reload_completed"
10401 [(set (reg:CCZ FLAGS_REG)
10402 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10403 (set (match_dup 0) (neg:SI (match_dup 1)))])
10405 [(set (match_dup 2)
10406 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10409 (clobber (reg:CC FLAGS_REG))])
10411 [(set (match_dup 2)
10412 (neg:SI (match_dup 2)))
10413 (clobber (reg:CC FLAGS_REG))])]
10414 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10416 (define_insn "*negdi2_1_rex64"
10417 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10418 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10422 [(set_attr "type" "negnot")
10423 (set_attr "mode" "DI")])
10425 ;; The problem with neg is that it does not perform (compare x 0),
10426 ;; it really performs (compare 0 x), which leaves us with the zero
10427 ;; flag being the only useful item.
10429 (define_insn "*negdi2_cmpz_rex64"
10430 [(set (reg:CCZ FLAGS_REG)
10431 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434 (neg:DI (match_dup 1)))]
10435 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437 [(set_attr "type" "negnot")
10438 (set_attr "mode" "DI")])
10441 (define_expand "negsi2"
10442 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10443 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10447 (define_insn "*negsi2_1"
10448 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10449 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10450 (clobber (reg:CC FLAGS_REG))]
10451 "ix86_unary_operator_ok (NEG, SImode, operands)"
10453 [(set_attr "type" "negnot")
10454 (set_attr "mode" "SI")])
10456 ;; Combine is quite creative about this pattern.
10457 (define_insn "*negsi2_1_zext"
10458 [(set (match_operand:DI 0 "register_operand" "=r")
10459 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10462 (clobber (reg:CC FLAGS_REG))]
10463 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10465 [(set_attr "type" "negnot")
10466 (set_attr "mode" "SI")])
10468 ;; The problem with neg is that it does not perform (compare x 0),
10469 ;; it really performs (compare 0 x), which leaves us with the zero
10470 ;; flag being the only useful item.
10472 (define_insn "*negsi2_cmpz"
10473 [(set (reg:CCZ FLAGS_REG)
10474 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10476 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10477 (neg:SI (match_dup 1)))]
10478 "ix86_unary_operator_ok (NEG, SImode, operands)"
10480 [(set_attr "type" "negnot")
10481 (set_attr "mode" "SI")])
10483 (define_insn "*negsi2_cmpz_zext"
10484 [(set (reg:CCZ FLAGS_REG)
10485 (compare:CCZ (lshiftrt:DI
10487 (match_operand:DI 1 "register_operand" "0")
10491 (set (match_operand:DI 0 "register_operand" "=r")
10492 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10497 [(set_attr "type" "negnot")
10498 (set_attr "mode" "SI")])
10500 (define_expand "neghi2"
10501 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10502 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10503 "TARGET_HIMODE_MATH"
10504 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10506 (define_insn "*neghi2_1"
10507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10508 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10509 (clobber (reg:CC FLAGS_REG))]
10510 "ix86_unary_operator_ok (NEG, HImode, operands)"
10512 [(set_attr "type" "negnot")
10513 (set_attr "mode" "HI")])
10515 (define_insn "*neghi2_cmpz"
10516 [(set (reg:CCZ FLAGS_REG)
10517 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520 (neg:HI (match_dup 1)))]
10521 "ix86_unary_operator_ok (NEG, HImode, operands)"
10523 [(set_attr "type" "negnot")
10524 (set_attr "mode" "HI")])
10526 (define_expand "negqi2"
10527 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10528 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10529 "TARGET_QIMODE_MATH"
10530 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10532 (define_insn "*negqi2_1"
10533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10534 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "ix86_unary_operator_ok (NEG, QImode, operands)"
10538 [(set_attr "type" "negnot")
10539 (set_attr "mode" "QI")])
10541 (define_insn "*negqi2_cmpz"
10542 [(set (reg:CCZ FLAGS_REG)
10543 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10545 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10546 (neg:QI (match_dup 1)))]
10547 "ix86_unary_operator_ok (NEG, QImode, operands)"
10549 [(set_attr "type" "negnot")
10550 (set_attr "mode" "QI")])
10552 ;; Changing of sign for FP values is doable using integer unit too.
10554 (define_expand "<code><mode>2"
10555 [(set (match_operand:X87MODEF 0 "register_operand" "")
10556 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10557 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10558 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10560 (define_insn "*absneg<mode>2_mixed"
10561 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10562 (match_operator:MODEF 3 "absneg_operator"
10563 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10564 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10569 (define_insn "*absneg<mode>2_sse"
10570 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10571 (match_operator:MODEF 3 "absneg_operator"
10572 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10573 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10578 (define_insn "*absneg<mode>2_i387"
10579 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10580 (match_operator:X87MODEF 3 "absneg_operator"
10581 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10582 (use (match_operand 2 "" ""))
10583 (clobber (reg:CC FLAGS_REG))]
10584 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10587 (define_expand "<code>tf2"
10588 [(set (match_operand:TF 0 "register_operand" "")
10589 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10591 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10593 (define_insn "*absnegtf2_sse"
10594 [(set (match_operand:TF 0 "register_operand" "=x,x")
10595 (match_operator:TF 3 "absneg_operator"
10596 [(match_operand:TF 1 "register_operand" "0,x")]))
10597 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10598 (clobber (reg:CC FLAGS_REG))]
10602 ;; Splitters for fp abs and neg.
10605 [(set (match_operand 0 "fp_register_operand" "")
10606 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10607 (use (match_operand 2 "" ""))
10608 (clobber (reg:CC FLAGS_REG))]
10610 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10613 [(set (match_operand 0 "register_operand" "")
10614 (match_operator 3 "absneg_operator"
10615 [(match_operand 1 "register_operand" "")]))
10616 (use (match_operand 2 "nonimmediate_operand" ""))
10617 (clobber (reg:CC FLAGS_REG))]
10618 "reload_completed && SSE_REG_P (operands[0])"
10619 [(set (match_dup 0) (match_dup 3))]
10621 enum machine_mode mode = GET_MODE (operands[0]);
10622 enum machine_mode vmode = GET_MODE (operands[2]);
10625 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10626 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10627 if (operands_match_p (operands[0], operands[2]))
10630 operands[1] = operands[2];
10633 if (GET_CODE (operands[3]) == ABS)
10634 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10636 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10641 [(set (match_operand:SF 0 "register_operand" "")
10642 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10643 (use (match_operand:V4SF 2 "" ""))
10644 (clobber (reg:CC FLAGS_REG))]
10646 [(parallel [(set (match_dup 0) (match_dup 1))
10647 (clobber (reg:CC FLAGS_REG))])]
10650 operands[0] = gen_lowpart (SImode, operands[0]);
10651 if (GET_CODE (operands[1]) == ABS)
10653 tmp = gen_int_mode (0x7fffffff, SImode);
10654 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10658 tmp = gen_int_mode (0x80000000, SImode);
10659 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10665 [(set (match_operand:DF 0 "register_operand" "")
10666 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10667 (use (match_operand 2 "" ""))
10668 (clobber (reg:CC FLAGS_REG))]
10670 [(parallel [(set (match_dup 0) (match_dup 1))
10671 (clobber (reg:CC FLAGS_REG))])]
10676 tmp = gen_lowpart (DImode, operands[0]);
10677 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10680 if (GET_CODE (operands[1]) == ABS)
10683 tmp = gen_rtx_NOT (DImode, tmp);
10687 operands[0] = gen_highpart (SImode, operands[0]);
10688 if (GET_CODE (operands[1]) == ABS)
10690 tmp = gen_int_mode (0x7fffffff, SImode);
10691 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10695 tmp = gen_int_mode (0x80000000, SImode);
10696 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10703 [(set (match_operand:XF 0 "register_operand" "")
10704 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10705 (use (match_operand 2 "" ""))
10706 (clobber (reg:CC FLAGS_REG))]
10708 [(parallel [(set (match_dup 0) (match_dup 1))
10709 (clobber (reg:CC FLAGS_REG))])]
10712 operands[0] = gen_rtx_REG (SImode,
10713 true_regnum (operands[0])
10714 + (TARGET_64BIT ? 1 : 2));
10715 if (GET_CODE (operands[1]) == ABS)
10717 tmp = GEN_INT (0x7fff);
10718 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10722 tmp = GEN_INT (0x8000);
10723 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10728 ;; Conditionalize these after reload. If they match before reload, we
10729 ;; lose the clobber and ability to use integer instructions.
10731 (define_insn "*<code><mode>2_1"
10732 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10733 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10735 && (reload_completed
10736 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10738 [(set_attr "type" "fsgn")
10739 (set_attr "mode" "<MODE>")])
10741 (define_insn "*<code>extendsfdf2"
10742 [(set (match_operand:DF 0 "register_operand" "=f")
10743 (absneg:DF (float_extend:DF
10744 (match_operand:SF 1 "register_operand" "0"))))]
10745 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10747 [(set_attr "type" "fsgn")
10748 (set_attr "mode" "DF")])
10750 (define_insn "*<code>extendsfxf2"
10751 [(set (match_operand:XF 0 "register_operand" "=f")
10752 (absneg:XF (float_extend:XF
10753 (match_operand:SF 1 "register_operand" "0"))))]
10756 [(set_attr "type" "fsgn")
10757 (set_attr "mode" "XF")])
10759 (define_insn "*<code>extenddfxf2"
10760 [(set (match_operand:XF 0 "register_operand" "=f")
10761 (absneg:XF (float_extend:XF
10762 (match_operand:DF 1 "register_operand" "0"))))]
10765 [(set_attr "type" "fsgn")
10766 (set_attr "mode" "XF")])
10768 ;; Copysign instructions
10770 (define_mode_iterator CSGNMODE [SF DF TF])
10771 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10773 (define_expand "copysign<mode>3"
10774 [(match_operand:CSGNMODE 0 "register_operand" "")
10775 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10776 (match_operand:CSGNMODE 2 "register_operand" "")]
10777 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10778 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10780 ix86_expand_copysign (operands);
10784 (define_insn_and_split "copysign<mode>3_const"
10785 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10787 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10788 (match_operand:CSGNMODE 2 "register_operand" "0")
10789 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10791 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10792 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10794 "&& reload_completed"
10797 ix86_split_copysign_const (operands);
10801 (define_insn "copysign<mode>3_var"
10802 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10804 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10805 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10806 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10807 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10809 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10815 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10817 [(match_operand:CSGNMODE 2 "register_operand" "")
10818 (match_operand:CSGNMODE 3 "register_operand" "")
10819 (match_operand:<CSGNVMODE> 4 "" "")
10820 (match_operand:<CSGNVMODE> 5 "" "")]
10822 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10823 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10824 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10825 && reload_completed"
10828 ix86_split_copysign_var (operands);
10832 ;; One complement instructions
10834 (define_expand "one_cmpldi2"
10835 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10836 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10838 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10840 (define_insn "*one_cmpldi2_1_rex64"
10841 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10843 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10845 [(set_attr "type" "negnot")
10846 (set_attr "mode" "DI")])
10848 (define_insn "*one_cmpldi2_2_rex64"
10849 [(set (reg FLAGS_REG)
10850 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10853 (not:DI (match_dup 1)))]
10854 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10855 && ix86_unary_operator_ok (NOT, DImode, operands)"
10857 [(set_attr "type" "alu1")
10858 (set_attr "mode" "DI")])
10861 [(set (match_operand 0 "flags_reg_operand" "")
10862 (match_operator 2 "compare_operator"
10863 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10865 (set (match_operand:DI 1 "nonimmediate_operand" "")
10866 (not:DI (match_dup 3)))]
10867 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10868 [(parallel [(set (match_dup 0)
10870 [(xor:DI (match_dup 3) (const_int -1))
10873 (xor:DI (match_dup 3) (const_int -1)))])]
10876 (define_expand "one_cmplsi2"
10877 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10878 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10880 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10882 (define_insn "*one_cmplsi2_1"
10883 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10884 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10885 "ix86_unary_operator_ok (NOT, SImode, operands)"
10887 [(set_attr "type" "negnot")
10888 (set_attr "mode" "SI")])
10890 ;; ??? Currently never generated - xor is used instead.
10891 (define_insn "*one_cmplsi2_1_zext"
10892 [(set (match_operand:DI 0 "register_operand" "=r")
10893 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10894 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10896 [(set_attr "type" "negnot")
10897 (set_attr "mode" "SI")])
10899 (define_insn "*one_cmplsi2_2"
10900 [(set (reg FLAGS_REG)
10901 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10903 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904 (not:SI (match_dup 1)))]
10905 "ix86_match_ccmode (insn, CCNOmode)
10906 && ix86_unary_operator_ok (NOT, SImode, operands)"
10908 [(set_attr "type" "alu1")
10909 (set_attr "mode" "SI")])
10912 [(set (match_operand 0 "flags_reg_operand" "")
10913 (match_operator 2 "compare_operator"
10914 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10916 (set (match_operand:SI 1 "nonimmediate_operand" "")
10917 (not:SI (match_dup 3)))]
10918 "ix86_match_ccmode (insn, CCNOmode)"
10919 [(parallel [(set (match_dup 0)
10920 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10923 (xor:SI (match_dup 3) (const_int -1)))])]
10926 ;; ??? Currently never generated - xor is used instead.
10927 (define_insn "*one_cmplsi2_2_zext"
10928 [(set (reg FLAGS_REG)
10929 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10931 (set (match_operand:DI 0 "register_operand" "=r")
10932 (zero_extend:DI (not:SI (match_dup 1))))]
10933 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10934 && ix86_unary_operator_ok (NOT, SImode, operands)"
10936 [(set_attr "type" "alu1")
10937 (set_attr "mode" "SI")])
10940 [(set (match_operand 0 "flags_reg_operand" "")
10941 (match_operator 2 "compare_operator"
10942 [(not:SI (match_operand:SI 3 "register_operand" ""))
10944 (set (match_operand:DI 1 "register_operand" "")
10945 (zero_extend:DI (not:SI (match_dup 3))))]
10946 "ix86_match_ccmode (insn, CCNOmode)"
10947 [(parallel [(set (match_dup 0)
10948 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10951 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10954 (define_expand "one_cmplhi2"
10955 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10956 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10957 "TARGET_HIMODE_MATH"
10958 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10960 (define_insn "*one_cmplhi2_1"
10961 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10962 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10963 "ix86_unary_operator_ok (NOT, HImode, operands)"
10965 [(set_attr "type" "negnot")
10966 (set_attr "mode" "HI")])
10968 (define_insn "*one_cmplhi2_2"
10969 [(set (reg FLAGS_REG)
10970 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10972 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10973 (not:HI (match_dup 1)))]
10974 "ix86_match_ccmode (insn, CCNOmode)
10975 && ix86_unary_operator_ok (NEG, HImode, operands)"
10977 [(set_attr "type" "alu1")
10978 (set_attr "mode" "HI")])
10981 [(set (match_operand 0 "flags_reg_operand" "")
10982 (match_operator 2 "compare_operator"
10983 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10985 (set (match_operand:HI 1 "nonimmediate_operand" "")
10986 (not:HI (match_dup 3)))]
10987 "ix86_match_ccmode (insn, CCNOmode)"
10988 [(parallel [(set (match_dup 0)
10989 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10992 (xor:HI (match_dup 3) (const_int -1)))])]
10995 ;; %%% Potential partial reg stall on alternative 1. What to do?
10996 (define_expand "one_cmplqi2"
10997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10998 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10999 "TARGET_QIMODE_MATH"
11000 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11002 (define_insn "*one_cmplqi2_1"
11003 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11004 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11005 "ix86_unary_operator_ok (NOT, QImode, operands)"
11009 [(set_attr "type" "negnot")
11010 (set_attr "mode" "QI,SI")])
11012 (define_insn "*one_cmplqi2_2"
11013 [(set (reg FLAGS_REG)
11014 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11016 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11017 (not:QI (match_dup 1)))]
11018 "ix86_match_ccmode (insn, CCNOmode)
11019 && ix86_unary_operator_ok (NOT, QImode, operands)"
11021 [(set_attr "type" "alu1")
11022 (set_attr "mode" "QI")])
11025 [(set (match_operand 0 "flags_reg_operand" "")
11026 (match_operator 2 "compare_operator"
11027 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11029 (set (match_operand:QI 1 "nonimmediate_operand" "")
11030 (not:QI (match_dup 3)))]
11031 "ix86_match_ccmode (insn, CCNOmode)"
11032 [(parallel [(set (match_dup 0)
11033 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11036 (xor:QI (match_dup 3) (const_int -1)))])]
11039 ;; Arithmetic shift instructions
11041 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11042 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11043 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11044 ;; from the assembler input.
11046 ;; This instruction shifts the target reg/mem as usual, but instead of
11047 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11048 ;; is a left shift double, bits are taken from the high order bits of
11049 ;; reg, else if the insn is a shift right double, bits are taken from the
11050 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11051 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11053 ;; Since sh[lr]d does not change the `reg' operand, that is done
11054 ;; separately, making all shifts emit pairs of shift double and normal
11055 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11056 ;; support a 63 bit shift, each shift where the count is in a reg expands
11057 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11059 ;; If the shift count is a constant, we need never emit more than one
11060 ;; shift pair, instead using moves and sign extension for counts greater
11063 (define_expand "ashlti3"
11064 [(set (match_operand:TI 0 "register_operand" "")
11065 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11066 (match_operand:QI 2 "nonmemory_operand" "")))]
11068 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11070 ;; This pattern must be defined before *ashlti3_1 to prevent
11071 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11073 (define_insn "*avx_ashlti3"
11074 [(set (match_operand:TI 0 "register_operand" "=x")
11075 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11076 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11079 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11080 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11082 [(set_attr "type" "sseishft")
11083 (set_attr "prefix" "vex")
11084 (set_attr "mode" "TI")])
11086 (define_insn "sse2_ashlti3"
11087 [(set (match_operand:TI 0 "register_operand" "=x")
11088 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11089 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11092 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11093 return "pslldq\t{%2, %0|%0, %2}";
11095 [(set_attr "type" "sseishft")
11096 (set_attr "prefix_data16" "1")
11097 (set_attr "mode" "TI")])
11099 (define_insn "*ashlti3_1"
11100 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11101 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11102 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11103 (clobber (reg:CC FLAGS_REG))]
11106 [(set_attr "type" "multi")])
11109 [(match_scratch:DI 3 "r")
11110 (parallel [(set (match_operand:TI 0 "register_operand" "")
11111 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11112 (match_operand:QI 2 "nonmemory_operand" "")))
11113 (clobber (reg:CC FLAGS_REG))])
11117 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11120 [(set (match_operand:TI 0 "register_operand" "")
11121 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11122 (match_operand:QI 2 "nonmemory_operand" "")))
11123 (clobber (reg:CC FLAGS_REG))]
11124 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11125 ? epilogue_completed : reload_completed)"
11127 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11129 (define_insn "x86_64_shld"
11130 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11131 (ior:DI (ashift:DI (match_dup 0)
11132 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11133 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11134 (minus:QI (const_int 64) (match_dup 2)))))
11135 (clobber (reg:CC FLAGS_REG))]
11137 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11138 [(set_attr "type" "ishift")
11139 (set_attr "prefix_0f" "1")
11140 (set_attr "mode" "DI")
11141 (set_attr "athlon_decode" "vector")
11142 (set_attr "amdfam10_decode" "vector")])
11144 (define_expand "x86_64_shift_adj_1"
11145 [(set (reg:CCZ FLAGS_REG)
11146 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11149 (set (match_operand:DI 0 "register_operand" "")
11150 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11151 (match_operand:DI 1 "register_operand" "")
11154 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11155 (match_operand:DI 3 "register_operand" "r")
11160 (define_expand "x86_64_shift_adj_2"
11161 [(use (match_operand:DI 0 "register_operand" ""))
11162 (use (match_operand:DI 1 "register_operand" ""))
11163 (use (match_operand:QI 2 "register_operand" ""))]
11166 rtx label = gen_label_rtx ();
11169 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11171 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11172 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11173 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11174 gen_rtx_LABEL_REF (VOIDmode, label),
11176 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11177 JUMP_LABEL (tmp) = label;
11179 emit_move_insn (operands[0], operands[1]);
11180 ix86_expand_clear (operands[1]);
11182 emit_label (label);
11183 LABEL_NUSES (label) = 1;
11188 (define_expand "ashldi3"
11189 [(set (match_operand:DI 0 "shiftdi_operand" "")
11190 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))]
11193 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11195 (define_insn "*ashldi3_1_rex64"
11196 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11197 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11198 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11199 (clobber (reg:CC FLAGS_REG))]
11200 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11202 switch (get_attr_type (insn))
11205 gcc_assert (operands[2] == const1_rtx);
11206 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11207 return "add{q}\t%0, %0";
11210 gcc_assert (CONST_INT_P (operands[2]));
11211 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11212 operands[1] = gen_rtx_MULT (DImode, operands[1],
11213 GEN_INT (1 << INTVAL (operands[2])));
11214 return "lea{q}\t{%a1, %0|%0, %a1}";
11217 if (REG_P (operands[2]))
11218 return "sal{q}\t{%b2, %0|%0, %b2}";
11219 else if (operands[2] == const1_rtx
11220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11221 return "sal{q}\t%0";
11223 return "sal{q}\t{%2, %0|%0, %2}";
11226 [(set (attr "type")
11227 (cond [(eq_attr "alternative" "1")
11228 (const_string "lea")
11229 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11231 (match_operand 0 "register_operand" ""))
11232 (match_operand 2 "const1_operand" ""))
11233 (const_string "alu")
11235 (const_string "ishift")))
11236 (set_attr "mode" "DI")])
11238 ;; Convert lea to the lea pattern to avoid flags dependency.
11240 [(set (match_operand:DI 0 "register_operand" "")
11241 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11242 (match_operand:QI 2 "immediate_operand" "")))
11243 (clobber (reg:CC FLAGS_REG))]
11244 "TARGET_64BIT && reload_completed
11245 && true_regnum (operands[0]) != true_regnum (operands[1])"
11246 [(set (match_dup 0)
11247 (mult:DI (match_dup 1)
11249 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags. We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashldi3_cmp_rex64"
11255 [(set (reg FLAGS_REG)
11257 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11258 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11260 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11261 (ashift:DI (match_dup 1) (match_dup 2)))]
11263 && (optimize_function_for_size_p (cfun)
11264 || !TARGET_PARTIAL_FLAG_REG_STALL
11265 || (operands[2] == const1_rtx
11267 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11268 && ix86_match_ccmode (insn, CCGOCmode)
11269 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11271 switch (get_attr_type (insn))
11274 gcc_assert (operands[2] == const1_rtx);
11275 return "add{q}\t%0, %0";
11278 if (REG_P (operands[2]))
11279 return "sal{q}\t{%b2, %0|%0, %b2}";
11280 else if (operands[2] == const1_rtx
11281 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11282 return "sal{q}\t%0";
11284 return "sal{q}\t{%2, %0|%0, %2}";
11287 [(set (attr "type")
11288 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290 (match_operand 0 "register_operand" ""))
11291 (match_operand 2 "const1_operand" ""))
11292 (const_string "alu")
11294 (const_string "ishift")))
11295 (set_attr "mode" "DI")])
11297 (define_insn "*ashldi3_cconly_rex64"
11298 [(set (reg FLAGS_REG)
11300 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11301 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11303 (clobber (match_scratch:DI 0 "=r"))]
11305 && (optimize_function_for_size_p (cfun)
11306 || !TARGET_PARTIAL_FLAG_REG_STALL
11307 || (operands[2] == const1_rtx
11309 || TARGET_DOUBLE_WITH_ADD)))
11310 && ix86_match_ccmode (insn, CCGOCmode)
11311 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11313 switch (get_attr_type (insn))
11316 gcc_assert (operands[2] == const1_rtx);
11317 return "add{q}\t%0, %0";
11320 if (REG_P (operands[2]))
11321 return "sal{q}\t{%b2, %0|%0, %b2}";
11322 else if (operands[2] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324 return "sal{q}\t%0";
11326 return "sal{q}\t{%2, %0|%0, %2}";
11329 [(set (attr "type")
11330 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (match_operand 0 "register_operand" ""))
11333 (match_operand 2 "const1_operand" ""))
11334 (const_string "alu")
11336 (const_string "ishift")))
11337 (set_attr "mode" "DI")])
11339 (define_insn "*ashldi3_1"
11340 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11341 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11342 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11343 (clobber (reg:CC FLAGS_REG))]
11346 [(set_attr "type" "multi")])
11348 ;; By default we don't ask for a scratch register, because when DImode
11349 ;; values are manipulated, registers are already at a premium. But if
11350 ;; we have one handy, we won't turn it away.
11352 [(match_scratch:SI 3 "r")
11353 (parallel [(set (match_operand:DI 0 "register_operand" "")
11354 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11355 (match_operand:QI 2 "nonmemory_operand" "")))
11356 (clobber (reg:CC FLAGS_REG))])
11358 "!TARGET_64BIT && TARGET_CMOVE"
11360 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11363 [(set (match_operand:DI 0 "register_operand" "")
11364 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11365 (match_operand:QI 2 "nonmemory_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11368 ? epilogue_completed : reload_completed)"
11370 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11372 (define_insn "x86_shld"
11373 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11374 (ior:SI (ashift:SI (match_dup 0)
11375 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11376 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11377 (minus:QI (const_int 32) (match_dup 2)))))
11378 (clobber (reg:CC FLAGS_REG))]
11380 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11381 [(set_attr "type" "ishift")
11382 (set_attr "prefix_0f" "1")
11383 (set_attr "mode" "SI")
11384 (set_attr "pent_pair" "np")
11385 (set_attr "athlon_decode" "vector")
11386 (set_attr "amdfam10_decode" "vector")])
11388 (define_expand "x86_shift_adj_1"
11389 [(set (reg:CCZ FLAGS_REG)
11390 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11393 (set (match_operand:SI 0 "register_operand" "")
11394 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11395 (match_operand:SI 1 "register_operand" "")
11398 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11399 (match_operand:SI 3 "register_operand" "r")
11404 (define_expand "x86_shift_adj_2"
11405 [(use (match_operand:SI 0 "register_operand" ""))
11406 (use (match_operand:SI 1 "register_operand" ""))
11407 (use (match_operand:QI 2 "register_operand" ""))]
11410 rtx label = gen_label_rtx ();
11413 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11415 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11416 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11417 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11418 gen_rtx_LABEL_REF (VOIDmode, label),
11420 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11421 JUMP_LABEL (tmp) = label;
11423 emit_move_insn (operands[0], operands[1]);
11424 ix86_expand_clear (operands[1]);
11426 emit_label (label);
11427 LABEL_NUSES (label) = 1;
11432 (define_expand "ashlsi3"
11433 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11434 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11435 (match_operand:QI 2 "nonmemory_operand" "")))]
11437 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11439 (define_insn "*ashlsi3_1"
11440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11441 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11442 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11443 (clobber (reg:CC FLAGS_REG))]
11444 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11446 switch (get_attr_type (insn))
11449 gcc_assert (operands[2] == const1_rtx);
11450 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11451 return "add{l}\t%0, %0";
11457 if (REG_P (operands[2]))
11458 return "sal{l}\t{%b2, %0|%0, %b2}";
11459 else if (operands[2] == const1_rtx
11460 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11461 return "sal{l}\t%0";
11463 return "sal{l}\t{%2, %0|%0, %2}";
11466 [(set (attr "type")
11467 (cond [(eq_attr "alternative" "1")
11468 (const_string "lea")
11469 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471 (match_operand 0 "register_operand" ""))
11472 (match_operand 2 "const1_operand" ""))
11473 (const_string "alu")
11475 (const_string "ishift")))
11476 (set_attr "mode" "SI")])
11478 ;; Convert lea to the lea pattern to avoid flags dependency.
11480 [(set (match_operand 0 "register_operand" "")
11481 (ashift (match_operand 1 "index_register_operand" "")
11482 (match_operand:QI 2 "const_int_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11485 && true_regnum (operands[0]) != true_regnum (operands[1])
11486 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11490 enum machine_mode mode = GET_MODE (operands[0]);
11492 if (GET_MODE_SIZE (mode) < 4)
11493 operands[0] = gen_lowpart (SImode, operands[0]);
11495 operands[1] = gen_lowpart (Pmode, operands[1]);
11496 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11498 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11499 if (Pmode != SImode)
11500 pat = gen_rtx_SUBREG (SImode, pat, 0);
11501 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11505 ;; Rare case of shifting RSP is handled by generating move and shift
11507 [(set (match_operand 0 "register_operand" "")
11508 (ashift (match_operand 1 "register_operand" "")
11509 (match_operand:QI 2 "const_int_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11512 && true_regnum (operands[0]) != true_regnum (operands[1])"
11516 emit_move_insn (operands[0], operands[1]);
11517 pat = gen_rtx_SET (VOIDmode, operands[0],
11518 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11519 operands[0], operands[2]));
11520 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11521 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11525 (define_insn "*ashlsi3_1_zext"
11526 [(set (match_operand:DI 0 "register_operand" "=r,r")
11527 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11528 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11529 (clobber (reg:CC FLAGS_REG))]
11530 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11532 switch (get_attr_type (insn))
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{l}\t%k0, %k0";
11542 if (REG_P (operands[2]))
11543 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11544 else if (operands[2] == const1_rtx
11545 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11546 return "sal{l}\t%k0";
11548 return "sal{l}\t{%2, %k0|%k0, %2}";
11551 [(set (attr "type")
11552 (cond [(eq_attr "alternative" "1")
11553 (const_string "lea")
11554 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556 (match_operand 2 "const1_operand" ""))
11557 (const_string "alu")
11559 (const_string "ishift")))
11560 (set_attr "mode" "SI")])
11562 ;; Convert lea to the lea pattern to avoid flags dependency.
11564 [(set (match_operand:DI 0 "register_operand" "")
11565 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11566 (match_operand:QI 2 "const_int_operand" ""))))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "TARGET_64BIT && reload_completed
11569 && true_regnum (operands[0]) != true_regnum (operands[1])"
11570 [(set (match_dup 0) (zero_extend:DI
11571 (subreg:SI (mult:SI (match_dup 1)
11572 (match_dup 2)) 0)))]
11574 operands[1] = gen_lowpart (Pmode, operands[1]);
11575 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags. We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*ashlsi3_cmp"
11582 [(set (reg FLAGS_REG)
11584 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588 (ashift:SI (match_dup 1) (match_dup 2)))]
11589 "(optimize_function_for_size_p (cfun)
11590 || !TARGET_PARTIAL_FLAG_REG_STALL
11591 || (operands[2] == const1_rtx
11593 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11594 && ix86_match_ccmode (insn, CCGOCmode)
11595 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11597 switch (get_attr_type (insn))
11600 gcc_assert (operands[2] == const1_rtx);
11601 return "add{l}\t%0, %0";
11604 if (REG_P (operands[2]))
11605 return "sal{l}\t{%b2, %0|%0, %b2}";
11606 else if (operands[2] == const1_rtx
11607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11608 return "sal{l}\t%0";
11610 return "sal{l}\t{%2, %0|%0, %2}";
11613 [(set (attr "type")
11614 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11616 (match_operand 0 "register_operand" ""))
11617 (match_operand 2 "const1_operand" ""))
11618 (const_string "alu")
11620 (const_string "ishift")))
11621 (set_attr "mode" "SI")])
11623 (define_insn "*ashlsi3_cconly"
11624 [(set (reg FLAGS_REG)
11626 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629 (clobber (match_scratch:SI 0 "=r"))]
11630 "(optimize_function_for_size_p (cfun)
11631 || !TARGET_PARTIAL_FLAG_REG_STALL
11632 || (operands[2] == const1_rtx
11634 || TARGET_DOUBLE_WITH_ADD)))
11635 && ix86_match_ccmode (insn, CCGOCmode)
11636 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11638 switch (get_attr_type (insn))
11641 gcc_assert (operands[2] == const1_rtx);
11642 return "add{l}\t%0, %0";
11645 if (REG_P (operands[2]))
11646 return "sal{l}\t{%b2, %0|%0, %b2}";
11647 else if (operands[2] == const1_rtx
11648 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11649 return "sal{l}\t%0";
11651 return "sal{l}\t{%2, %0|%0, %2}";
11654 [(set (attr "type")
11655 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11657 (match_operand 0 "register_operand" ""))
11658 (match_operand 2 "const1_operand" ""))
11659 (const_string "alu")
11661 (const_string "ishift")))
11662 (set_attr "mode" "SI")])
11664 (define_insn "*ashlsi3_cmp_zext"
11665 [(set (reg FLAGS_REG)
11667 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11668 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670 (set (match_operand:DI 0 "register_operand" "=r")
11671 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11673 && (optimize_function_for_size_p (cfun)
11674 || !TARGET_PARTIAL_FLAG_REG_STALL
11675 || (operands[2] == const1_rtx
11677 || TARGET_DOUBLE_WITH_ADD)))
11678 && ix86_match_ccmode (insn, CCGOCmode)
11679 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11681 switch (get_attr_type (insn))
11684 gcc_assert (operands[2] == const1_rtx);
11685 return "add{l}\t%k0, %k0";
11688 if (REG_P (operands[2]))
11689 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11690 else if (operands[2] == const1_rtx
11691 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11692 return "sal{l}\t%k0";
11694 return "sal{l}\t{%2, %k0|%k0, %2}";
11697 [(set (attr "type")
11698 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700 (match_operand 2 "const1_operand" ""))
11701 (const_string "alu")
11703 (const_string "ishift")))
11704 (set_attr "mode" "SI")])
11706 (define_expand "ashlhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))]
11710 "TARGET_HIMODE_MATH"
11711 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11713 (define_insn "*ashlhi3_1_lea"
11714 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11715 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11716 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11717 (clobber (reg:CC FLAGS_REG))]
11718 "!TARGET_PARTIAL_REG_STALL
11719 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11721 switch (get_attr_type (insn))
11726 gcc_assert (operands[2] == const1_rtx);
11727 return "add{w}\t%0, %0";
11730 if (REG_P (operands[2]))
11731 return "sal{w}\t{%b2, %0|%0, %b2}";
11732 else if (operands[2] == const1_rtx
11733 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11734 return "sal{w}\t%0";
11736 return "sal{w}\t{%2, %0|%0, %2}";
11739 [(set (attr "type")
11740 (cond [(eq_attr "alternative" "1")
11741 (const_string "lea")
11742 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744 (match_operand 0 "register_operand" ""))
11745 (match_operand 2 "const1_operand" ""))
11746 (const_string "alu")
11748 (const_string "ishift")))
11749 (set_attr "mode" "HI,SI")])
11751 (define_insn "*ashlhi3_1"
11752 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11754 (match_operand:QI 2 "nonmemory_operand" "cI")))
11755 (clobber (reg:CC FLAGS_REG))]
11756 "TARGET_PARTIAL_REG_STALL
11757 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11759 switch (get_attr_type (insn))
11762 gcc_assert (operands[2] == const1_rtx);
11763 return "add{w}\t%0, %0";
11766 if (REG_P (operands[2]))
11767 return "sal{w}\t{%b2, %0|%0, %b2}";
11768 else if (operands[2] == const1_rtx
11769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11770 return "sal{w}\t%0";
11772 return "sal{w}\t{%2, %0|%0, %2}";
11775 [(set (attr "type")
11776 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (match_operand 0 "register_operand" ""))
11779 (match_operand 2 "const1_operand" ""))
11780 (const_string "alu")
11782 (const_string "ishift")))
11783 (set_attr "mode" "HI")])
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags. We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashlhi3_cmp"
11789 [(set (reg FLAGS_REG)
11791 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11792 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11794 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11795 (ashift:HI (match_dup 1) (match_dup 2)))]
11796 "(optimize_function_for_size_p (cfun)
11797 || !TARGET_PARTIAL_FLAG_REG_STALL
11798 || (operands[2] == const1_rtx
11800 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11801 && ix86_match_ccmode (insn, CCGOCmode)
11802 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11804 switch (get_attr_type (insn))
11807 gcc_assert (operands[2] == const1_rtx);
11808 return "add{w}\t%0, %0";
11811 if (REG_P (operands[2]))
11812 return "sal{w}\t{%b2, %0|%0, %b2}";
11813 else if (operands[2] == const1_rtx
11814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11815 return "sal{w}\t%0";
11817 return "sal{w}\t{%2, %0|%0, %2}";
11820 [(set (attr "type")
11821 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11823 (match_operand 0 "register_operand" ""))
11824 (match_operand 2 "const1_operand" ""))
11825 (const_string "alu")
11827 (const_string "ishift")))
11828 (set_attr "mode" "HI")])
11830 (define_insn "*ashlhi3_cconly"
11831 [(set (reg FLAGS_REG)
11833 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11834 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836 (clobber (match_scratch:HI 0 "=r"))]
11837 "(optimize_function_for_size_p (cfun)
11838 || !TARGET_PARTIAL_FLAG_REG_STALL
11839 || (operands[2] == const1_rtx
11841 || TARGET_DOUBLE_WITH_ADD)))
11842 && ix86_match_ccmode (insn, CCGOCmode)
11843 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11845 switch (get_attr_type (insn))
11848 gcc_assert (operands[2] == const1_rtx);
11849 return "add{w}\t%0, %0";
11852 if (REG_P (operands[2]))
11853 return "sal{w}\t{%b2, %0|%0, %b2}";
11854 else if (operands[2] == const1_rtx
11855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11856 return "sal{w}\t%0";
11858 return "sal{w}\t{%2, %0|%0, %2}";
11861 [(set (attr "type")
11862 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11864 (match_operand 0 "register_operand" ""))
11865 (match_operand 2 "const1_operand" ""))
11866 (const_string "alu")
11868 (const_string "ishift")))
11869 (set_attr "mode" "HI")])
11871 (define_expand "ashlqi3"
11872 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11873 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11874 (match_operand:QI 2 "nonmemory_operand" "")))]
11875 "TARGET_QIMODE_MATH"
11876 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11878 ;; %%% Potential partial reg stall on alternative 2. What to do?
11880 (define_insn "*ashlqi3_1_lea"
11881 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11882 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11883 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11884 (clobber (reg:CC FLAGS_REG))]
11885 "!TARGET_PARTIAL_REG_STALL
11886 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11888 switch (get_attr_type (insn))
11893 gcc_assert (operands[2] == const1_rtx);
11894 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11895 return "add{l}\t%k0, %k0";
11897 return "add{b}\t%0, %0";
11900 if (REG_P (operands[2]))
11902 if (get_attr_mode (insn) == MODE_SI)
11903 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11905 return "sal{b}\t{%b2, %0|%0, %b2}";
11907 else if (operands[2] == const1_rtx
11908 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11910 if (get_attr_mode (insn) == MODE_SI)
11911 return "sal{l}\t%0";
11913 return "sal{b}\t%0";
11917 if (get_attr_mode (insn) == MODE_SI)
11918 return "sal{l}\t{%2, %k0|%k0, %2}";
11920 return "sal{b}\t{%2, %0|%0, %2}";
11924 [(set (attr "type")
11925 (cond [(eq_attr "alternative" "2")
11926 (const_string "lea")
11927 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11929 (match_operand 0 "register_operand" ""))
11930 (match_operand 2 "const1_operand" ""))
11931 (const_string "alu")
11933 (const_string "ishift")))
11934 (set_attr "mode" "QI,SI,SI")])
11936 (define_insn "*ashlqi3_1"
11937 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11938 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11939 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "TARGET_PARTIAL_REG_STALL
11942 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11944 switch (get_attr_type (insn))
11947 gcc_assert (operands[2] == const1_rtx);
11948 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11949 return "add{l}\t%k0, %k0";
11951 return "add{b}\t%0, %0";
11954 if (REG_P (operands[2]))
11956 if (get_attr_mode (insn) == MODE_SI)
11957 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11959 return "sal{b}\t{%b2, %0|%0, %b2}";
11961 else if (operands[2] == const1_rtx
11962 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11964 if (get_attr_mode (insn) == MODE_SI)
11965 return "sal{l}\t%0";
11967 return "sal{b}\t%0";
11971 if (get_attr_mode (insn) == MODE_SI)
11972 return "sal{l}\t{%2, %k0|%k0, %2}";
11974 return "sal{b}\t{%2, %0|%0, %2}";
11978 [(set (attr "type")
11979 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11981 (match_operand 0 "register_operand" ""))
11982 (match_operand 2 "const1_operand" ""))
11983 (const_string "alu")
11985 (const_string "ishift")))
11986 (set_attr "mode" "QI,SI")])
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags. We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*ashlqi3_cmp"
11992 [(set (reg FLAGS_REG)
11994 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998 (ashift:QI (match_dup 1) (match_dup 2)))]
11999 "(optimize_function_for_size_p (cfun)
12000 || !TARGET_PARTIAL_FLAG_REG_STALL
12001 || (operands[2] == const1_rtx
12003 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12004 && ix86_match_ccmode (insn, CCGOCmode)
12005 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12007 switch (get_attr_type (insn))
12010 gcc_assert (operands[2] == const1_rtx);
12011 return "add{b}\t%0, %0";
12014 if (REG_P (operands[2]))
12015 return "sal{b}\t{%b2, %0|%0, %b2}";
12016 else if (operands[2] == const1_rtx
12017 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018 return "sal{b}\t%0";
12020 return "sal{b}\t{%2, %0|%0, %2}";
12023 [(set (attr "type")
12024 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12026 (match_operand 0 "register_operand" ""))
12027 (match_operand 2 "const1_operand" ""))
12028 (const_string "alu")
12030 (const_string "ishift")))
12031 (set_attr "mode" "QI")])
12033 (define_insn "*ashlqi3_cconly"
12034 [(set (reg FLAGS_REG)
12036 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12037 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039 (clobber (match_scratch:QI 0 "=q"))]
12040 "(optimize_function_for_size_p (cfun)
12041 || !TARGET_PARTIAL_FLAG_REG_STALL
12042 || (operands[2] == const1_rtx
12044 || TARGET_DOUBLE_WITH_ADD)))
12045 && ix86_match_ccmode (insn, CCGOCmode)
12046 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12048 switch (get_attr_type (insn))
12051 gcc_assert (operands[2] == const1_rtx);
12052 return "add{b}\t%0, %0";
12055 if (REG_P (operands[2]))
12056 return "sal{b}\t{%b2, %0|%0, %b2}";
12057 else if (operands[2] == const1_rtx
12058 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12059 return "sal{b}\t%0";
12061 return "sal{b}\t{%2, %0|%0, %2}";
12064 [(set (attr "type")
12065 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12067 (match_operand 0 "register_operand" ""))
12068 (match_operand 2 "const1_operand" ""))
12069 (const_string "alu")
12071 (const_string "ishift")))
12072 (set_attr "mode" "QI")])
12074 ;; See comment above `ashldi3' about how this works.
12076 (define_expand "ashrti3"
12077 [(set (match_operand:TI 0 "register_operand" "")
12078 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12079 (match_operand:QI 2 "nonmemory_operand" "")))]
12081 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12083 (define_insn "*ashrti3_1"
12084 [(set (match_operand:TI 0 "register_operand" "=r")
12085 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12086 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12087 (clobber (reg:CC FLAGS_REG))]
12090 [(set_attr "type" "multi")])
12093 [(match_scratch:DI 3 "r")
12094 (parallel [(set (match_operand:TI 0 "register_operand" "")
12095 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12096 (match_operand:QI 2 "nonmemory_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))])
12101 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12104 [(set (match_operand:TI 0 "register_operand" "")
12105 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12106 (match_operand:QI 2 "nonmemory_operand" "")))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12109 ? epilogue_completed : reload_completed)"
12111 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12113 (define_insn "x86_64_shrd"
12114 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12115 (ior:DI (ashiftrt:DI (match_dup 0)
12116 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12117 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12118 (minus:QI (const_int 64) (match_dup 2)))))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12122 [(set_attr "type" "ishift")
12123 (set_attr "prefix_0f" "1")
12124 (set_attr "mode" "DI")
12125 (set_attr "athlon_decode" "vector")
12126 (set_attr "amdfam10_decode" "vector")])
12128 (define_expand "ashrdi3"
12129 [(set (match_operand:DI 0 "shiftdi_operand" "")
12130 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12131 (match_operand:QI 2 "nonmemory_operand" "")))]
12133 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12135 (define_expand "x86_64_shift_adj_3"
12136 [(use (match_operand:DI 0 "register_operand" ""))
12137 (use (match_operand:DI 1 "register_operand" ""))
12138 (use (match_operand:QI 2 "register_operand" ""))]
12141 rtx label = gen_label_rtx ();
12144 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12146 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12147 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12148 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12149 gen_rtx_LABEL_REF (VOIDmode, label),
12151 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12152 JUMP_LABEL (tmp) = label;
12154 emit_move_insn (operands[0], operands[1]);
12155 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12157 emit_label (label);
12158 LABEL_NUSES (label) = 1;
12163 (define_insn "ashrdi3_63_rex64"
12164 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12165 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12166 (match_operand:DI 2 "const_int_operand" "i,i")))
12167 (clobber (reg:CC FLAGS_REG))]
12168 "TARGET_64BIT && INTVAL (operands[2]) == 63
12169 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12170 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12173 sar{q}\t{%2, %0|%0, %2}"
12174 [(set_attr "type" "imovx,ishift")
12175 (set_attr "prefix_0f" "0,*")
12176 (set_attr "length_immediate" "0,*")
12177 (set_attr "modrm" "0,1")
12178 (set_attr "mode" "DI")])
12180 (define_insn "*ashrdi3_1_one_bit_rex64"
12181 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12182 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "const1_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12187 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189 [(set_attr "type" "ishift")
12190 (set (attr "length")
12191 (if_then_else (match_operand:DI 0 "register_operand" "")
12193 (const_string "*")))])
12195 (define_insn "*ashrdi3_1_rex64"
12196 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12197 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12198 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12199 (clobber (reg:CC FLAGS_REG))]
12200 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12202 sar{q}\t{%2, %0|%0, %2}
12203 sar{q}\t{%b2, %0|%0, %b2}"
12204 [(set_attr "type" "ishift")
12205 (set_attr "mode" "DI")])
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags. We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12211 [(set (reg FLAGS_REG)
12213 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12214 (match_operand:QI 2 "const1_operand" ""))
12216 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12220 && ix86_match_ccmode (insn, CCGOCmode)
12221 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:DI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12230 [(set (reg FLAGS_REG)
12232 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12233 (match_operand:QI 2 "const1_operand" ""))
12235 (clobber (match_scratch:DI 0 "=r"))]
12237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238 && ix86_match_ccmode (insn, CCGOCmode)
12239 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12241 [(set_attr "type" "ishift")
12242 (set_attr "length" "2")])
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags. We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrdi3_cmp_rex64"
12248 [(set (reg FLAGS_REG)
12250 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12251 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12253 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12254 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12256 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12257 && ix86_match_ccmode (insn, CCGOCmode)
12258 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12259 "sar{q}\t{%2, %0|%0, %2}"
12260 [(set_attr "type" "ishift")
12261 (set_attr "mode" "DI")])
12263 (define_insn "*ashrdi3_cconly_rex64"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269 (clobber (match_scratch:DI 0 "=r"))]
12271 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12272 && ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12274 "sar{q}\t{%2, %0|%0, %2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "DI")])
12278 (define_insn "*ashrdi3_1"
12279 [(set (match_operand:DI 0 "register_operand" "=r")
12280 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12281 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12282 (clobber (reg:CC FLAGS_REG))]
12285 [(set_attr "type" "multi")])
12287 ;; By default we don't ask for a scratch register, because when DImode
12288 ;; values are manipulated, registers are already at a premium. But if
12289 ;; we have one handy, we won't turn it away.
12291 [(match_scratch:SI 3 "r")
12292 (parallel [(set (match_operand:DI 0 "register_operand" "")
12293 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12294 (match_operand:QI 2 "nonmemory_operand" "")))
12295 (clobber (reg:CC FLAGS_REG))])
12297 "!TARGET_64BIT && TARGET_CMOVE"
12299 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12302 [(set (match_operand:DI 0 "register_operand" "")
12303 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12304 (match_operand:QI 2 "nonmemory_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12307 ? epilogue_completed : reload_completed)"
12309 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12311 (define_insn "x86_shrd"
12312 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12313 (ior:SI (ashiftrt:SI (match_dup 0)
12314 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12315 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12316 (minus:QI (const_int 32) (match_dup 2)))))
12317 (clobber (reg:CC FLAGS_REG))]
12319 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12320 [(set_attr "type" "ishift")
12321 (set_attr "prefix_0f" "1")
12322 (set_attr "pent_pair" "np")
12323 (set_attr "mode" "SI")])
12325 (define_expand "x86_shift_adj_3"
12326 [(use (match_operand:SI 0 "register_operand" ""))
12327 (use (match_operand:SI 1 "register_operand" ""))
12328 (use (match_operand:QI 2 "register_operand" ""))]
12331 rtx label = gen_label_rtx ();
12334 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12336 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12337 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12338 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12339 gen_rtx_LABEL_REF (VOIDmode, label),
12341 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12342 JUMP_LABEL (tmp) = label;
12344 emit_move_insn (operands[0], operands[1]);
12345 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12347 emit_label (label);
12348 LABEL_NUSES (label) = 1;
12353 (define_expand "ashrsi3_31"
12354 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12355 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12356 (match_operand:SI 2 "const_int_operand" "i,i")))
12357 (clobber (reg:CC FLAGS_REG))])]
12360 (define_insn "*ashrsi3_31"
12361 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12363 (match_operand:SI 2 "const_int_operand" "i,i")))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "INTVAL (operands[2]) == 31
12366 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12367 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12370 sar{l}\t{%2, %0|%0, %2}"
12371 [(set_attr "type" "imovx,ishift")
12372 (set_attr "prefix_0f" "0,*")
12373 (set_attr "length_immediate" "0,*")
12374 (set_attr "modrm" "0,1")
12375 (set_attr "mode" "SI")])
12377 (define_insn "*ashrsi3_31_zext"
12378 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12379 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12380 (match_operand:SI 2 "const_int_operand" "i,i"))))
12381 (clobber (reg:CC FLAGS_REG))]
12382 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383 && INTVAL (operands[2]) == 31
12384 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12387 sar{l}\t{%2, %k0|%k0, %2}"
12388 [(set_attr "type" "imovx,ishift")
12389 (set_attr "prefix_0f" "0,*")
12390 (set_attr "length_immediate" "0,*")
12391 (set_attr "modrm" "0,1")
12392 (set_attr "mode" "SI")])
12394 (define_expand "ashrsi3"
12395 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12396 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12397 (match_operand:QI 2 "nonmemory_operand" "")))]
12399 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12401 (define_insn "*ashrsi3_1_one_bit"
12402 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12403 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12404 (match_operand:QI 2 "const1_operand" "")))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12407 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409 [(set_attr "type" "ishift")
12410 (set (attr "length")
12411 (if_then_else (match_operand:SI 0 "register_operand" "")
12413 (const_string "*")))])
12415 (define_insn "*ashrsi3_1_one_bit_zext"
12416 [(set (match_operand:DI 0 "register_operand" "=r")
12417 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12418 (match_operand:QI 2 "const1_operand" ""))))
12419 (clobber (reg:CC FLAGS_REG))]
12421 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12422 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424 [(set_attr "type" "ishift")
12425 (set_attr "length" "2")])
12427 (define_insn "*ashrsi3_1"
12428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12429 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12430 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434 sar{l}\t{%2, %0|%0, %2}
12435 sar{l}\t{%b2, %0|%0, %b2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "SI")])
12439 (define_insn "*ashrsi3_1_zext"
12440 [(set (match_operand:DI 0 "register_operand" "=r,r")
12441 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12442 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12446 sar{l}\t{%2, %k0|%k0, %2}
12447 sar{l}\t{%b2, %k0|%k0, %b2}"
12448 [(set_attr "type" "ishift")
12449 (set_attr "mode" "SI")])
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags. We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrsi3_one_bit_cmp"
12455 [(set (reg FLAGS_REG)
12457 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458 (match_operand:QI 2 "const1_operand" ""))
12460 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12461 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12462 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12463 && ix86_match_ccmode (insn, CCGOCmode)
12464 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466 [(set_attr "type" "ishift")
12467 (set (attr "length")
12468 (if_then_else (match_operand:SI 0 "register_operand" "")
12470 (const_string "*")))])
12472 (define_insn "*ashrsi3_one_bit_cconly"
12473 [(set (reg FLAGS_REG)
12475 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const1_operand" ""))
12478 (clobber (match_scratch:SI 0 "=r"))]
12479 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12480 && ix86_match_ccmode (insn, CCGOCmode)
12481 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12483 [(set_attr "type" "ishift")
12484 (set_attr "length" "2")])
12486 (define_insn "*ashrsi3_one_bit_cmp_zext"
12487 [(set (reg FLAGS_REG)
12489 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12490 (match_operand:QI 2 "const1_operand" ""))
12492 (set (match_operand:DI 0 "register_operand" "=r")
12493 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496 && ix86_match_ccmode (insn, CCmode)
12497 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499 [(set_attr "type" "ishift")
12500 (set_attr "length" "2")])
12502 ;; This pattern can't accept a variable shift count, since shifts by
12503 ;; zero don't affect the flags. We assume that shifts by constant
12504 ;; zero are optimized away.
12505 (define_insn "*ashrsi3_cmp"
12506 [(set (reg FLAGS_REG)
12508 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12511 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12512 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12513 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12514 && ix86_match_ccmode (insn, CCGOCmode)
12515 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12516 "sar{l}\t{%2, %0|%0, %2}"
12517 [(set_attr "type" "ishift")
12518 (set_attr "mode" "SI")])
12520 (define_insn "*ashrsi3_cconly"
12521 [(set (reg FLAGS_REG)
12523 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12524 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526 (clobber (match_scratch:SI 0 "=r"))]
12527 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12528 && ix86_match_ccmode (insn, CCGOCmode)
12529 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12530 "sar{l}\t{%2, %0|%0, %2}"
12531 [(set_attr "type" "ishift")
12532 (set_attr "mode" "SI")])
12534 (define_insn "*ashrsi3_cmp_zext"
12535 [(set (reg FLAGS_REG)
12537 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12538 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540 (set (match_operand:DI 0 "register_operand" "=r")
12541 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12543 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544 && ix86_match_ccmode (insn, CCGOCmode)
12545 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546 "sar{l}\t{%2, %k0|%k0, %2}"
12547 [(set_attr "type" "ishift")
12548 (set_attr "mode" "SI")])
12550 (define_expand "ashrhi3"
12551 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12552 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12553 (match_operand:QI 2 "nonmemory_operand" "")))]
12554 "TARGET_HIMODE_MATH"
12555 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12557 (define_insn "*ashrhi3_1_one_bit"
12558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12559 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const1_operand" "")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12563 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12565 [(set_attr "type" "ishift")
12566 (set (attr "length")
12567 (if_then_else (match_operand 0 "register_operand" "")
12569 (const_string "*")))])
12571 (define_insn "*ashrhi3_1"
12572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12573 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12574 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12578 sar{w}\t{%2, %0|%0, %2}
12579 sar{w}\t{%b2, %0|%0, %b2}"
12580 [(set_attr "type" "ishift")
12581 (set_attr "mode" "HI")])
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags. We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*ashrhi3_one_bit_cmp"
12587 [(set (reg FLAGS_REG)
12589 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12590 (match_operand:QI 2 "const1_operand" ""))
12592 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12594 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12595 && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598 [(set_attr "type" "ishift")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12602 (const_string "*")))])
12604 (define_insn "*ashrhi3_one_bit_cconly"
12605 [(set (reg FLAGS_REG)
12607 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12608 (match_operand:QI 2 "const1_operand" ""))
12610 (clobber (match_scratch:HI 0 "=r"))]
12611 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12612 && ix86_match_ccmode (insn, CCGOCmode)
12613 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12615 [(set_attr "type" "ishift")
12616 (set_attr "length" "2")])
12618 ;; This pattern can't accept a variable shift count, since shifts by
12619 ;; zero don't affect the flags. We assume that shifts by constant
12620 ;; zero are optimized away.
12621 (define_insn "*ashrhi3_cmp"
12622 [(set (reg FLAGS_REG)
12624 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12625 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12627 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12628 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12629 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12630 && ix86_match_ccmode (insn, CCGOCmode)
12631 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12632 "sar{w}\t{%2, %0|%0, %2}"
12633 [(set_attr "type" "ishift")
12634 (set_attr "mode" "HI")])
12636 (define_insn "*ashrhi3_cconly"
12637 [(set (reg FLAGS_REG)
12639 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642 (clobber (match_scratch:HI 0 "=r"))]
12643 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12644 && ix86_match_ccmode (insn, CCGOCmode)
12645 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12646 "sar{w}\t{%2, %0|%0, %2}"
12647 [(set_attr "type" "ishift")
12648 (set_attr "mode" "HI")])
12650 (define_expand "ashrqi3"
12651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12652 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12653 (match_operand:QI 2 "nonmemory_operand" "")))]
12654 "TARGET_QIMODE_MATH"
12655 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12657 (define_insn "*ashrqi3_1_one_bit"
12658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const1_operand" "")))
12661 (clobber (reg:CC FLAGS_REG))]
12662 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12663 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12665 [(set_attr "type" "ishift")
12666 (set (attr "length")
12667 (if_then_else (match_operand 0 "register_operand" "")
12669 (const_string "*")))])
12671 (define_insn "*ashrqi3_1_one_bit_slp"
12672 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673 (ashiftrt:QI (match_dup 0)
12674 (match_operand:QI 1 "const1_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))]
12676 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12677 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12678 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680 [(set_attr "type" "ishift1")
12681 (set (attr "length")
12682 (if_then_else (match_operand 0 "register_operand" "")
12684 (const_string "*")))])
12686 (define_insn "*ashrqi3_1"
12687 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12688 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12689 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12693 sar{b}\t{%2, %0|%0, %2}
12694 sar{b}\t{%b2, %0|%0, %b2}"
12695 [(set_attr "type" "ishift")
12696 (set_attr "mode" "QI")])
12698 (define_insn "*ashrqi3_1_slp"
12699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12700 (ashiftrt:QI (match_dup 0)
12701 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12704 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706 sar{b}\t{%1, %0|%0, %1}
12707 sar{b}\t{%b1, %0|%0, %b1}"
12708 [(set_attr "type" "ishift1")
12709 (set_attr "mode" "QI")])
12711 ;; This pattern can't accept a variable shift count, since shifts by
12712 ;; zero don't affect the flags. We assume that shifts by constant
12713 ;; zero are optimized away.
12714 (define_insn "*ashrqi3_one_bit_cmp"
12715 [(set (reg FLAGS_REG)
12717 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718 (match_operand:QI 2 "const1_operand" "I"))
12720 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12721 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12722 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12723 && ix86_match_ccmode (insn, CCGOCmode)
12724 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726 [(set_attr "type" "ishift")
12727 (set (attr "length")
12728 (if_then_else (match_operand 0 "register_operand" "")
12730 (const_string "*")))])
12732 (define_insn "*ashrqi3_one_bit_cconly"
12733 [(set (reg FLAGS_REG)
12735 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12736 (match_operand:QI 2 "const1_operand" ""))
12738 (clobber (match_scratch:QI 0 "=q"))]
12739 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740 && ix86_match_ccmode (insn, CCGOCmode)
12741 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12743 [(set_attr "type" "ishift")
12744 (set_attr "length" "2")])
12746 ;; This pattern can't accept a variable shift count, since shifts by
12747 ;; zero don't affect the flags. We assume that shifts by constant
12748 ;; zero are optimized away.
12749 (define_insn "*ashrqi3_cmp"
12750 [(set (reg FLAGS_REG)
12752 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12753 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12755 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12756 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12757 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12758 && ix86_match_ccmode (insn, CCGOCmode)
12759 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12760 "sar{b}\t{%2, %0|%0, %2}"
12761 [(set_attr "type" "ishift")
12762 (set_attr "mode" "QI")])
12764 (define_insn "*ashrqi3_cconly"
12765 [(set (reg FLAGS_REG)
12767 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770 (clobber (match_scratch:QI 0 "=q"))]
12771 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12772 && ix86_match_ccmode (insn, CCGOCmode)
12773 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12774 "sar{b}\t{%2, %0|%0, %2}"
12775 [(set_attr "type" "ishift")
12776 (set_attr "mode" "QI")])
12779 ;; Logical shift instructions
12781 ;; See comment above `ashldi3' about how this works.
12783 (define_expand "lshrti3"
12784 [(set (match_operand:TI 0 "register_operand" "")
12785 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12786 (match_operand:QI 2 "nonmemory_operand" "")))]
12788 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12790 ;; This pattern must be defined before *lshrti3_1 to prevent
12791 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12793 (define_insn "*avx_lshrti3"
12794 [(set (match_operand:TI 0 "register_operand" "=x")
12795 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12796 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12799 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12800 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12802 [(set_attr "type" "sseishft")
12803 (set_attr "prefix" "vex")
12804 (set_attr "mode" "TI")])
12806 (define_insn "sse2_lshrti3"
12807 [(set (match_operand:TI 0 "register_operand" "=x")
12808 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12809 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12812 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12813 return "psrldq\t{%2, %0|%0, %2}";
12815 [(set_attr "type" "sseishft")
12816 (set_attr "prefix_data16" "1")
12817 (set_attr "mode" "TI")])
12819 (define_insn "*lshrti3_1"
12820 [(set (match_operand:TI 0 "register_operand" "=r")
12821 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12822 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12823 (clobber (reg:CC FLAGS_REG))]
12826 [(set_attr "type" "multi")])
12829 [(match_scratch:DI 3 "r")
12830 (parallel [(set (match_operand:TI 0 "register_operand" "")
12831 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12832 (match_operand:QI 2 "nonmemory_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))])
12837 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12840 [(set (match_operand:TI 0 "register_operand" "")
12841 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12842 (match_operand:QI 2 "nonmemory_operand" "")))
12843 (clobber (reg:CC FLAGS_REG))]
12844 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12845 ? epilogue_completed : reload_completed)"
12847 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12849 (define_expand "lshrdi3"
12850 [(set (match_operand:DI 0 "shiftdi_operand" "")
12851 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))]
12854 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12856 (define_insn "*lshrdi3_1_one_bit_rex64"
12857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12858 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12859 (match_operand:QI 2 "const1_operand" "")))
12860 (clobber (reg:CC FLAGS_REG))]
12862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 [(set_attr "type" "ishift")
12866 (set (attr "length")
12867 (if_then_else (match_operand:DI 0 "register_operand" "")
12869 (const_string "*")))])
12871 (define_insn "*lshrdi3_1_rex64"
12872 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{q}\t{%2, %0|%0, %2}
12879 shr{q}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "DI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags. We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const1_operand" ""))
12892 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12895 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12896 && ix86_match_ccmode (insn, CCGOCmode)
12897 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899 [(set_attr "type" "ishift")
12900 (set (attr "length")
12901 (if_then_else (match_operand:DI 0 "register_operand" "")
12903 (const_string "*")))])
12905 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12906 [(set (reg FLAGS_REG)
12908 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12909 (match_operand:QI 2 "const1_operand" ""))
12911 (clobber (match_scratch:DI 0 "=r"))]
12913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12914 && ix86_match_ccmode (insn, CCGOCmode)
12915 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12917 [(set_attr "type" "ishift")
12918 (set_attr "length" "2")])
12920 ;; This pattern can't accept a variable shift count, since shifts by
12921 ;; zero don't affect the flags. We assume that shifts by constant
12922 ;; zero are optimized away.
12923 (define_insn "*lshrdi3_cmp_rex64"
12924 [(set (reg FLAGS_REG)
12926 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12927 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12929 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12930 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12932 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12933 && ix86_match_ccmode (insn, CCGOCmode)
12934 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935 "shr{q}\t{%2, %0|%0, %2}"
12936 [(set_attr "type" "ishift")
12937 (set_attr "mode" "DI")])
12939 (define_insn "*lshrdi3_cconly_rex64"
12940 [(set (reg FLAGS_REG)
12942 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945 (clobber (match_scratch:DI 0 "=r"))]
12947 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12948 && ix86_match_ccmode (insn, CCGOCmode)
12949 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12950 "shr{q}\t{%2, %0|%0, %2}"
12951 [(set_attr "type" "ishift")
12952 (set_attr "mode" "DI")])
12954 (define_insn "*lshrdi3_1"
12955 [(set (match_operand:DI 0 "register_operand" "=r")
12956 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12957 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12958 (clobber (reg:CC FLAGS_REG))]
12961 [(set_attr "type" "multi")])
12963 ;; By default we don't ask for a scratch register, because when DImode
12964 ;; values are manipulated, registers are already at a premium. But if
12965 ;; we have one handy, we won't turn it away.
12967 [(match_scratch:SI 3 "r")
12968 (parallel [(set (match_operand:DI 0 "register_operand" "")
12969 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))])
12973 "!TARGET_64BIT && TARGET_CMOVE"
12975 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12978 [(set (match_operand:DI 0 "register_operand" "")
12979 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12980 (match_operand:QI 2 "nonmemory_operand" "")))
12981 (clobber (reg:CC FLAGS_REG))]
12982 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12983 ? epilogue_completed : reload_completed)"
12985 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12987 (define_expand "lshrsi3"
12988 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12989 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))]
12992 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12994 (define_insn "*lshrsi3_1_one_bit"
12995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12996 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12997 (match_operand:QI 2 "const1_operand" "")))
12998 (clobber (reg:CC FLAGS_REG))]
12999 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13000 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13002 [(set_attr "type" "ishift")
13003 (set (attr "length")
13004 (if_then_else (match_operand:SI 0 "register_operand" "")
13006 (const_string "*")))])
13008 (define_insn "*lshrsi3_1_one_bit_zext"
13009 [(set (match_operand:DI 0 "register_operand" "=r")
13010 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13011 (match_operand:QI 2 "const1_operand" "")))
13012 (clobber (reg:CC FLAGS_REG))]
13014 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13015 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017 [(set_attr "type" "ishift")
13018 (set_attr "length" "2")])
13020 (define_insn "*lshrsi3_1"
13021 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13022 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13023 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 shr{l}\t{%2, %0|%0, %2}
13028 shr{l}\t{%b2, %0|%0, %b2}"
13029 [(set_attr "type" "ishift")
13030 (set_attr "mode" "SI")])
13032 (define_insn "*lshrsi3_1_zext"
13033 [(set (match_operand:DI 0 "register_operand" "=r,r")
13035 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13036 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13037 (clobber (reg:CC FLAGS_REG))]
13038 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13040 shr{l}\t{%2, %k0|%k0, %2}
13041 shr{l}\t{%b2, %k0|%k0, %b2}"
13042 [(set_attr "type" "ishift")
13043 (set_attr "mode" "SI")])
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags. We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrsi3_one_bit_cmp"
13049 [(set (reg FLAGS_REG)
13051 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13052 (match_operand:QI 2 "const1_operand" ""))
13054 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13055 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13056 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13057 && ix86_match_ccmode (insn, CCGOCmode)
13058 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060 [(set_attr "type" "ishift")
13061 (set (attr "length")
13062 (if_then_else (match_operand:SI 0 "register_operand" "")
13064 (const_string "*")))])
13066 (define_insn "*lshrsi3_one_bit_cconly"
13067 [(set (reg FLAGS_REG)
13069 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13070 (match_operand:QI 2 "const1_operand" ""))
13072 (clobber (match_scratch:SI 0 "=r"))]
13073 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13074 && ix86_match_ccmode (insn, CCGOCmode)
13075 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13077 [(set_attr "type" "ishift")
13078 (set_attr "length" "2")])
13080 (define_insn "*lshrsi3_cmp_one_bit_zext"
13081 [(set (reg FLAGS_REG)
13083 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13084 (match_operand:QI 2 "const1_operand" ""))
13086 (set (match_operand:DI 0 "register_operand" "=r")
13087 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13089 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090 && ix86_match_ccmode (insn, CCGOCmode)
13091 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093 [(set_attr "type" "ishift")
13094 (set_attr "length" "2")])
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags. We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrsi3_cmp"
13100 [(set (reg FLAGS_REG)
13102 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13107 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13108 && ix86_match_ccmode (insn, CCGOCmode)
13109 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13110 "shr{l}\t{%2, %0|%0, %2}"
13111 [(set_attr "type" "ishift")
13112 (set_attr "mode" "SI")])
13114 (define_insn "*lshrsi3_cconly"
13115 [(set (reg FLAGS_REG)
13117 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13118 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120 (clobber (match_scratch:SI 0 "=r"))]
13121 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13122 && ix86_match_ccmode (insn, CCGOCmode)
13123 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13124 "shr{l}\t{%2, %0|%0, %2}"
13125 [(set_attr "type" "ishift")
13126 (set_attr "mode" "SI")])
13128 (define_insn "*lshrsi3_cmp_zext"
13129 [(set (reg FLAGS_REG)
13131 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13132 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13134 (set (match_operand:DI 0 "register_operand" "=r")
13135 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13137 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138 && ix86_match_ccmode (insn, CCGOCmode)
13139 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140 "shr{l}\t{%2, %k0|%k0, %2}"
13141 [(set_attr "type" "ishift")
13142 (set_attr "mode" "SI")])
13144 (define_expand "lshrhi3"
13145 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13146 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13147 (match_operand:QI 2 "nonmemory_operand" "")))]
13148 "TARGET_HIMODE_MATH"
13149 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13151 (define_insn "*lshrhi3_1_one_bit"
13152 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13153 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13154 (match_operand:QI 2 "const1_operand" "")))
13155 (clobber (reg:CC FLAGS_REG))]
13156 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13157 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13159 [(set_attr "type" "ishift")
13160 (set (attr "length")
13161 (if_then_else (match_operand 0 "register_operand" "")
13163 (const_string "*")))])
13165 (define_insn "*lshrhi3_1"
13166 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13167 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13168 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13172 shr{w}\t{%2, %0|%0, %2}
13173 shr{w}\t{%b2, %0|%0, %b2}"
13174 [(set_attr "type" "ishift")
13175 (set_attr "mode" "HI")])
13177 ;; This pattern can't accept a variable shift count, since shifts by
13178 ;; zero don't affect the flags. We assume that shifts by constant
13179 ;; zero are optimized away.
13180 (define_insn "*lshrhi3_one_bit_cmp"
13181 [(set (reg FLAGS_REG)
13183 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13184 (match_operand:QI 2 "const1_operand" ""))
13186 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13188 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13189 && ix86_match_ccmode (insn, CCGOCmode)
13190 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192 [(set_attr "type" "ishift")
13193 (set (attr "length")
13194 (if_then_else (match_operand:SI 0 "register_operand" "")
13196 (const_string "*")))])
13198 (define_insn "*lshrhi3_one_bit_cconly"
13199 [(set (reg FLAGS_REG)
13201 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13202 (match_operand:QI 2 "const1_operand" ""))
13204 (clobber (match_scratch:HI 0 "=r"))]
13205 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13206 && ix86_match_ccmode (insn, CCGOCmode)
13207 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13209 [(set_attr "type" "ishift")
13210 (set_attr "length" "2")])
13212 ;; This pattern can't accept a variable shift count, since shifts by
13213 ;; zero don't affect the flags. We assume that shifts by constant
13214 ;; zero are optimized away.
13215 (define_insn "*lshrhi3_cmp"
13216 [(set (reg FLAGS_REG)
13218 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13219 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13221 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13222 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13223 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13224 && ix86_match_ccmode (insn, CCGOCmode)
13225 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13226 "shr{w}\t{%2, %0|%0, %2}"
13227 [(set_attr "type" "ishift")
13228 (set_attr "mode" "HI")])
13230 (define_insn "*lshrhi3_cconly"
13231 [(set (reg FLAGS_REG)
13233 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236 (clobber (match_scratch:HI 0 "=r"))]
13237 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13238 && ix86_match_ccmode (insn, CCGOCmode)
13239 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13240 "shr{w}\t{%2, %0|%0, %2}"
13241 [(set_attr "type" "ishift")
13242 (set_attr "mode" "HI")])
13244 (define_expand "lshrqi3"
13245 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13246 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13247 (match_operand:QI 2 "nonmemory_operand" "")))]
13248 "TARGET_QIMODE_MATH"
13249 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13251 (define_insn "*lshrqi3_1_one_bit"
13252 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13253 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13254 (match_operand:QI 2 "const1_operand" "")))
13255 (clobber (reg:CC FLAGS_REG))]
13256 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13257 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13259 [(set_attr "type" "ishift")
13260 (set (attr "length")
13261 (if_then_else (match_operand 0 "register_operand" "")
13263 (const_string "*")))])
13265 (define_insn "*lshrqi3_1_one_bit_slp"
13266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13267 (lshiftrt:QI (match_dup 0)
13268 (match_operand:QI 1 "const1_operand" "")))
13269 (clobber (reg:CC FLAGS_REG))]
13270 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13273 [(set_attr "type" "ishift1")
13274 (set (attr "length")
13275 (if_then_else (match_operand 0 "register_operand" "")
13277 (const_string "*")))])
13279 (define_insn "*lshrqi3_1"
13280 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13281 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13282 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283 (clobber (reg:CC FLAGS_REG))]
13284 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13286 shr{b}\t{%2, %0|%0, %2}
13287 shr{b}\t{%b2, %0|%0, %b2}"
13288 [(set_attr "type" "ishift")
13289 (set_attr "mode" "QI")])
13291 (define_insn "*lshrqi3_1_slp"
13292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293 (lshiftrt:QI (match_dup 0)
13294 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295 (clobber (reg:CC FLAGS_REG))]
13296 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13297 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 shr{b}\t{%1, %0|%0, %1}
13300 shr{b}\t{%b1, %0|%0, %b1}"
13301 [(set_attr "type" "ishift1")
13302 (set_attr "mode" "QI")])
13304 ;; This pattern can't accept a variable shift count, since shifts by
13305 ;; zero don't affect the flags. We assume that shifts by constant
13306 ;; zero are optimized away.
13307 (define_insn "*lshrqi2_one_bit_cmp"
13308 [(set (reg FLAGS_REG)
13310 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13311 (match_operand:QI 2 "const1_operand" ""))
13313 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13314 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13315 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316 && ix86_match_ccmode (insn, CCGOCmode)
13317 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319 [(set_attr "type" "ishift")
13320 (set (attr "length")
13321 (if_then_else (match_operand:SI 0 "register_operand" "")
13323 (const_string "*")))])
13325 (define_insn "*lshrqi2_one_bit_cconly"
13326 [(set (reg FLAGS_REG)
13328 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13329 (match_operand:QI 2 "const1_operand" ""))
13331 (clobber (match_scratch:QI 0 "=q"))]
13332 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333 && ix86_match_ccmode (insn, CCGOCmode)
13334 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336 [(set_attr "type" "ishift")
13337 (set_attr "length" "2")])
13339 ;; This pattern can't accept a variable shift count, since shifts by
13340 ;; zero don't affect the flags. We assume that shifts by constant
13341 ;; zero are optimized away.
13342 (define_insn "*lshrqi2_cmp"
13343 [(set (reg FLAGS_REG)
13345 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13346 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13348 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13349 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13350 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13351 && ix86_match_ccmode (insn, CCGOCmode)
13352 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13353 "shr{b}\t{%2, %0|%0, %2}"
13354 [(set_attr "type" "ishift")
13355 (set_attr "mode" "QI")])
13357 (define_insn "*lshrqi2_cconly"
13358 [(set (reg FLAGS_REG)
13360 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13361 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363 (clobber (match_scratch:QI 0 "=q"))]
13364 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13365 && ix86_match_ccmode (insn, CCGOCmode)
13366 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13367 "shr{b}\t{%2, %0|%0, %2}"
13368 [(set_attr "type" "ishift")
13369 (set_attr "mode" "QI")])
13371 ;; Rotate instructions
13373 (define_expand "rotldi3"
13374 [(set (match_operand:DI 0 "shiftdi_operand" "")
13375 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13376 (match_operand:QI 2 "nonmemory_operand" "")))]
13381 ix86_expand_binary_operator (ROTATE, DImode, operands);
13384 if (!const_1_to_31_operand (operands[2], VOIDmode))
13386 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13390 ;; Implement rotation using two double-precision shift instructions
13391 ;; and a scratch register.
13392 (define_insn_and_split "ix86_rotldi3"
13393 [(set (match_operand:DI 0 "register_operand" "=r")
13394 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13395 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13396 (clobber (reg:CC FLAGS_REG))
13397 (clobber (match_scratch:SI 3 "=&r"))]
13400 "&& reload_completed"
13401 [(set (match_dup 3) (match_dup 4))
13403 [(set (match_dup 4)
13404 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13405 (lshiftrt:SI (match_dup 5)
13406 (minus:QI (const_int 32) (match_dup 2)))))
13407 (clobber (reg:CC FLAGS_REG))])
13409 [(set (match_dup 5)
13410 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13411 (lshiftrt:SI (match_dup 3)
13412 (minus:QI (const_int 32) (match_dup 2)))))
13413 (clobber (reg:CC FLAGS_REG))])]
13414 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13416 (define_insn "*rotlsi3_1_one_bit_rex64"
13417 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13418 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13419 (match_operand:QI 2 "const1_operand" "")))
13420 (clobber (reg:CC FLAGS_REG))]
13422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13425 [(set_attr "type" "rotate")
13426 (set (attr "length")
13427 (if_then_else (match_operand:DI 0 "register_operand" "")
13429 (const_string "*")))])
13431 (define_insn "*rotldi3_1_rex64"
13432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13433 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13434 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13435 (clobber (reg:CC FLAGS_REG))]
13436 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13438 rol{q}\t{%2, %0|%0, %2}
13439 rol{q}\t{%b2, %0|%0, %b2}"
13440 [(set_attr "type" "rotate")
13441 (set_attr "mode" "DI")])
13443 (define_expand "rotlsi3"
13444 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13445 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13446 (match_operand:QI 2 "nonmemory_operand" "")))]
13448 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13450 (define_insn "*rotlsi3_1_one_bit"
13451 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13452 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13453 (match_operand:QI 2 "const1_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13456 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13458 [(set_attr "type" "rotate")
13459 (set (attr "length")
13460 (if_then_else (match_operand:SI 0 "register_operand" "")
13462 (const_string "*")))])
13464 (define_insn "*rotlsi3_1_one_bit_zext"
13465 [(set (match_operand:DI 0 "register_operand" "=r")
13467 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13468 (match_operand:QI 2 "const1_operand" ""))))
13469 (clobber (reg:CC FLAGS_REG))]
13471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474 [(set_attr "type" "rotate")
13475 (set_attr "length" "2")])
13477 (define_insn "*rotlsi3_1"
13478 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13479 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13480 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481 (clobber (reg:CC FLAGS_REG))]
13482 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13484 rol{l}\t{%2, %0|%0, %2}
13485 rol{l}\t{%b2, %0|%0, %b2}"
13486 [(set_attr "type" "rotate")
13487 (set_attr "mode" "SI")])
13489 (define_insn "*rotlsi3_1_zext"
13490 [(set (match_operand:DI 0 "register_operand" "=r,r")
13492 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13493 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13494 (clobber (reg:CC FLAGS_REG))]
13495 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13497 rol{l}\t{%2, %k0|%k0, %2}
13498 rol{l}\t{%b2, %k0|%k0, %b2}"
13499 [(set_attr "type" "rotate")
13500 (set_attr "mode" "SI")])
13502 (define_expand "rotlhi3"
13503 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13504 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13505 (match_operand:QI 2 "nonmemory_operand" "")))]
13506 "TARGET_HIMODE_MATH"
13507 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13509 (define_insn "*rotlhi3_1_one_bit"
13510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13511 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13512 (match_operand:QI 2 "const1_operand" "")))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13515 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13517 [(set_attr "type" "rotate")
13518 (set (attr "length")
13519 (if_then_else (match_operand 0 "register_operand" "")
13521 (const_string "*")))])
13523 (define_insn "*rotlhi3_1"
13524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13525 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13526 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13527 (clobber (reg:CC FLAGS_REG))]
13528 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13530 rol{w}\t{%2, %0|%0, %2}
13531 rol{w}\t{%b2, %0|%0, %b2}"
13532 [(set_attr "type" "rotate")
13533 (set_attr "mode" "HI")])
13536 [(set (match_operand:HI 0 "register_operand" "")
13537 (rotate:HI (match_dup 0) (const_int 8)))
13538 (clobber (reg:CC FLAGS_REG))]
13540 [(parallel [(set (strict_low_part (match_dup 0))
13541 (bswap:HI (match_dup 0)))
13542 (clobber (reg:CC FLAGS_REG))])]
13545 (define_expand "rotlqi3"
13546 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13547 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13548 (match_operand:QI 2 "nonmemory_operand" "")))]
13549 "TARGET_QIMODE_MATH"
13550 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13552 (define_insn "*rotlqi3_1_one_bit_slp"
13553 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13554 (rotate:QI (match_dup 0)
13555 (match_operand:QI 1 "const1_operand" "")))
13556 (clobber (reg:CC FLAGS_REG))]
13557 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13560 [(set_attr "type" "rotate1")
13561 (set (attr "length")
13562 (if_then_else (match_operand 0 "register_operand" "")
13564 (const_string "*")))])
13566 (define_insn "*rotlqi3_1_one_bit"
13567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13568 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13569 (match_operand:QI 2 "const1_operand" "")))
13570 (clobber (reg:CC FLAGS_REG))]
13571 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13572 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13574 [(set_attr "type" "rotate")
13575 (set (attr "length")
13576 (if_then_else (match_operand 0 "register_operand" "")
13578 (const_string "*")))])
13580 (define_insn "*rotlqi3_1_slp"
13581 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13582 (rotate:QI (match_dup 0)
13583 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13584 (clobber (reg:CC FLAGS_REG))]
13585 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13586 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13588 rol{b}\t{%1, %0|%0, %1}
13589 rol{b}\t{%b1, %0|%0, %b1}"
13590 [(set_attr "type" "rotate1")
13591 (set_attr "mode" "QI")])
13593 (define_insn "*rotlqi3_1"
13594 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13595 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13596 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13597 (clobber (reg:CC FLAGS_REG))]
13598 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13600 rol{b}\t{%2, %0|%0, %2}
13601 rol{b}\t{%b2, %0|%0, %b2}"
13602 [(set_attr "type" "rotate")
13603 (set_attr "mode" "QI")])
13605 (define_expand "rotrdi3"
13606 [(set (match_operand:DI 0 "shiftdi_operand" "")
13607 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13608 (match_operand:QI 2 "nonmemory_operand" "")))]
13613 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13616 if (!const_1_to_31_operand (operands[2], VOIDmode))
13618 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13622 ;; Implement rotation using two double-precision shift instructions
13623 ;; and a scratch register.
13624 (define_insn_and_split "ix86_rotrdi3"
13625 [(set (match_operand:DI 0 "register_operand" "=r")
13626 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13627 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13628 (clobber (reg:CC FLAGS_REG))
13629 (clobber (match_scratch:SI 3 "=&r"))]
13632 "&& reload_completed"
13633 [(set (match_dup 3) (match_dup 4))
13635 [(set (match_dup 4)
13636 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13637 (ashift:SI (match_dup 5)
13638 (minus:QI (const_int 32) (match_dup 2)))))
13639 (clobber (reg:CC FLAGS_REG))])
13641 [(set (match_dup 5)
13642 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13643 (ashift:SI (match_dup 3)
13644 (minus:QI (const_int 32) (match_dup 2)))))
13645 (clobber (reg:CC FLAGS_REG))])]
13646 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13648 (define_insn "*rotrdi3_1_one_bit_rex64"
13649 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13650 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13651 (match_operand:QI 2 "const1_operand" "")))
13652 (clobber (reg:CC FLAGS_REG))]
13654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13655 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13657 [(set_attr "type" "rotate")
13658 (set (attr "length")
13659 (if_then_else (match_operand:DI 0 "register_operand" "")
13661 (const_string "*")))])
13663 (define_insn "*rotrdi3_1_rex64"
13664 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13665 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13666 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13667 (clobber (reg:CC FLAGS_REG))]
13668 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13670 ror{q}\t{%2, %0|%0, %2}
13671 ror{q}\t{%b2, %0|%0, %b2}"
13672 [(set_attr "type" "rotate")
13673 (set_attr "mode" "DI")])
13675 (define_expand "rotrsi3"
13676 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13677 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13678 (match_operand:QI 2 "nonmemory_operand" "")))]
13680 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13682 (define_insn "*rotrsi3_1_one_bit"
13683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13684 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13685 (match_operand:QI 2 "const1_operand" "")))
13686 (clobber (reg:CC FLAGS_REG))]
13687 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13688 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13690 [(set_attr "type" "rotate")
13691 (set (attr "length")
13692 (if_then_else (match_operand:SI 0 "register_operand" "")
13694 (const_string "*")))])
13696 (define_insn "*rotrsi3_1_one_bit_zext"
13697 [(set (match_operand:DI 0 "register_operand" "=r")
13699 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13700 (match_operand:QI 2 "const1_operand" ""))))
13701 (clobber (reg:CC FLAGS_REG))]
13703 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706 [(set_attr "type" "rotate")
13707 (set (attr "length")
13708 (if_then_else (match_operand:SI 0 "register_operand" "")
13710 (const_string "*")))])
13712 (define_insn "*rotrsi3_1"
13713 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13714 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13715 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13716 (clobber (reg:CC FLAGS_REG))]
13717 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13719 ror{l}\t{%2, %0|%0, %2}
13720 ror{l}\t{%b2, %0|%0, %b2}"
13721 [(set_attr "type" "rotate")
13722 (set_attr "mode" "SI")])
13724 (define_insn "*rotrsi3_1_zext"
13725 [(set (match_operand:DI 0 "register_operand" "=r,r")
13727 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13728 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13729 (clobber (reg:CC FLAGS_REG))]
13730 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13732 ror{l}\t{%2, %k0|%k0, %2}
13733 ror{l}\t{%b2, %k0|%k0, %b2}"
13734 [(set_attr "type" "rotate")
13735 (set_attr "mode" "SI")])
13737 (define_expand "rotrhi3"
13738 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13739 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13740 (match_operand:QI 2 "nonmemory_operand" "")))]
13741 "TARGET_HIMODE_MATH"
13742 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13744 (define_insn "*rotrhi3_one_bit"
13745 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13746 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13747 (match_operand:QI 2 "const1_operand" "")))
13748 (clobber (reg:CC FLAGS_REG))]
13749 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13750 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13752 [(set_attr "type" "rotate")
13753 (set (attr "length")
13754 (if_then_else (match_operand 0 "register_operand" "")
13756 (const_string "*")))])
13758 (define_insn "*rotrhi3_1"
13759 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13760 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13761 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13762 (clobber (reg:CC FLAGS_REG))]
13763 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13765 ror{w}\t{%2, %0|%0, %2}
13766 ror{w}\t{%b2, %0|%0, %b2}"
13767 [(set_attr "type" "rotate")
13768 (set_attr "mode" "HI")])
13771 [(set (match_operand:HI 0 "register_operand" "")
13772 (rotatert:HI (match_dup 0) (const_int 8)))
13773 (clobber (reg:CC FLAGS_REG))]
13775 [(parallel [(set (strict_low_part (match_dup 0))
13776 (bswap:HI (match_dup 0)))
13777 (clobber (reg:CC FLAGS_REG))])]
13780 (define_expand "rotrqi3"
13781 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13782 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13783 (match_operand:QI 2 "nonmemory_operand" "")))]
13784 "TARGET_QIMODE_MATH"
13785 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13787 (define_insn "*rotrqi3_1_one_bit"
13788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13789 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13790 (match_operand:QI 2 "const1_operand" "")))
13791 (clobber (reg:CC FLAGS_REG))]
13792 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13793 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13795 [(set_attr "type" "rotate")
13796 (set (attr "length")
13797 (if_then_else (match_operand 0 "register_operand" "")
13799 (const_string "*")))])
13801 (define_insn "*rotrqi3_1_one_bit_slp"
13802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13803 (rotatert:QI (match_dup 0)
13804 (match_operand:QI 1 "const1_operand" "")))
13805 (clobber (reg:CC FLAGS_REG))]
13806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13809 [(set_attr "type" "rotate1")
13810 (set (attr "length")
13811 (if_then_else (match_operand 0 "register_operand" "")
13813 (const_string "*")))])
13815 (define_insn "*rotrqi3_1"
13816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13817 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13819 (clobber (reg:CC FLAGS_REG))]
13820 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13822 ror{b}\t{%2, %0|%0, %2}
13823 ror{b}\t{%b2, %0|%0, %b2}"
13824 [(set_attr "type" "rotate")
13825 (set_attr "mode" "QI")])
13827 (define_insn "*rotrqi3_1_slp"
13828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13829 (rotatert:QI (match_dup 0)
13830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13831 (clobber (reg:CC FLAGS_REG))]
13832 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13833 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13835 ror{b}\t{%1, %0|%0, %1}
13836 ror{b}\t{%b1, %0|%0, %b1}"
13837 [(set_attr "type" "rotate1")
13838 (set_attr "mode" "QI")])
13840 ;; Bit set / bit test instructions
13842 (define_expand "extv"
13843 [(set (match_operand:SI 0 "register_operand" "")
13844 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13845 (match_operand:SI 2 "const8_operand" "")
13846 (match_operand:SI 3 "const8_operand" "")))]
13849 /* Handle extractions from %ah et al. */
13850 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13853 /* From mips.md: extract_bit_field doesn't verify that our source
13854 matches the predicate, so check it again here. */
13855 if (! ext_register_operand (operands[1], VOIDmode))
13859 (define_expand "extzv"
13860 [(set (match_operand:SI 0 "register_operand" "")
13861 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13862 (match_operand:SI 2 "const8_operand" "")
13863 (match_operand:SI 3 "const8_operand" "")))]
13866 /* Handle extractions from %ah et al. */
13867 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13870 /* From mips.md: extract_bit_field doesn't verify that our source
13871 matches the predicate, so check it again here. */
13872 if (! ext_register_operand (operands[1], VOIDmode))
13876 (define_expand "insv"
13877 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13878 (match_operand 1 "const8_operand" "")
13879 (match_operand 2 "const8_operand" ""))
13880 (match_operand 3 "register_operand" ""))]
13883 /* Handle insertions to %ah et al. */
13884 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13887 /* From mips.md: insert_bit_field doesn't verify that our source
13888 matches the predicate, so check it again here. */
13889 if (! ext_register_operand (operands[0], VOIDmode))
13893 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13895 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13900 ;; %%% bts, btr, btc, bt.
13901 ;; In general these instructions are *slow* when applied to memory,
13902 ;; since they enforce atomic operation. When applied to registers,
13903 ;; it depends on the cpu implementation. They're never faster than
13904 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13905 ;; no point. But in 64-bit, we can't hold the relevant immediates
13906 ;; within the instruction itself, so operating on bits in the high
13907 ;; 32-bits of a register becomes easier.
13909 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13910 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13911 ;; negdf respectively, so they can never be disabled entirely.
13913 (define_insn "*btsq"
13914 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13916 (match_operand:DI 1 "const_0_to_63_operand" ""))
13918 (clobber (reg:CC FLAGS_REG))]
13919 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13920 "bts{q}\t{%1, %0|%0, %1}"
13921 [(set_attr "type" "alu1")])
13923 (define_insn "*btrq"
13924 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13926 (match_operand:DI 1 "const_0_to_63_operand" ""))
13928 (clobber (reg:CC FLAGS_REG))]
13929 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13930 "btr{q}\t{%1, %0|%0, %1}"
13931 [(set_attr "type" "alu1")])
13933 (define_insn "*btcq"
13934 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936 (match_operand:DI 1 "const_0_to_63_operand" ""))
13937 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13938 (clobber (reg:CC FLAGS_REG))]
13939 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940 "btc{q}\t{%1, %0|%0, %1}"
13941 [(set_attr "type" "alu1")])
13943 ;; Allow Nocona to avoid these instructions if a register is available.
13946 [(match_scratch:DI 2 "r")
13947 (parallel [(set (zero_extract:DI
13948 (match_operand:DI 0 "register_operand" "")
13950 (match_operand:DI 1 "const_0_to_63_operand" ""))
13952 (clobber (reg:CC FLAGS_REG))])]
13953 "TARGET_64BIT && !TARGET_USE_BT"
13956 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13959 if (HOST_BITS_PER_WIDE_INT >= 64)
13960 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13961 else if (i < HOST_BITS_PER_WIDE_INT)
13962 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13964 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13966 op1 = immed_double_const (lo, hi, DImode);
13969 emit_move_insn (operands[2], op1);
13973 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13978 [(match_scratch:DI 2 "r")
13979 (parallel [(set (zero_extract:DI
13980 (match_operand:DI 0 "register_operand" "")
13982 (match_operand:DI 1 "const_0_to_63_operand" ""))
13984 (clobber (reg:CC FLAGS_REG))])]
13985 "TARGET_64BIT && !TARGET_USE_BT"
13988 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13991 if (HOST_BITS_PER_WIDE_INT >= 64)
13992 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13993 else if (i < HOST_BITS_PER_WIDE_INT)
13994 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13996 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13998 op1 = immed_double_const (~lo, ~hi, DImode);
14001 emit_move_insn (operands[2], op1);
14005 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14010 [(match_scratch:DI 2 "r")
14011 (parallel [(set (zero_extract:DI
14012 (match_operand:DI 0 "register_operand" "")
14014 (match_operand:DI 1 "const_0_to_63_operand" ""))
14015 (not:DI (zero_extract:DI
14016 (match_dup 0) (const_int 1) (match_dup 1))))
14017 (clobber (reg:CC FLAGS_REG))])]
14018 "TARGET_64BIT && !TARGET_USE_BT"
14021 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14024 if (HOST_BITS_PER_WIDE_INT >= 64)
14025 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14026 else if (i < HOST_BITS_PER_WIDE_INT)
14027 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031 op1 = immed_double_const (lo, hi, DImode);
14034 emit_move_insn (operands[2], op1);
14038 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14042 (define_insn "*btdi_rex64"
14043 [(set (reg:CCC FLAGS_REG)
14046 (match_operand:DI 0 "register_operand" "r")
14048 (match_operand:DI 1 "nonmemory_operand" "rN"))
14050 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14051 "bt{q}\t{%1, %0|%0, %1}"
14052 [(set_attr "type" "alu1")])
14054 (define_insn "*btsi"
14055 [(set (reg:CCC FLAGS_REG)
14058 (match_operand:SI 0 "register_operand" "r")
14060 (match_operand:SI 1 "nonmemory_operand" "rN"))
14062 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14063 "bt{l}\t{%1, %0|%0, %1}"
14064 [(set_attr "type" "alu1")])
14066 ;; Store-flag instructions.
14068 ;; For all sCOND expanders, also expand the compare or test insn that
14069 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14071 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14072 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14073 ;; way, which can later delete the movzx if only QImode is needed.
14075 (define_expand "s<code>"
14076 [(set (match_operand:QI 0 "register_operand" "")
14077 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14079 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14081 (define_expand "s<code>"
14082 [(set (match_operand:QI 0 "register_operand" "")
14083 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14084 "TARGET_80387 || TARGET_SSE"
14085 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14087 (define_insn "*setcc_1"
14088 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14089 (match_operator:QI 1 "ix86_comparison_operator"
14090 [(reg FLAGS_REG) (const_int 0)]))]
14093 [(set_attr "type" "setcc")
14094 (set_attr "mode" "QI")])
14096 (define_insn "*setcc_2"
14097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14098 (match_operator:QI 1 "ix86_comparison_operator"
14099 [(reg FLAGS_REG) (const_int 0)]))]
14102 [(set_attr "type" "setcc")
14103 (set_attr "mode" "QI")])
14105 ;; In general it is not safe to assume too much about CCmode registers,
14106 ;; so simplify-rtx stops when it sees a second one. Under certain
14107 ;; conditions this is safe on x86, so help combine not create
14114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14115 (ne:QI (match_operator 1 "ix86_comparison_operator"
14116 [(reg FLAGS_REG) (const_int 0)])
14119 [(set (match_dup 0) (match_dup 1))]
14121 PUT_MODE (operands[1], QImode);
14125 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14126 (ne:QI (match_operator 1 "ix86_comparison_operator"
14127 [(reg FLAGS_REG) (const_int 0)])
14130 [(set (match_dup 0) (match_dup 1))]
14132 PUT_MODE (operands[1], QImode);
14136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14137 (eq:QI (match_operator 1 "ix86_comparison_operator"
14138 [(reg FLAGS_REG) (const_int 0)])
14141 [(set (match_dup 0) (match_dup 1))]
14143 rtx new_op1 = copy_rtx (operands[1]);
14144 operands[1] = new_op1;
14145 PUT_MODE (new_op1, QImode);
14146 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14147 GET_MODE (XEXP (new_op1, 0))));
14149 /* Make sure that (a) the CCmode we have for the flags is strong
14150 enough for the reversed compare or (b) we have a valid FP compare. */
14151 if (! ix86_comparison_operator (new_op1, VOIDmode))
14156 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14157 (eq:QI (match_operator 1 "ix86_comparison_operator"
14158 [(reg FLAGS_REG) (const_int 0)])
14161 [(set (match_dup 0) (match_dup 1))]
14163 rtx new_op1 = copy_rtx (operands[1]);
14164 operands[1] = new_op1;
14165 PUT_MODE (new_op1, QImode);
14166 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14167 GET_MODE (XEXP (new_op1, 0))));
14169 /* Make sure that (a) the CCmode we have for the flags is strong
14170 enough for the reversed compare or (b) we have a valid FP compare. */
14171 if (! ix86_comparison_operator (new_op1, VOIDmode))
14175 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14176 ;; subsequent logical operations are used to imitate conditional moves.
14177 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14180 (define_insn "*avx_setcc<mode>"
14181 [(set (match_operand:MODEF 0 "register_operand" "=x")
14182 (match_operator:MODEF 1 "avx_comparison_float_operator"
14183 [(match_operand:MODEF 2 "register_operand" "x")
14184 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14186 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14187 [(set_attr "type" "ssecmp")
14188 (set_attr "prefix" "vex")
14189 (set_attr "mode" "<MODE>")])
14191 (define_insn "*sse_setcc<mode>"
14192 [(set (match_operand:MODEF 0 "register_operand" "=x")
14193 (match_operator:MODEF 1 "sse_comparison_operator"
14194 [(match_operand:MODEF 2 "register_operand" "0")
14195 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14196 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14197 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14198 [(set_attr "type" "ssecmp")
14199 (set_attr "mode" "<MODE>")])
14201 (define_insn "*sse5_setcc<mode>"
14202 [(set (match_operand:MODEF 0 "register_operand" "=x")
14203 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14204 [(match_operand:MODEF 2 "register_operand" "x")
14205 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14207 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14208 [(set_attr "type" "sse4arg")
14209 (set_attr "mode" "<MODE>")])
14212 ;; Basic conditional jump instructions.
14213 ;; We ignore the overflow flag for signed branch instructions.
14215 ;; For all bCOND expanders, also expand the compare or test insn that
14216 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14218 (define_expand "b<code>"
14220 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14222 (label_ref (match_operand 0 ""))
14225 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14227 (define_expand "b<code>"
14229 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14231 (label_ref (match_operand 0 ""))
14233 "TARGET_80387 || TARGET_SSE_MATH"
14234 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14236 (define_insn "*jcc_1"
14238 (if_then_else (match_operator 1 "ix86_comparison_operator"
14239 [(reg FLAGS_REG) (const_int 0)])
14240 (label_ref (match_operand 0 "" ""))
14244 [(set_attr "type" "ibr")
14245 (set_attr "modrm" "0")
14246 (set (attr "length")
14247 (if_then_else (and (ge (minus (match_dup 0) (pc))
14249 (lt (minus (match_dup 0) (pc))
14254 (define_insn "*jcc_2"
14256 (if_then_else (match_operator 1 "ix86_comparison_operator"
14257 [(reg FLAGS_REG) (const_int 0)])
14259 (label_ref (match_operand 0 "" ""))))]
14262 [(set_attr "type" "ibr")
14263 (set_attr "modrm" "0")
14264 (set (attr "length")
14265 (if_then_else (and (ge (minus (match_dup 0) (pc))
14267 (lt (minus (match_dup 0) (pc))
14272 ;; In general it is not safe to assume too much about CCmode registers,
14273 ;; so simplify-rtx stops when it sees a second one. Under certain
14274 ;; conditions this is safe on x86, so help combine not create
14282 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14283 [(reg FLAGS_REG) (const_int 0)])
14285 (label_ref (match_operand 1 "" ""))
14289 (if_then_else (match_dup 0)
14290 (label_ref (match_dup 1))
14293 PUT_MODE (operands[0], VOIDmode);
14298 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14299 [(reg FLAGS_REG) (const_int 0)])
14301 (label_ref (match_operand 1 "" ""))
14305 (if_then_else (match_dup 0)
14306 (label_ref (match_dup 1))
14309 rtx new_op0 = copy_rtx (operands[0]);
14310 operands[0] = new_op0;
14311 PUT_MODE (new_op0, VOIDmode);
14312 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14313 GET_MODE (XEXP (new_op0, 0))));
14315 /* Make sure that (a) the CCmode we have for the flags is strong
14316 enough for the reversed compare or (b) we have a valid FP compare. */
14317 if (! ix86_comparison_operator (new_op0, VOIDmode))
14321 ;; zero_extend in SImode is correct, since this is what combine pass
14322 ;; generates from shift insn with QImode operand. Actually, the mode of
14323 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14324 ;; appropriate modulo of the bit offset value.
14326 (define_insn_and_split "*jcc_btdi_rex64"
14328 (if_then_else (match_operator 0 "bt_comparison_operator"
14330 (match_operand:DI 1 "register_operand" "r")
14333 (match_operand:QI 2 "register_operand" "r")))
14335 (label_ref (match_operand 3 "" ""))
14337 (clobber (reg:CC FLAGS_REG))]
14338 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14341 [(set (reg:CCC FLAGS_REG)
14349 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14350 (label_ref (match_dup 3))
14353 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14355 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14358 ;; avoid useless masking of bit offset operand
14359 (define_insn_and_split "*jcc_btdi_mask_rex64"
14361 (if_then_else (match_operator 0 "bt_comparison_operator"
14363 (match_operand:DI 1 "register_operand" "r")
14366 (match_operand:SI 2 "register_operand" "r")
14367 (match_operand:SI 3 "const_int_operand" "n")))])
14368 (label_ref (match_operand 4 "" ""))
14370 (clobber (reg:CC FLAGS_REG))]
14371 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14372 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14375 [(set (reg:CCC FLAGS_REG)
14383 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384 (label_ref (match_dup 4))
14387 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14389 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14392 (define_insn_and_split "*jcc_btsi"
14394 (if_then_else (match_operator 0 "bt_comparison_operator"
14396 (match_operand:SI 1 "register_operand" "r")
14399 (match_operand:QI 2 "register_operand" "r")))
14401 (label_ref (match_operand 3 "" ""))
14403 (clobber (reg:CC FLAGS_REG))]
14404 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14407 [(set (reg:CCC FLAGS_REG)
14415 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14416 (label_ref (match_dup 3))
14419 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14421 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14424 ;; avoid useless masking of bit offset operand
14425 (define_insn_and_split "*jcc_btsi_mask"
14427 (if_then_else (match_operator 0 "bt_comparison_operator"
14429 (match_operand:SI 1 "register_operand" "r")
14432 (match_operand:SI 2 "register_operand" "r")
14433 (match_operand:SI 3 "const_int_operand" "n")))])
14434 (label_ref (match_operand 4 "" ""))
14436 (clobber (reg:CC FLAGS_REG))]
14437 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14438 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14441 [(set (reg:CCC FLAGS_REG)
14449 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450 (label_ref (match_dup 4))
14452 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14454 (define_insn_and_split "*jcc_btsi_1"
14456 (if_then_else (match_operator 0 "bt_comparison_operator"
14459 (match_operand:SI 1 "register_operand" "r")
14460 (match_operand:QI 2 "register_operand" "r"))
14463 (label_ref (match_operand 3 "" ""))
14465 (clobber (reg:CC FLAGS_REG))]
14466 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14469 [(set (reg:CCC FLAGS_REG)
14477 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14478 (label_ref (match_dup 3))
14481 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14483 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14486 ;; avoid useless masking of bit offset operand
14487 (define_insn_and_split "*jcc_btsi_mask_1"
14490 (match_operator 0 "bt_comparison_operator"
14493 (match_operand:SI 1 "register_operand" "r")
14496 (match_operand:SI 2 "register_operand" "r")
14497 (match_operand:SI 3 "const_int_operand" "n")) 0))
14500 (label_ref (match_operand 4 "" ""))
14502 (clobber (reg:CC FLAGS_REG))]
14503 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14504 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14507 [(set (reg:CCC FLAGS_REG)
14515 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14516 (label_ref (match_dup 4))
14518 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14520 ;; Define combination compare-and-branch fp compare instructions to use
14521 ;; during early optimization. Splitting the operation apart early makes
14522 ;; for bad code when we want to reverse the operation.
14524 (define_insn "*fp_jcc_1_mixed"
14526 (if_then_else (match_operator 0 "comparison_operator"
14527 [(match_operand 1 "register_operand" "f,x")
14528 (match_operand 2 "nonimmediate_operand" "f,xm")])
14529 (label_ref (match_operand 3 "" ""))
14531 (clobber (reg:CCFP FPSR_REG))
14532 (clobber (reg:CCFP FLAGS_REG))]
14533 "TARGET_MIX_SSE_I387
14534 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14535 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14536 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14539 (define_insn "*fp_jcc_1_sse"
14541 (if_then_else (match_operator 0 "comparison_operator"
14542 [(match_operand 1 "register_operand" "x")
14543 (match_operand 2 "nonimmediate_operand" "xm")])
14544 (label_ref (match_operand 3 "" ""))
14546 (clobber (reg:CCFP FPSR_REG))
14547 (clobber (reg:CCFP FLAGS_REG))]
14549 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14550 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14551 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14554 (define_insn "*fp_jcc_1_387"
14556 (if_then_else (match_operator 0 "comparison_operator"
14557 [(match_operand 1 "register_operand" "f")
14558 (match_operand 2 "register_operand" "f")])
14559 (label_ref (match_operand 3 "" ""))
14561 (clobber (reg:CCFP FPSR_REG))
14562 (clobber (reg:CCFP FLAGS_REG))]
14563 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14565 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14566 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14569 (define_insn "*fp_jcc_2_mixed"
14571 (if_then_else (match_operator 0 "comparison_operator"
14572 [(match_operand 1 "register_operand" "f,x")
14573 (match_operand 2 "nonimmediate_operand" "f,xm")])
14575 (label_ref (match_operand 3 "" ""))))
14576 (clobber (reg:CCFP FPSR_REG))
14577 (clobber (reg:CCFP FLAGS_REG))]
14578 "TARGET_MIX_SSE_I387
14579 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14580 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14581 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14584 (define_insn "*fp_jcc_2_sse"
14586 (if_then_else (match_operator 0 "comparison_operator"
14587 [(match_operand 1 "register_operand" "x")
14588 (match_operand 2 "nonimmediate_operand" "xm")])
14590 (label_ref (match_operand 3 "" ""))))
14591 (clobber (reg:CCFP FPSR_REG))
14592 (clobber (reg:CCFP FLAGS_REG))]
14594 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14595 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14596 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14599 (define_insn "*fp_jcc_2_387"
14601 (if_then_else (match_operator 0 "comparison_operator"
14602 [(match_operand 1 "register_operand" "f")
14603 (match_operand 2 "register_operand" "f")])
14605 (label_ref (match_operand 3 "" ""))))
14606 (clobber (reg:CCFP FPSR_REG))
14607 (clobber (reg:CCFP FLAGS_REG))]
14608 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14610 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14611 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14614 (define_insn "*fp_jcc_3_387"
14616 (if_then_else (match_operator 0 "comparison_operator"
14617 [(match_operand 1 "register_operand" "f")
14618 (match_operand 2 "nonimmediate_operand" "fm")])
14619 (label_ref (match_operand 3 "" ""))
14621 (clobber (reg:CCFP FPSR_REG))
14622 (clobber (reg:CCFP FLAGS_REG))
14623 (clobber (match_scratch:HI 4 "=a"))]
14625 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14626 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14628 && SELECT_CC_MODE (GET_CODE (operands[0]),
14629 operands[1], operands[2]) == CCFPmode
14630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14633 (define_insn "*fp_jcc_4_387"
14635 (if_then_else (match_operator 0 "comparison_operator"
14636 [(match_operand 1 "register_operand" "f")
14637 (match_operand 2 "nonimmediate_operand" "fm")])
14639 (label_ref (match_operand 3 "" ""))))
14640 (clobber (reg:CCFP FPSR_REG))
14641 (clobber (reg:CCFP FLAGS_REG))
14642 (clobber (match_scratch:HI 4 "=a"))]
14644 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14645 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14647 && SELECT_CC_MODE (GET_CODE (operands[0]),
14648 operands[1], operands[2]) == CCFPmode
14649 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14652 (define_insn "*fp_jcc_5_387"
14654 (if_then_else (match_operator 0 "comparison_operator"
14655 [(match_operand 1 "register_operand" "f")
14656 (match_operand 2 "register_operand" "f")])
14657 (label_ref (match_operand 3 "" ""))
14659 (clobber (reg:CCFP FPSR_REG))
14660 (clobber (reg:CCFP FLAGS_REG))
14661 (clobber (match_scratch:HI 4 "=a"))]
14662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14663 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14664 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14667 (define_insn "*fp_jcc_6_387"
14669 (if_then_else (match_operator 0 "comparison_operator"
14670 [(match_operand 1 "register_operand" "f")
14671 (match_operand 2 "register_operand" "f")])
14673 (label_ref (match_operand 3 "" ""))))
14674 (clobber (reg:CCFP FPSR_REG))
14675 (clobber (reg:CCFP FLAGS_REG))
14676 (clobber (match_scratch:HI 4 "=a"))]
14677 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14678 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14679 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14682 (define_insn "*fp_jcc_7_387"
14684 (if_then_else (match_operator 0 "comparison_operator"
14685 [(match_operand 1 "register_operand" "f")
14686 (match_operand 2 "const0_operand" "")])
14687 (label_ref (match_operand 3 "" ""))
14689 (clobber (reg:CCFP FPSR_REG))
14690 (clobber (reg:CCFP FLAGS_REG))
14691 (clobber (match_scratch:HI 4 "=a"))]
14692 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14694 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14695 && SELECT_CC_MODE (GET_CODE (operands[0]),
14696 operands[1], operands[2]) == CCFPmode
14697 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14700 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14701 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14702 ;; with a precedence over other operators and is always put in the first
14703 ;; place. Swap condition and operands to match ficom instruction.
14705 (define_insn "*fp_jcc_8<mode>_387"
14707 (if_then_else (match_operator 0 "comparison_operator"
14708 [(match_operator 1 "float_operator"
14709 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14710 (match_operand 3 "register_operand" "f,f")])
14711 (label_ref (match_operand 4 "" ""))
14713 (clobber (reg:CCFP FPSR_REG))
14714 (clobber (reg:CCFP FLAGS_REG))
14715 (clobber (match_scratch:HI 5 "=a,a"))]
14716 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14717 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14718 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14719 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14720 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14721 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14726 (if_then_else (match_operator 0 "comparison_operator"
14727 [(match_operand 1 "register_operand" "")
14728 (match_operand 2 "nonimmediate_operand" "")])
14729 (match_operand 3 "" "")
14730 (match_operand 4 "" "")))
14731 (clobber (reg:CCFP FPSR_REG))
14732 (clobber (reg:CCFP FLAGS_REG))]
14736 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14737 operands[3], operands[4], NULL_RTX, NULL_RTX);
14743 (if_then_else (match_operator 0 "comparison_operator"
14744 [(match_operand 1 "register_operand" "")
14745 (match_operand 2 "general_operand" "")])
14746 (match_operand 3 "" "")
14747 (match_operand 4 "" "")))
14748 (clobber (reg:CCFP FPSR_REG))
14749 (clobber (reg:CCFP FLAGS_REG))
14750 (clobber (match_scratch:HI 5 "=a"))]
14754 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14755 operands[3], operands[4], operands[5], NULL_RTX);
14761 (if_then_else (match_operator 0 "comparison_operator"
14762 [(match_operator 1 "float_operator"
14763 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14764 (match_operand 3 "register_operand" "")])
14765 (match_operand 4 "" "")
14766 (match_operand 5 "" "")))
14767 (clobber (reg:CCFP FPSR_REG))
14768 (clobber (reg:CCFP FLAGS_REG))
14769 (clobber (match_scratch:HI 6 "=a"))]
14773 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14774 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14775 operands[3], operands[7],
14776 operands[4], operands[5], operands[6], NULL_RTX);
14780 ;; %%% Kill this when reload knows how to do it.
14783 (if_then_else (match_operator 0 "comparison_operator"
14784 [(match_operator 1 "float_operator"
14785 [(match_operand:X87MODEI12 2 "register_operand" "")])
14786 (match_operand 3 "register_operand" "")])
14787 (match_operand 4 "" "")
14788 (match_operand 5 "" "")))
14789 (clobber (reg:CCFP FPSR_REG))
14790 (clobber (reg:CCFP FLAGS_REG))
14791 (clobber (match_scratch:HI 6 "=a"))]
14795 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14796 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14797 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14798 operands[3], operands[7],
14799 operands[4], operands[5], operands[6], operands[2]);
14803 ;; Unconditional and other jump instructions
14805 (define_insn "jump"
14807 (label_ref (match_operand 0 "" "")))]
14810 [(set_attr "type" "ibr")
14811 (set (attr "length")
14812 (if_then_else (and (ge (minus (match_dup 0) (pc))
14814 (lt (minus (match_dup 0) (pc))
14818 (set_attr "modrm" "0")])
14820 (define_expand "indirect_jump"
14821 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14825 (define_insn "*indirect_jump"
14826 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14829 [(set_attr "type" "ibr")
14830 (set_attr "length_immediate" "0")])
14832 (define_expand "tablejump"
14833 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14834 (use (label_ref (match_operand 1 "" "")))])]
14837 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14838 relative. Convert the relative address to an absolute address. */
14842 enum rtx_code code;
14844 /* We can't use @GOTOFF for text labels on VxWorks;
14845 see gotoff_operand. */
14846 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14850 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14852 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14856 op1 = pic_offset_table_rtx;
14861 op0 = pic_offset_table_rtx;
14865 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14870 (define_insn "*tablejump_1"
14871 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14872 (use (label_ref (match_operand 1 "" "")))]
14875 [(set_attr "type" "ibr")
14876 (set_attr "length_immediate" "0")])
14878 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14881 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14882 (set (match_operand:QI 1 "register_operand" "")
14883 (match_operator:QI 2 "ix86_comparison_operator"
14884 [(reg FLAGS_REG) (const_int 0)]))
14885 (set (match_operand 3 "q_regs_operand" "")
14886 (zero_extend (match_dup 1)))]
14887 "(peep2_reg_dead_p (3, operands[1])
14888 || operands_match_p (operands[1], operands[3]))
14889 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14890 [(set (match_dup 4) (match_dup 0))
14891 (set (strict_low_part (match_dup 5))
14894 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14895 operands[5] = gen_lowpart (QImode, operands[3]);
14896 ix86_expand_clear (operands[3]);
14899 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14902 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14903 (set (match_operand:QI 1 "register_operand" "")
14904 (match_operator:QI 2 "ix86_comparison_operator"
14905 [(reg FLAGS_REG) (const_int 0)]))
14906 (parallel [(set (match_operand 3 "q_regs_operand" "")
14907 (zero_extend (match_dup 1)))
14908 (clobber (reg:CC FLAGS_REG))])]
14909 "(peep2_reg_dead_p (3, operands[1])
14910 || operands_match_p (operands[1], operands[3]))
14911 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14912 [(set (match_dup 4) (match_dup 0))
14913 (set (strict_low_part (match_dup 5))
14916 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14917 operands[5] = gen_lowpart (QImode, operands[3]);
14918 ix86_expand_clear (operands[3]);
14921 ;; Call instructions.
14923 ;; The predicates normally associated with named expanders are not properly
14924 ;; checked for calls. This is a bug in the generic code, but it isn't that
14925 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14927 ;; Call subroutine returning no value.
14929 (define_expand "call_pop"
14930 [(parallel [(call (match_operand:QI 0 "" "")
14931 (match_operand:SI 1 "" ""))
14932 (set (reg:SI SP_REG)
14933 (plus:SI (reg:SI SP_REG)
14934 (match_operand:SI 3 "" "")))])]
14937 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14941 (define_insn "*call_pop_0"
14942 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14943 (match_operand:SI 1 "" ""))
14944 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14945 (match_operand:SI 2 "immediate_operand" "")))]
14948 if (SIBLING_CALL_P (insn))
14951 return "call\t%P0";
14953 [(set_attr "type" "call")])
14955 (define_insn "*call_pop_1"
14956 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14957 (match_operand:SI 1 "" ""))
14958 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14959 (match_operand:SI 2 "immediate_operand" "i")))]
14962 if (constant_call_address_operand (operands[0], Pmode))
14964 if (SIBLING_CALL_P (insn))
14967 return "call\t%P0";
14969 if (SIBLING_CALL_P (insn))
14972 return "call\t%A0";
14974 [(set_attr "type" "call")])
14976 (define_expand "call"
14977 [(call (match_operand:QI 0 "" "")
14978 (match_operand 1 "" ""))
14979 (use (match_operand 2 "" ""))]
14982 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14986 (define_expand "sibcall"
14987 [(call (match_operand:QI 0 "" "")
14988 (match_operand 1 "" ""))
14989 (use (match_operand 2 "" ""))]
14992 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14996 (define_insn "*call_0"
14997 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14998 (match_operand 1 "" ""))]
15001 if (SIBLING_CALL_P (insn))
15004 return "call\t%P0";
15006 [(set_attr "type" "call")])
15008 (define_insn "*call_1"
15009 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15010 (match_operand 1 "" ""))]
15011 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15013 if (constant_call_address_operand (operands[0], Pmode))
15014 return "call\t%P0";
15015 return "call\t%A0";
15017 [(set_attr "type" "call")])
15019 (define_insn "*sibcall_1"
15020 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15021 (match_operand 1 "" ""))]
15022 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15024 if (constant_call_address_operand (operands[0], Pmode))
15028 [(set_attr "type" "call")])
15030 (define_insn "*call_1_rex64"
15031 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15032 (match_operand 1 "" ""))]
15033 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15034 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15036 if (constant_call_address_operand (operands[0], Pmode))
15037 return "call\t%P0";
15038 return "call\t%A0";
15040 [(set_attr "type" "call")])
15042 (define_insn "*call_1_rex64_ms_sysv"
15043 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15044 (match_operand 1 "" ""))
15045 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15046 (clobber (reg:TI 27))
15047 (clobber (reg:TI 28))
15048 (clobber (reg:TI 45))
15049 (clobber (reg:TI 46))
15050 (clobber (reg:TI 47))
15051 (clobber (reg:TI 48))
15052 (clobber (reg:TI 49))
15053 (clobber (reg:TI 50))
15054 (clobber (reg:TI 51))
15055 (clobber (reg:TI 52))
15056 (clobber (reg:DI SI_REG))
15057 (clobber (reg:DI DI_REG))]
15058 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15060 if (constant_call_address_operand (operands[0], Pmode))
15061 return "call\t%P0";
15062 return "call\t%A0";
15064 [(set_attr "type" "call")])
15066 (define_insn "*call_1_rex64_large"
15067 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15068 (match_operand 1 "" ""))]
15069 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15071 [(set_attr "type" "call")])
15073 (define_insn "*sibcall_1_rex64"
15074 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15075 (match_operand 1 "" ""))]
15076 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15078 [(set_attr "type" "call")])
15080 (define_insn "*sibcall_1_rex64_v"
15081 [(call (mem:QI (reg:DI R11_REG))
15082 (match_operand 0 "" ""))]
15083 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15085 [(set_attr "type" "call")])
15088 ;; Call subroutine, returning value in operand 0
15090 (define_expand "call_value_pop"
15091 [(parallel [(set (match_operand 0 "" "")
15092 (call (match_operand:QI 1 "" "")
15093 (match_operand:SI 2 "" "")))
15094 (set (reg:SI SP_REG)
15095 (plus:SI (reg:SI SP_REG)
15096 (match_operand:SI 4 "" "")))])]
15099 ix86_expand_call (operands[0], operands[1], operands[2],
15100 operands[3], operands[4], 0);
15104 (define_expand "call_value"
15105 [(set (match_operand 0 "" "")
15106 (call (match_operand:QI 1 "" "")
15107 (match_operand:SI 2 "" "")))
15108 (use (match_operand:SI 3 "" ""))]
15109 ;; Operand 2 not used on the i386.
15112 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15116 (define_expand "sibcall_value"
15117 [(set (match_operand 0 "" "")
15118 (call (match_operand:QI 1 "" "")
15119 (match_operand:SI 2 "" "")))
15120 (use (match_operand:SI 3 "" ""))]
15121 ;; Operand 2 not used on the i386.
15124 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15128 ;; Call subroutine returning any type.
15130 (define_expand "untyped_call"
15131 [(parallel [(call (match_operand 0 "" "")
15133 (match_operand 1 "" "")
15134 (match_operand 2 "" "")])]
15139 /* In order to give reg-stack an easier job in validating two
15140 coprocessor registers as containing a possible return value,
15141 simply pretend the untyped call returns a complex long double
15144 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15145 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15146 operands[0], const0_rtx,
15147 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15148 : X64_SSE_REGPARM_MAX)
15152 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15154 rtx set = XVECEXP (operands[2], 0, i);
15155 emit_move_insn (SET_DEST (set), SET_SRC (set));
15158 /* The optimizer does not know that the call sets the function value
15159 registers we stored in the result block. We avoid problems by
15160 claiming that all hard registers are used and clobbered at this
15162 emit_insn (gen_blockage ());
15167 ;; Prologue and epilogue instructions
15169 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15170 ;; all of memory. This blocks insns from being moved across this point.
15172 (define_insn "blockage"
15173 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15176 [(set_attr "length" "0")])
15178 ;; As USE insns aren't meaningful after reload, this is used instead
15179 ;; to prevent deleting instructions setting registers for PIC code
15180 (define_insn "prologue_use"
15181 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15184 [(set_attr "length" "0")])
15186 ;; Insn emitted into the body of a function to return from a function.
15187 ;; This is only done if the function's epilogue is known to be simple.
15188 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15190 (define_expand "return"
15192 "ix86_can_use_return_insn_p ()"
15194 if (crtl->args.pops_args)
15196 rtx popc = GEN_INT (crtl->args.pops_args);
15197 emit_jump_insn (gen_return_pop_internal (popc));
15202 (define_insn "return_internal"
15206 [(set_attr "length" "1")
15207 (set_attr "length_immediate" "0")
15208 (set_attr "modrm" "0")])
15210 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15211 ;; instruction Athlon and K8 have.
15213 (define_insn "return_internal_long"
15215 (unspec [(const_int 0)] UNSPEC_REP)]
15218 [(set_attr "length" "1")
15219 (set_attr "length_immediate" "0")
15220 (set_attr "prefix_rep" "1")
15221 (set_attr "modrm" "0")])
15223 (define_insn "return_pop_internal"
15225 (use (match_operand:SI 0 "const_int_operand" ""))]
15228 [(set_attr "length" "3")
15229 (set_attr "length_immediate" "2")
15230 (set_attr "modrm" "0")])
15232 (define_insn "return_indirect_internal"
15234 (use (match_operand:SI 0 "register_operand" "r"))]
15237 [(set_attr "type" "ibr")
15238 (set_attr "length_immediate" "0")])
15244 [(set_attr "length" "1")
15245 (set_attr "length_immediate" "0")
15246 (set_attr "modrm" "0")])
15248 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15249 ;; branch prediction penalty for the third jump in a 16-byte
15252 (define_insn "align"
15253 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15256 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15257 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15259 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15260 The align insn is used to avoid 3 jump instructions in the row to improve
15261 branch prediction and the benefits hardly outweigh the cost of extra 8
15262 nops on the average inserted by full alignment pseudo operation. */
15266 [(set_attr "length" "16")])
15268 (define_expand "prologue"
15271 "ix86_expand_prologue (); DONE;")
15273 (define_insn "set_got"
15274 [(set (match_operand:SI 0 "register_operand" "=r")
15275 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15276 (clobber (reg:CC FLAGS_REG))]
15278 { return output_set_got (operands[0], NULL_RTX); }
15279 [(set_attr "type" "multi")
15280 (set_attr "length" "12")])
15282 (define_insn "set_got_labelled"
15283 [(set (match_operand:SI 0 "register_operand" "=r")
15284 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15286 (clobber (reg:CC FLAGS_REG))]
15288 { return output_set_got (operands[0], operands[1]); }
15289 [(set_attr "type" "multi")
15290 (set_attr "length" "12")])
15292 (define_insn "set_got_rex64"
15293 [(set (match_operand:DI 0 "register_operand" "=r")
15294 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15296 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15297 [(set_attr "type" "lea")
15298 (set_attr "length" "6")])
15300 (define_insn "set_rip_rex64"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15304 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15305 [(set_attr "type" "lea")
15306 (set_attr "length" "6")])
15308 (define_insn "set_got_offset_rex64"
15309 [(set (match_operand:DI 0 "register_operand" "=r")
15311 [(label_ref (match_operand 1 "" ""))]
15312 UNSPEC_SET_GOT_OFFSET))]
15314 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15315 [(set_attr "type" "imov")
15316 (set_attr "length" "11")])
15318 (define_expand "epilogue"
15321 "ix86_expand_epilogue (1); DONE;")
15323 (define_expand "sibcall_epilogue"
15326 "ix86_expand_epilogue (0); DONE;")
15328 (define_expand "eh_return"
15329 [(use (match_operand 0 "register_operand" ""))]
15332 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15334 /* Tricky bit: we write the address of the handler to which we will
15335 be returning into someone else's stack frame, one word below the
15336 stack address we wish to restore. */
15337 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15338 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15339 tmp = gen_rtx_MEM (Pmode, tmp);
15340 emit_move_insn (tmp, ra);
15342 if (Pmode == SImode)
15343 emit_jump_insn (gen_eh_return_si (sa));
15345 emit_jump_insn (gen_eh_return_di (sa));
15350 (define_insn_and_split "eh_return_<mode>"
15352 (unspec [(match_operand:P 0 "register_operand" "c")]
15353 UNSPEC_EH_RETURN))]
15358 "ix86_expand_epilogue (2); DONE;")
15360 (define_insn "leave"
15361 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15362 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15363 (clobber (mem:BLK (scratch)))]
15366 [(set_attr "type" "leave")])
15368 (define_insn "leave_rex64"
15369 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15370 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15371 (clobber (mem:BLK (scratch)))]
15374 [(set_attr "type" "leave")])
15376 (define_expand "ffssi2"
15378 [(set (match_operand:SI 0 "register_operand" "")
15379 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15380 (clobber (match_scratch:SI 2 ""))
15381 (clobber (reg:CC FLAGS_REG))])]
15386 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15391 (define_expand "ffs_cmove"
15392 [(set (match_dup 2) (const_int -1))
15393 (parallel [(set (reg:CCZ FLAGS_REG)
15394 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15396 (set (match_operand:SI 0 "register_operand" "")
15397 (ctz:SI (match_dup 1)))])
15398 (set (match_dup 0) (if_then_else:SI
15399 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15402 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15403 (clobber (reg:CC FLAGS_REG))])]
15405 "operands[2] = gen_reg_rtx (SImode);")
15407 (define_insn_and_split "*ffs_no_cmove"
15408 [(set (match_operand:SI 0 "register_operand" "=r")
15409 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15410 (clobber (match_scratch:SI 2 "=&q"))
15411 (clobber (reg:CC FLAGS_REG))]
15414 "&& reload_completed"
15415 [(parallel [(set (reg:CCZ FLAGS_REG)
15416 (compare:CCZ (match_dup 1) (const_int 0)))
15417 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15418 (set (strict_low_part (match_dup 3))
15419 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15420 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15421 (clobber (reg:CC FLAGS_REG))])
15422 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15423 (clobber (reg:CC FLAGS_REG))])
15424 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15425 (clobber (reg:CC FLAGS_REG))])]
15427 operands[3] = gen_lowpart (QImode, operands[2]);
15428 ix86_expand_clear (operands[2]);
15431 (define_insn "*ffssi_1"
15432 [(set (reg:CCZ FLAGS_REG)
15433 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15435 (set (match_operand:SI 0 "register_operand" "=r")
15436 (ctz:SI (match_dup 1)))]
15438 "bsf{l}\t{%1, %0|%0, %1}"
15439 [(set_attr "prefix_0f" "1")])
15441 (define_expand "ffsdi2"
15442 [(set (match_dup 2) (const_int -1))
15443 (parallel [(set (reg:CCZ FLAGS_REG)
15444 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15446 (set (match_operand:DI 0 "register_operand" "")
15447 (ctz:DI (match_dup 1)))])
15448 (set (match_dup 0) (if_then_else:DI
15449 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15452 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15453 (clobber (reg:CC FLAGS_REG))])]
15455 "operands[2] = gen_reg_rtx (DImode);")
15457 (define_insn "*ffsdi_1"
15458 [(set (reg:CCZ FLAGS_REG)
15459 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15461 (set (match_operand:DI 0 "register_operand" "=r")
15462 (ctz:DI (match_dup 1)))]
15464 "bsf{q}\t{%1, %0|%0, %1}"
15465 [(set_attr "prefix_0f" "1")])
15467 (define_insn "ctzsi2"
15468 [(set (match_operand:SI 0 "register_operand" "=r")
15469 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15470 (clobber (reg:CC FLAGS_REG))]
15472 "bsf{l}\t{%1, %0|%0, %1}"
15473 [(set_attr "prefix_0f" "1")])
15475 (define_insn "ctzdi2"
15476 [(set (match_operand:DI 0 "register_operand" "=r")
15477 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15478 (clobber (reg:CC FLAGS_REG))]
15480 "bsf{q}\t{%1, %0|%0, %1}"
15481 [(set_attr "prefix_0f" "1")])
15483 (define_expand "clzsi2"
15485 [(set (match_operand:SI 0 "register_operand" "")
15486 (minus:SI (const_int 31)
15487 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15488 (clobber (reg:CC FLAGS_REG))])
15490 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15491 (clobber (reg:CC FLAGS_REG))])]
15496 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15501 (define_insn "clzsi2_abm"
15502 [(set (match_operand:SI 0 "register_operand" "=r")
15503 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15504 (clobber (reg:CC FLAGS_REG))]
15506 "lzcnt{l}\t{%1, %0|%0, %1}"
15507 [(set_attr "prefix_rep" "1")
15508 (set_attr "type" "bitmanip")
15509 (set_attr "mode" "SI")])
15511 (define_insn "*bsr"
15512 [(set (match_operand:SI 0 "register_operand" "=r")
15513 (minus:SI (const_int 31)
15514 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15515 (clobber (reg:CC FLAGS_REG))]
15517 "bsr{l}\t{%1, %0|%0, %1}"
15518 [(set_attr "prefix_0f" "1")
15519 (set_attr "mode" "SI")])
15521 (define_insn "popcount<mode>2"
15522 [(set (match_operand:SWI248 0 "register_operand" "=r")
15524 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15525 (clobber (reg:CC FLAGS_REG))]
15529 return "popcnt\t{%1, %0|%0, %1}";
15531 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15534 [(set_attr "prefix_rep" "1")
15535 (set_attr "type" "bitmanip")
15536 (set_attr "mode" "<MODE>")])
15538 (define_insn "*popcount<mode>2_cmp"
15539 [(set (reg FLAGS_REG)
15542 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15544 (set (match_operand:SWI248 0 "register_operand" "=r")
15545 (popcount:SWI248 (match_dup 1)))]
15546 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15549 return "popcnt\t{%1, %0|%0, %1}";
15551 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15554 [(set_attr "prefix_rep" "1")
15555 (set_attr "type" "bitmanip")
15556 (set_attr "mode" "<MODE>")])
15558 (define_insn "*popcountsi2_cmp_zext"
15559 [(set (reg FLAGS_REG)
15561 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15563 (set (match_operand:DI 0 "register_operand" "=r")
15564 (zero_extend:DI(popcount:SI (match_dup 1))))]
15565 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15568 return "popcnt\t{%1, %0|%0, %1}";
15570 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15573 [(set_attr "prefix_rep" "1")
15574 (set_attr "type" "bitmanip")
15575 (set_attr "mode" "SI")])
15577 (define_expand "bswapsi2"
15578 [(set (match_operand:SI 0 "register_operand" "")
15579 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15584 rtx x = operands[0];
15586 emit_move_insn (x, operands[1]);
15587 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15588 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15589 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15594 (define_insn "*bswapsi_1"
15595 [(set (match_operand:SI 0 "register_operand" "=r")
15596 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15599 [(set_attr "prefix_0f" "1")
15600 (set_attr "length" "2")])
15602 (define_insn "*bswaphi_lowpart_1"
15603 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15604 (bswap:HI (match_dup 0)))
15605 (clobber (reg:CC FLAGS_REG))]
15606 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15608 xchg{b}\t{%h0, %b0|%b0, %h0}
15609 rol{w}\t{$8, %0|%0, 8}"
15610 [(set_attr "length" "2,4")
15611 (set_attr "mode" "QI,HI")])
15613 (define_insn "bswaphi_lowpart"
15614 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15615 (bswap:HI (match_dup 0)))
15616 (clobber (reg:CC FLAGS_REG))]
15618 "rol{w}\t{$8, %0|%0, 8}"
15619 [(set_attr "length" "4")
15620 (set_attr "mode" "HI")])
15622 (define_insn "bswapdi2"
15623 [(set (match_operand:DI 0 "register_operand" "=r")
15624 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15627 [(set_attr "prefix_0f" "1")
15628 (set_attr "length" "3")])
15630 (define_expand "clzdi2"
15632 [(set (match_operand:DI 0 "register_operand" "")
15633 (minus:DI (const_int 63)
15634 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15635 (clobber (reg:CC FLAGS_REG))])
15637 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15638 (clobber (reg:CC FLAGS_REG))])]
15643 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15648 (define_insn "clzdi2_abm"
15649 [(set (match_operand:DI 0 "register_operand" "=r")
15650 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "TARGET_64BIT && TARGET_ABM"
15653 "lzcnt{q}\t{%1, %0|%0, %1}"
15654 [(set_attr "prefix_rep" "1")
15655 (set_attr "type" "bitmanip")
15656 (set_attr "mode" "DI")])
15658 (define_insn "*bsr_rex64"
15659 [(set (match_operand:DI 0 "register_operand" "=r")
15660 (minus:DI (const_int 63)
15661 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15662 (clobber (reg:CC FLAGS_REG))]
15664 "bsr{q}\t{%1, %0|%0, %1}"
15665 [(set_attr "prefix_0f" "1")
15666 (set_attr "mode" "DI")])
15668 (define_expand "clzhi2"
15670 [(set (match_operand:HI 0 "register_operand" "")
15671 (minus:HI (const_int 15)
15672 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15673 (clobber (reg:CC FLAGS_REG))])
15675 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15676 (clobber (reg:CC FLAGS_REG))])]
15681 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15686 (define_insn "clzhi2_abm"
15687 [(set (match_operand:HI 0 "register_operand" "=r")
15688 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15689 (clobber (reg:CC FLAGS_REG))]
15691 "lzcnt{w}\t{%1, %0|%0, %1}"
15692 [(set_attr "prefix_rep" "1")
15693 (set_attr "type" "bitmanip")
15694 (set_attr "mode" "HI")])
15696 (define_insn "*bsrhi"
15697 [(set (match_operand:HI 0 "register_operand" "=r")
15698 (minus:HI (const_int 15)
15699 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15700 (clobber (reg:CC FLAGS_REG))]
15702 "bsr{w}\t{%1, %0|%0, %1}"
15703 [(set_attr "prefix_0f" "1")
15704 (set_attr "mode" "HI")])
15706 (define_expand "paritydi2"
15707 [(set (match_operand:DI 0 "register_operand" "")
15708 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15711 rtx scratch = gen_reg_rtx (QImode);
15714 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15715 NULL_RTX, operands[1]));
15717 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15718 gen_rtx_REG (CCmode, FLAGS_REG),
15720 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15723 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15726 rtx tmp = gen_reg_rtx (SImode);
15728 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15729 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15734 (define_insn_and_split "paritydi2_cmp"
15735 [(set (reg:CC FLAGS_REG)
15736 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15737 (clobber (match_scratch:DI 0 "=r"))
15738 (clobber (match_scratch:SI 1 "=&r"))
15739 (clobber (match_scratch:HI 2 "=Q"))]
15742 "&& reload_completed"
15744 [(set (match_dup 1)
15745 (xor:SI (match_dup 1) (match_dup 4)))
15746 (clobber (reg:CC FLAGS_REG))])
15748 [(set (reg:CC FLAGS_REG)
15749 (parity:CC (match_dup 1)))
15750 (clobber (match_dup 1))
15751 (clobber (match_dup 2))])]
15753 operands[4] = gen_lowpart (SImode, operands[3]);
15757 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15758 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15761 operands[1] = gen_highpart (SImode, operands[3]);
15764 (define_expand "paritysi2"
15765 [(set (match_operand:SI 0 "register_operand" "")
15766 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15769 rtx scratch = gen_reg_rtx (QImode);
15772 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15774 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15775 gen_rtx_REG (CCmode, FLAGS_REG),
15777 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15779 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15783 (define_insn_and_split "paritysi2_cmp"
15784 [(set (reg:CC FLAGS_REG)
15785 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15786 (clobber (match_scratch:SI 0 "=r"))
15787 (clobber (match_scratch:HI 1 "=&Q"))]
15790 "&& reload_completed"
15792 [(set (match_dup 1)
15793 (xor:HI (match_dup 1) (match_dup 3)))
15794 (clobber (reg:CC FLAGS_REG))])
15796 [(set (reg:CC FLAGS_REG)
15797 (parity:CC (match_dup 1)))
15798 (clobber (match_dup 1))])]
15800 operands[3] = gen_lowpart (HImode, operands[2]);
15802 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15803 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15806 (define_insn "*parityhi2_cmp"
15807 [(set (reg:CC FLAGS_REG)
15808 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15809 (clobber (match_scratch:HI 0 "=Q"))]
15811 "xor{b}\t{%h0, %b0|%b0, %h0}"
15812 [(set_attr "length" "2")
15813 (set_attr "mode" "HI")])
15815 (define_insn "*parityqi2_cmp"
15816 [(set (reg:CC FLAGS_REG)
15817 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15820 [(set_attr "length" "2")
15821 (set_attr "mode" "QI")])
15823 ;; Thread-local storage patterns for ELF.
15825 ;; Note that these code sequences must appear exactly as shown
15826 ;; in order to allow linker relaxation.
15828 (define_insn "*tls_global_dynamic_32_gnu"
15829 [(set (match_operand:SI 0 "register_operand" "=a")
15830 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15831 (match_operand:SI 2 "tls_symbolic_operand" "")
15832 (match_operand:SI 3 "call_insn_operand" "")]
15834 (clobber (match_scratch:SI 4 "=d"))
15835 (clobber (match_scratch:SI 5 "=c"))
15836 (clobber (reg:CC FLAGS_REG))]
15837 "!TARGET_64BIT && TARGET_GNU_TLS"
15838 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15839 [(set_attr "type" "multi")
15840 (set_attr "length" "12")])
15842 (define_insn "*tls_global_dynamic_32_sun"
15843 [(set (match_operand:SI 0 "register_operand" "=a")
15844 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15845 (match_operand:SI 2 "tls_symbolic_operand" "")
15846 (match_operand:SI 3 "call_insn_operand" "")]
15848 (clobber (match_scratch:SI 4 "=d"))
15849 (clobber (match_scratch:SI 5 "=c"))
15850 (clobber (reg:CC FLAGS_REG))]
15851 "!TARGET_64BIT && TARGET_SUN_TLS"
15852 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15853 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15854 [(set_attr "type" "multi")
15855 (set_attr "length" "14")])
15857 (define_expand "tls_global_dynamic_32"
15858 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15861 (match_operand:SI 1 "tls_symbolic_operand" "")
15864 (clobber (match_scratch:SI 4 ""))
15865 (clobber (match_scratch:SI 5 ""))
15866 (clobber (reg:CC FLAGS_REG))])]
15870 operands[2] = pic_offset_table_rtx;
15873 operands[2] = gen_reg_rtx (Pmode);
15874 emit_insn (gen_set_got (operands[2]));
15876 if (TARGET_GNU2_TLS)
15878 emit_insn (gen_tls_dynamic_gnu2_32
15879 (operands[0], operands[1], operands[2]));
15882 operands[3] = ix86_tls_get_addr ();
15885 (define_insn "*tls_global_dynamic_64"
15886 [(set (match_operand:DI 0 "register_operand" "=a")
15887 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15888 (match_operand:DI 3 "" "")))
15889 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15892 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15893 [(set_attr "type" "multi")
15894 (set_attr "length" "16")])
15896 (define_expand "tls_global_dynamic_64"
15897 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15898 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15899 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15903 if (TARGET_GNU2_TLS)
15905 emit_insn (gen_tls_dynamic_gnu2_64
15906 (operands[0], operands[1]));
15909 operands[2] = ix86_tls_get_addr ();
15912 (define_insn "*tls_local_dynamic_base_32_gnu"
15913 [(set (match_operand:SI 0 "register_operand" "=a")
15914 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15915 (match_operand:SI 2 "call_insn_operand" "")]
15916 UNSPEC_TLS_LD_BASE))
15917 (clobber (match_scratch:SI 3 "=d"))
15918 (clobber (match_scratch:SI 4 "=c"))
15919 (clobber (reg:CC FLAGS_REG))]
15920 "!TARGET_64BIT && TARGET_GNU_TLS"
15921 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15922 [(set_attr "type" "multi")
15923 (set_attr "length" "11")])
15925 (define_insn "*tls_local_dynamic_base_32_sun"
15926 [(set (match_operand:SI 0 "register_operand" "=a")
15927 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15928 (match_operand:SI 2 "call_insn_operand" "")]
15929 UNSPEC_TLS_LD_BASE))
15930 (clobber (match_scratch:SI 3 "=d"))
15931 (clobber (match_scratch:SI 4 "=c"))
15932 (clobber (reg:CC FLAGS_REG))]
15933 "!TARGET_64BIT && TARGET_SUN_TLS"
15934 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15935 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15936 [(set_attr "type" "multi")
15937 (set_attr "length" "13")])
15939 (define_expand "tls_local_dynamic_base_32"
15940 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15941 (unspec:SI [(match_dup 1) (match_dup 2)]
15942 UNSPEC_TLS_LD_BASE))
15943 (clobber (match_scratch:SI 3 ""))
15944 (clobber (match_scratch:SI 4 ""))
15945 (clobber (reg:CC FLAGS_REG))])]
15949 operands[1] = pic_offset_table_rtx;
15952 operands[1] = gen_reg_rtx (Pmode);
15953 emit_insn (gen_set_got (operands[1]));
15955 if (TARGET_GNU2_TLS)
15957 emit_insn (gen_tls_dynamic_gnu2_32
15958 (operands[0], ix86_tls_module_base (), operands[1]));
15961 operands[2] = ix86_tls_get_addr ();
15964 (define_insn "*tls_local_dynamic_base_64"
15965 [(set (match_operand:DI 0 "register_operand" "=a")
15966 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15967 (match_operand:DI 2 "" "")))
15968 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15970 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15971 [(set_attr "type" "multi")
15972 (set_attr "length" "12")])
15974 (define_expand "tls_local_dynamic_base_64"
15975 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15976 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15977 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15980 if (TARGET_GNU2_TLS)
15982 emit_insn (gen_tls_dynamic_gnu2_64
15983 (operands[0], ix86_tls_module_base ()));
15986 operands[1] = ix86_tls_get_addr ();
15989 ;; Local dynamic of a single variable is a lose. Show combine how
15990 ;; to convert that back to global dynamic.
15992 (define_insn_and_split "*tls_local_dynamic_32_once"
15993 [(set (match_operand:SI 0 "register_operand" "=a")
15994 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15995 (match_operand:SI 2 "call_insn_operand" "")]
15996 UNSPEC_TLS_LD_BASE)
15997 (const:SI (unspec:SI
15998 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16000 (clobber (match_scratch:SI 4 "=d"))
16001 (clobber (match_scratch:SI 5 "=c"))
16002 (clobber (reg:CC FLAGS_REG))]
16006 [(parallel [(set (match_dup 0)
16007 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16009 (clobber (match_dup 4))
16010 (clobber (match_dup 5))
16011 (clobber (reg:CC FLAGS_REG))])]
16014 ;; Load and add the thread base pointer from %gs:0.
16016 (define_insn "*load_tp_si"
16017 [(set (match_operand:SI 0 "register_operand" "=r")
16018 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16020 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16021 [(set_attr "type" "imov")
16022 (set_attr "modrm" "0")
16023 (set_attr "length" "7")
16024 (set_attr "memory" "load")
16025 (set_attr "imm_disp" "false")])
16027 (define_insn "*add_tp_si"
16028 [(set (match_operand:SI 0 "register_operand" "=r")
16029 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16030 (match_operand:SI 1 "register_operand" "0")))
16031 (clobber (reg:CC FLAGS_REG))]
16033 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16034 [(set_attr "type" "alu")
16035 (set_attr "modrm" "0")
16036 (set_attr "length" "7")
16037 (set_attr "memory" "load")
16038 (set_attr "imm_disp" "false")])
16040 (define_insn "*load_tp_di"
16041 [(set (match_operand:DI 0 "register_operand" "=r")
16042 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16044 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16045 [(set_attr "type" "imov")
16046 (set_attr "modrm" "0")
16047 (set_attr "length" "7")
16048 (set_attr "memory" "load")
16049 (set_attr "imm_disp" "false")])
16051 (define_insn "*add_tp_di"
16052 [(set (match_operand:DI 0 "register_operand" "=r")
16053 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16054 (match_operand:DI 1 "register_operand" "0")))
16055 (clobber (reg:CC FLAGS_REG))]
16057 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16058 [(set_attr "type" "alu")
16059 (set_attr "modrm" "0")
16060 (set_attr "length" "7")
16061 (set_attr "memory" "load")
16062 (set_attr "imm_disp" "false")])
16064 ;; GNU2 TLS patterns can be split.
16066 (define_expand "tls_dynamic_gnu2_32"
16067 [(set (match_dup 3)
16068 (plus:SI (match_operand:SI 2 "register_operand" "")
16070 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16073 [(set (match_operand:SI 0 "register_operand" "")
16074 (unspec:SI [(match_dup 1) (match_dup 3)
16075 (match_dup 2) (reg:SI SP_REG)]
16077 (clobber (reg:CC FLAGS_REG))])]
16078 "!TARGET_64BIT && TARGET_GNU2_TLS"
16080 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16081 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16084 (define_insn "*tls_dynamic_lea_32"
16085 [(set (match_operand:SI 0 "register_operand" "=r")
16086 (plus:SI (match_operand:SI 1 "register_operand" "b")
16088 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16089 UNSPEC_TLSDESC))))]
16090 "!TARGET_64BIT && TARGET_GNU2_TLS"
16091 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16092 [(set_attr "type" "lea")
16093 (set_attr "mode" "SI")
16094 (set_attr "length" "6")
16095 (set_attr "length_address" "4")])
16097 (define_insn "*tls_dynamic_call_32"
16098 [(set (match_operand:SI 0 "register_operand" "=a")
16099 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16100 (match_operand:SI 2 "register_operand" "0")
16101 ;; we have to make sure %ebx still points to the GOT
16102 (match_operand:SI 3 "register_operand" "b")
16105 (clobber (reg:CC FLAGS_REG))]
16106 "!TARGET_64BIT && TARGET_GNU2_TLS"
16107 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16108 [(set_attr "type" "call")
16109 (set_attr "length" "2")
16110 (set_attr "length_address" "0")])
16112 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16113 [(set (match_operand:SI 0 "register_operand" "=&a")
16115 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16116 (match_operand:SI 4 "" "")
16117 (match_operand:SI 2 "register_operand" "b")
16120 (const:SI (unspec:SI
16121 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16123 (clobber (reg:CC FLAGS_REG))]
16124 "!TARGET_64BIT && TARGET_GNU2_TLS"
16127 [(set (match_dup 0) (match_dup 5))]
16129 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16130 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16133 (define_expand "tls_dynamic_gnu2_64"
16134 [(set (match_dup 2)
16135 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16138 [(set (match_operand:DI 0 "register_operand" "")
16139 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16141 (clobber (reg:CC FLAGS_REG))])]
16142 "TARGET_64BIT && TARGET_GNU2_TLS"
16144 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16145 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16148 (define_insn "*tls_dynamic_lea_64"
16149 [(set (match_operand:DI 0 "register_operand" "=r")
16150 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16152 "TARGET_64BIT && TARGET_GNU2_TLS"
16153 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16154 [(set_attr "type" "lea")
16155 (set_attr "mode" "DI")
16156 (set_attr "length" "7")
16157 (set_attr "length_address" "4")])
16159 (define_insn "*tls_dynamic_call_64"
16160 [(set (match_operand:DI 0 "register_operand" "=a")
16161 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16162 (match_operand:DI 2 "register_operand" "0")
16165 (clobber (reg:CC FLAGS_REG))]
16166 "TARGET_64BIT && TARGET_GNU2_TLS"
16167 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16168 [(set_attr "type" "call")
16169 (set_attr "length" "2")
16170 (set_attr "length_address" "0")])
16172 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16173 [(set (match_operand:DI 0 "register_operand" "=&a")
16175 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16176 (match_operand:DI 3 "" "")
16179 (const:DI (unspec:DI
16180 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16182 (clobber (reg:CC FLAGS_REG))]
16183 "TARGET_64BIT && TARGET_GNU2_TLS"
16186 [(set (match_dup 0) (match_dup 4))]
16188 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16189 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16194 ;; These patterns match the binary 387 instructions for addM3, subM3,
16195 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16196 ;; SFmode. The first is the normal insn, the second the same insn but
16197 ;; with one operand a conversion, and the third the same insn but with
16198 ;; the other operand a conversion. The conversion may be SFmode or
16199 ;; SImode if the target mode DFmode, but only SImode if the target mode
16202 ;; Gcc is slightly more smart about handling normal two address instructions
16203 ;; so use special patterns for add and mull.
16205 (define_insn "*fop_<mode>_comm_mixed_avx"
16206 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16207 (match_operator:MODEF 3 "binary_fp_operator"
16208 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16209 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16210 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16211 && COMMUTATIVE_ARITH_P (operands[3])
16212 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16213 "* return output_387_binary_op (insn, operands);"
16214 [(set (attr "type")
16215 (if_then_else (eq_attr "alternative" "1")
16216 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16217 (const_string "ssemul")
16218 (const_string "sseadd"))
16219 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16220 (const_string "fmul")
16221 (const_string "fop"))))
16222 (set_attr "prefix" "orig,maybe_vex")
16223 (set_attr "mode" "<MODE>")])
16225 (define_insn "*fop_<mode>_comm_mixed"
16226 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16227 (match_operator:MODEF 3 "binary_fp_operator"
16228 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16229 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16230 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16231 && COMMUTATIVE_ARITH_P (operands[3])
16232 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16233 "* return output_387_binary_op (insn, operands);"
16234 [(set (attr "type")
16235 (if_then_else (eq_attr "alternative" "1")
16236 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16237 (const_string "ssemul")
16238 (const_string "sseadd"))
16239 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16240 (const_string "fmul")
16241 (const_string "fop"))))
16242 (set_attr "mode" "<MODE>")])
16244 (define_insn "*fop_<mode>_comm_avx"
16245 [(set (match_operand:MODEF 0 "register_operand" "=x")
16246 (match_operator:MODEF 3 "binary_fp_operator"
16247 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16248 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16249 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16250 && COMMUTATIVE_ARITH_P (operands[3])
16251 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16252 "* return output_387_binary_op (insn, operands);"
16253 [(set (attr "type")
16254 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16255 (const_string "ssemul")
16256 (const_string "sseadd")))
16257 (set_attr "prefix" "vex")
16258 (set_attr "mode" "<MODE>")])
16260 (define_insn "*fop_<mode>_comm_sse"
16261 [(set (match_operand:MODEF 0 "register_operand" "=x")
16262 (match_operator:MODEF 3 "binary_fp_operator"
16263 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16264 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16266 && COMMUTATIVE_ARITH_P (operands[3])
16267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16268 "* return output_387_binary_op (insn, operands);"
16269 [(set (attr "type")
16270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271 (const_string "ssemul")
16272 (const_string "sseadd")))
16273 (set_attr "mode" "<MODE>")])
16275 (define_insn "*fop_<mode>_comm_i387"
16276 [(set (match_operand:MODEF 0 "register_operand" "=f")
16277 (match_operator:MODEF 3 "binary_fp_operator"
16278 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16279 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16281 && COMMUTATIVE_ARITH_P (operands[3])
16282 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16283 "* return output_387_binary_op (insn, operands);"
16284 [(set (attr "type")
16285 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16286 (const_string "fmul")
16287 (const_string "fop")))
16288 (set_attr "mode" "<MODE>")])
16290 (define_insn "*fop_<mode>_1_mixed_avx"
16291 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16292 (match_operator:MODEF 3 "binary_fp_operator"
16293 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16294 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16295 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16296 && !COMMUTATIVE_ARITH_P (operands[3])
16297 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16298 "* return output_387_binary_op (insn, operands);"
16299 [(set (attr "type")
16300 (cond [(and (eq_attr "alternative" "2")
16301 (match_operand:MODEF 3 "mult_operator" ""))
16302 (const_string "ssemul")
16303 (and (eq_attr "alternative" "2")
16304 (match_operand:MODEF 3 "div_operator" ""))
16305 (const_string "ssediv")
16306 (eq_attr "alternative" "2")
16307 (const_string "sseadd")
16308 (match_operand:MODEF 3 "mult_operator" "")
16309 (const_string "fmul")
16310 (match_operand:MODEF 3 "div_operator" "")
16311 (const_string "fdiv")
16313 (const_string "fop")))
16314 (set_attr "prefix" "orig,orig,maybe_vex")
16315 (set_attr "mode" "<MODE>")])
16317 (define_insn "*fop_<mode>_1_mixed"
16318 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16319 (match_operator:MODEF 3 "binary_fp_operator"
16320 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16321 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16322 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16323 && !COMMUTATIVE_ARITH_P (operands[3])
16324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16325 "* return output_387_binary_op (insn, operands);"
16326 [(set (attr "type")
16327 (cond [(and (eq_attr "alternative" "2")
16328 (match_operand:MODEF 3 "mult_operator" ""))
16329 (const_string "ssemul")
16330 (and (eq_attr "alternative" "2")
16331 (match_operand:MODEF 3 "div_operator" ""))
16332 (const_string "ssediv")
16333 (eq_attr "alternative" "2")
16334 (const_string "sseadd")
16335 (match_operand:MODEF 3 "mult_operator" "")
16336 (const_string "fmul")
16337 (match_operand:MODEF 3 "div_operator" "")
16338 (const_string "fdiv")
16340 (const_string "fop")))
16341 (set_attr "mode" "<MODE>")])
16343 (define_insn "*rcpsf2_sse"
16344 [(set (match_operand:SF 0 "register_operand" "=x")
16345 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16348 "%vrcpss\t{%1, %d0|%d0, %1}"
16349 [(set_attr "type" "sse")
16350 (set_attr "prefix" "maybe_vex")
16351 (set_attr "mode" "SF")])
16353 (define_insn "*fop_<mode>_1_avx"
16354 [(set (match_operand:MODEF 0 "register_operand" "=x")
16355 (match_operator:MODEF 3 "binary_fp_operator"
16356 [(match_operand:MODEF 1 "register_operand" "x")
16357 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16358 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16359 && !COMMUTATIVE_ARITH_P (operands[3])"
16360 "* return output_387_binary_op (insn, operands);"
16361 [(set (attr "type")
16362 (cond [(match_operand:MODEF 3 "mult_operator" "")
16363 (const_string "ssemul")
16364 (match_operand:MODEF 3 "div_operator" "")
16365 (const_string "ssediv")
16367 (const_string "sseadd")))
16368 (set_attr "prefix" "vex")
16369 (set_attr "mode" "<MODE>")])
16371 (define_insn "*fop_<mode>_1_sse"
16372 [(set (match_operand:MODEF 0 "register_operand" "=x")
16373 (match_operator:MODEF 3 "binary_fp_operator"
16374 [(match_operand:MODEF 1 "register_operand" "0")
16375 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16376 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16377 && !COMMUTATIVE_ARITH_P (operands[3])"
16378 "* return output_387_binary_op (insn, operands);"
16379 [(set (attr "type")
16380 (cond [(match_operand:MODEF 3 "mult_operator" "")
16381 (const_string "ssemul")
16382 (match_operand:MODEF 3 "div_operator" "")
16383 (const_string "ssediv")
16385 (const_string "sseadd")))
16386 (set_attr "mode" "<MODE>")])
16388 ;; This pattern is not fully shadowed by the pattern above.
16389 (define_insn "*fop_<mode>_1_i387"
16390 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16391 (match_operator:MODEF 3 "binary_fp_operator"
16392 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16393 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16394 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16395 && !COMMUTATIVE_ARITH_P (operands[3])
16396 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16397 "* return output_387_binary_op (insn, operands);"
16398 [(set (attr "type")
16399 (cond [(match_operand:MODEF 3 "mult_operator" "")
16400 (const_string "fmul")
16401 (match_operand:MODEF 3 "div_operator" "")
16402 (const_string "fdiv")
16404 (const_string "fop")))
16405 (set_attr "mode" "<MODE>")])
16407 ;; ??? Add SSE splitters for these!
16408 (define_insn "*fop_<MODEF:mode>_2_i387"
16409 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16410 (match_operator:MODEF 3 "binary_fp_operator"
16412 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16413 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16414 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16415 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16416 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16417 [(set (attr "type")
16418 (cond [(match_operand:MODEF 3 "mult_operator" "")
16419 (const_string "fmul")
16420 (match_operand:MODEF 3 "div_operator" "")
16421 (const_string "fdiv")
16423 (const_string "fop")))
16424 (set_attr "fp_int_src" "true")
16425 (set_attr "mode" "<X87MODEI12:MODE>")])
16427 (define_insn "*fop_<MODEF:mode>_3_i387"
16428 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429 (match_operator:MODEF 3 "binary_fp_operator"
16430 [(match_operand:MODEF 1 "register_operand" "0,0")
16432 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16433 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16434 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436 [(set (attr "type")
16437 (cond [(match_operand:MODEF 3 "mult_operator" "")
16438 (const_string "fmul")
16439 (match_operand:MODEF 3 "div_operator" "")
16440 (const_string "fdiv")
16442 (const_string "fop")))
16443 (set_attr "fp_int_src" "true")
16444 (set_attr "mode" "<MODE>")])
16446 (define_insn "*fop_df_4_i387"
16447 [(set (match_operand:DF 0 "register_operand" "=f,f")
16448 (match_operator:DF 3 "binary_fp_operator"
16450 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16451 (match_operand:DF 2 "register_operand" "0,f")]))]
16452 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16453 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16454 "* return output_387_binary_op (insn, operands);"
16455 [(set (attr "type")
16456 (cond [(match_operand:DF 3 "mult_operator" "")
16457 (const_string "fmul")
16458 (match_operand:DF 3 "div_operator" "")
16459 (const_string "fdiv")
16461 (const_string "fop")))
16462 (set_attr "mode" "SF")])
16464 (define_insn "*fop_df_5_i387"
16465 [(set (match_operand:DF 0 "register_operand" "=f,f")
16466 (match_operator:DF 3 "binary_fp_operator"
16467 [(match_operand:DF 1 "register_operand" "0,f")
16469 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16470 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16471 "* return output_387_binary_op (insn, operands);"
16472 [(set (attr "type")
16473 (cond [(match_operand:DF 3 "mult_operator" "")
16474 (const_string "fmul")
16475 (match_operand:DF 3 "div_operator" "")
16476 (const_string "fdiv")
16478 (const_string "fop")))
16479 (set_attr "mode" "SF")])
16481 (define_insn "*fop_df_6_i387"
16482 [(set (match_operand:DF 0 "register_operand" "=f,f")
16483 (match_operator:DF 3 "binary_fp_operator"
16485 (match_operand:SF 1 "register_operand" "0,f"))
16487 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16488 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16489 "* return output_387_binary_op (insn, operands);"
16490 [(set (attr "type")
16491 (cond [(match_operand:DF 3 "mult_operator" "")
16492 (const_string "fmul")
16493 (match_operand:DF 3 "div_operator" "")
16494 (const_string "fdiv")
16496 (const_string "fop")))
16497 (set_attr "mode" "SF")])
16499 (define_insn "*fop_xf_comm_i387"
16500 [(set (match_operand:XF 0 "register_operand" "=f")
16501 (match_operator:XF 3 "binary_fp_operator"
16502 [(match_operand:XF 1 "register_operand" "%0")
16503 (match_operand:XF 2 "register_operand" "f")]))]
16505 && COMMUTATIVE_ARITH_P (operands[3])"
16506 "* return output_387_binary_op (insn, operands);"
16507 [(set (attr "type")
16508 (if_then_else (match_operand:XF 3 "mult_operator" "")
16509 (const_string "fmul")
16510 (const_string "fop")))
16511 (set_attr "mode" "XF")])
16513 (define_insn "*fop_xf_1_i387"
16514 [(set (match_operand:XF 0 "register_operand" "=f,f")
16515 (match_operator:XF 3 "binary_fp_operator"
16516 [(match_operand:XF 1 "register_operand" "0,f")
16517 (match_operand:XF 2 "register_operand" "f,0")]))]
16519 && !COMMUTATIVE_ARITH_P (operands[3])"
16520 "* return output_387_binary_op (insn, operands);"
16521 [(set (attr "type")
16522 (cond [(match_operand:XF 3 "mult_operator" "")
16523 (const_string "fmul")
16524 (match_operand:XF 3 "div_operator" "")
16525 (const_string "fdiv")
16527 (const_string "fop")))
16528 (set_attr "mode" "XF")])
16530 (define_insn "*fop_xf_2_i387"
16531 [(set (match_operand:XF 0 "register_operand" "=f,f")
16532 (match_operator:XF 3 "binary_fp_operator"
16534 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16535 (match_operand:XF 2 "register_operand" "0,0")]))]
16536 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16537 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16538 [(set (attr "type")
16539 (cond [(match_operand:XF 3 "mult_operator" "")
16540 (const_string "fmul")
16541 (match_operand:XF 3 "div_operator" "")
16542 (const_string "fdiv")
16544 (const_string "fop")))
16545 (set_attr "fp_int_src" "true")
16546 (set_attr "mode" "<MODE>")])
16548 (define_insn "*fop_xf_3_i387"
16549 [(set (match_operand:XF 0 "register_operand" "=f,f")
16550 (match_operator:XF 3 "binary_fp_operator"
16551 [(match_operand:XF 1 "register_operand" "0,0")
16553 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16554 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16555 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16556 [(set (attr "type")
16557 (cond [(match_operand:XF 3 "mult_operator" "")
16558 (const_string "fmul")
16559 (match_operand:XF 3 "div_operator" "")
16560 (const_string "fdiv")
16562 (const_string "fop")))
16563 (set_attr "fp_int_src" "true")
16564 (set_attr "mode" "<MODE>")])
16566 (define_insn "*fop_xf_4_i387"
16567 [(set (match_operand:XF 0 "register_operand" "=f,f")
16568 (match_operator:XF 3 "binary_fp_operator"
16570 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16571 (match_operand:XF 2 "register_operand" "0,f")]))]
16573 "* return output_387_binary_op (insn, operands);"
16574 [(set (attr "type")
16575 (cond [(match_operand:XF 3 "mult_operator" "")
16576 (const_string "fmul")
16577 (match_operand:XF 3 "div_operator" "")
16578 (const_string "fdiv")
16580 (const_string "fop")))
16581 (set_attr "mode" "<MODE>")])
16583 (define_insn "*fop_xf_5_i387"
16584 [(set (match_operand:XF 0 "register_operand" "=f,f")
16585 (match_operator:XF 3 "binary_fp_operator"
16586 [(match_operand:XF 1 "register_operand" "0,f")
16588 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16590 "* return output_387_binary_op (insn, operands);"
16591 [(set (attr "type")
16592 (cond [(match_operand:XF 3 "mult_operator" "")
16593 (const_string "fmul")
16594 (match_operand:XF 3 "div_operator" "")
16595 (const_string "fdiv")
16597 (const_string "fop")))
16598 (set_attr "mode" "<MODE>")])
16600 (define_insn "*fop_xf_6_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f,f")
16602 (match_operator:XF 3 "binary_fp_operator"
16604 (match_operand:MODEF 1 "register_operand" "0,f"))
16606 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16608 "* return output_387_binary_op (insn, operands);"
16609 [(set (attr "type")
16610 (cond [(match_operand:XF 3 "mult_operator" "")
16611 (const_string "fmul")
16612 (match_operand:XF 3 "div_operator" "")
16613 (const_string "fdiv")
16615 (const_string "fop")))
16616 (set_attr "mode" "<MODE>")])
16619 [(set (match_operand 0 "register_operand" "")
16620 (match_operator 3 "binary_fp_operator"
16621 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16622 (match_operand 2 "register_operand" "")]))]
16624 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16627 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16628 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16629 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16630 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16631 GET_MODE (operands[3]),
16634 ix86_free_from_memory (GET_MODE (operands[1]));
16639 [(set (match_operand 0 "register_operand" "")
16640 (match_operator 3 "binary_fp_operator"
16641 [(match_operand 1 "register_operand" "")
16642 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16644 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16647 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16648 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16649 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16650 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16651 GET_MODE (operands[3]),
16654 ix86_free_from_memory (GET_MODE (operands[2]));
16658 ;; FPU special functions.
16660 ;; This pattern implements a no-op XFmode truncation for
16661 ;; all fancy i386 XFmode math functions.
16663 (define_insn "truncxf<mode>2_i387_noop_unspec"
16664 [(set (match_operand:MODEF 0 "register_operand" "=f")
16665 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16666 UNSPEC_TRUNC_NOOP))]
16667 "TARGET_USE_FANCY_MATH_387"
16668 "* return output_387_reg_move (insn, operands);"
16669 [(set_attr "type" "fmov")
16670 (set_attr "mode" "<MODE>")])
16672 (define_insn "sqrtxf2"
16673 [(set (match_operand:XF 0 "register_operand" "=f")
16674 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16675 "TARGET_USE_FANCY_MATH_387"
16677 [(set_attr "type" "fpspc")
16678 (set_attr "mode" "XF")
16679 (set_attr "athlon_decode" "direct")
16680 (set_attr "amdfam10_decode" "direct")])
16682 (define_insn "sqrt_extend<mode>xf2_i387"
16683 [(set (match_operand:XF 0 "register_operand" "=f")
16686 (match_operand:MODEF 1 "register_operand" "0"))))]
16687 "TARGET_USE_FANCY_MATH_387"
16689 [(set_attr "type" "fpspc")
16690 (set_attr "mode" "XF")
16691 (set_attr "athlon_decode" "direct")
16692 (set_attr "amdfam10_decode" "direct")])
16694 (define_insn "*rsqrtsf2_sse"
16695 [(set (match_operand:SF 0 "register_operand" "=x")
16696 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16699 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16700 [(set_attr "type" "sse")
16701 (set_attr "prefix" "maybe_vex")
16702 (set_attr "mode" "SF")])
16704 (define_expand "rsqrtsf2"
16705 [(set (match_operand:SF 0 "register_operand" "")
16706 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16710 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16714 (define_insn "*sqrt<mode>2_sse"
16715 [(set (match_operand:MODEF 0 "register_operand" "=x")
16717 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16718 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16719 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16720 [(set_attr "type" "sse")
16721 (set_attr "prefix" "maybe_vex")
16722 (set_attr "mode" "<MODE>")
16723 (set_attr "athlon_decode" "*")
16724 (set_attr "amdfam10_decode" "*")])
16726 (define_expand "sqrt<mode>2"
16727 [(set (match_operand:MODEF 0 "register_operand" "")
16729 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16730 "TARGET_USE_FANCY_MATH_387
16731 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16733 if (<MODE>mode == SFmode
16734 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16735 && flag_finite_math_only && !flag_trapping_math
16736 && flag_unsafe_math_optimizations)
16738 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16742 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16744 rtx op0 = gen_reg_rtx (XFmode);
16745 rtx op1 = force_reg (<MODE>mode, operands[1]);
16747 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16748 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16753 (define_insn "fpremxf4_i387"
16754 [(set (match_operand:XF 0 "register_operand" "=f")
16755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16756 (match_operand:XF 3 "register_operand" "1")]
16758 (set (match_operand:XF 1 "register_operand" "=u")
16759 (unspec:XF [(match_dup 2) (match_dup 3)]
16761 (set (reg:CCFP FPSR_REG)
16762 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16764 "TARGET_USE_FANCY_MATH_387"
16766 [(set_attr "type" "fpspc")
16767 (set_attr "mode" "XF")])
16769 (define_expand "fmodxf3"
16770 [(use (match_operand:XF 0 "register_operand" ""))
16771 (use (match_operand:XF 1 "general_operand" ""))
16772 (use (match_operand:XF 2 "general_operand" ""))]
16773 "TARGET_USE_FANCY_MATH_387"
16775 rtx label = gen_label_rtx ();
16777 rtx op1 = gen_reg_rtx (XFmode);
16778 rtx op2 = gen_reg_rtx (XFmode);
16780 emit_move_insn (op2, operands[2]);
16781 emit_move_insn (op1, operands[1]);
16783 emit_label (label);
16784 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16785 ix86_emit_fp_unordered_jump (label);
16786 LABEL_NUSES (label) = 1;
16788 emit_move_insn (operands[0], op1);
16792 (define_expand "fmod<mode>3"
16793 [(use (match_operand:MODEF 0 "register_operand" ""))
16794 (use (match_operand:MODEF 1 "general_operand" ""))
16795 (use (match_operand:MODEF 2 "general_operand" ""))]
16796 "TARGET_USE_FANCY_MATH_387"
16798 rtx label = gen_label_rtx ();
16800 rtx op1 = gen_reg_rtx (XFmode);
16801 rtx op2 = gen_reg_rtx (XFmode);
16803 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16804 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16806 emit_label (label);
16807 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16808 ix86_emit_fp_unordered_jump (label);
16809 LABEL_NUSES (label) = 1;
16811 /* Truncate the result properly for strict SSE math. */
16812 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16813 && !TARGET_MIX_SSE_I387)
16814 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16816 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16821 (define_insn "fprem1xf4_i387"
16822 [(set (match_operand:XF 0 "register_operand" "=f")
16823 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16824 (match_operand:XF 3 "register_operand" "1")]
16826 (set (match_operand:XF 1 "register_operand" "=u")
16827 (unspec:XF [(match_dup 2) (match_dup 3)]
16829 (set (reg:CCFP FPSR_REG)
16830 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16832 "TARGET_USE_FANCY_MATH_387"
16834 [(set_attr "type" "fpspc")
16835 (set_attr "mode" "XF")])
16837 (define_expand "remainderxf3"
16838 [(use (match_operand:XF 0 "register_operand" ""))
16839 (use (match_operand:XF 1 "general_operand" ""))
16840 (use (match_operand:XF 2 "general_operand" ""))]
16841 "TARGET_USE_FANCY_MATH_387"
16843 rtx label = gen_label_rtx ();
16845 rtx op1 = gen_reg_rtx (XFmode);
16846 rtx op2 = gen_reg_rtx (XFmode);
16848 emit_move_insn (op2, operands[2]);
16849 emit_move_insn (op1, operands[1]);
16851 emit_label (label);
16852 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16853 ix86_emit_fp_unordered_jump (label);
16854 LABEL_NUSES (label) = 1;
16856 emit_move_insn (operands[0], op1);
16860 (define_expand "remainder<mode>3"
16861 [(use (match_operand:MODEF 0 "register_operand" ""))
16862 (use (match_operand:MODEF 1 "general_operand" ""))
16863 (use (match_operand:MODEF 2 "general_operand" ""))]
16864 "TARGET_USE_FANCY_MATH_387"
16866 rtx label = gen_label_rtx ();
16868 rtx op1 = gen_reg_rtx (XFmode);
16869 rtx op2 = gen_reg_rtx (XFmode);
16871 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16872 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16874 emit_label (label);
16876 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16877 ix86_emit_fp_unordered_jump (label);
16878 LABEL_NUSES (label) = 1;
16880 /* Truncate the result properly for strict SSE math. */
16881 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16882 && !TARGET_MIX_SSE_I387)
16883 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16885 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16890 (define_insn "*sinxf2_i387"
16891 [(set (match_operand:XF 0 "register_operand" "=f")
16892 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16893 "TARGET_USE_FANCY_MATH_387
16894 && flag_unsafe_math_optimizations"
16896 [(set_attr "type" "fpspc")
16897 (set_attr "mode" "XF")])
16899 (define_insn "*sin_extend<mode>xf2_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(float_extend:XF
16902 (match_operand:MODEF 1 "register_operand" "0"))]
16904 "TARGET_USE_FANCY_MATH_387
16905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16906 || TARGET_MIX_SSE_I387)
16907 && flag_unsafe_math_optimizations"
16909 [(set_attr "type" "fpspc")
16910 (set_attr "mode" "XF")])
16912 (define_insn "*cosxf2_i387"
16913 [(set (match_operand:XF 0 "register_operand" "=f")
16914 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && flag_unsafe_math_optimizations"
16918 [(set_attr "type" "fpspc")
16919 (set_attr "mode" "XF")])
16921 (define_insn "*cos_extend<mode>xf2_i387"
16922 [(set (match_operand:XF 0 "register_operand" "=f")
16923 (unspec:XF [(float_extend:XF
16924 (match_operand:MODEF 1 "register_operand" "0"))]
16926 "TARGET_USE_FANCY_MATH_387
16927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16928 || TARGET_MIX_SSE_I387)
16929 && flag_unsafe_math_optimizations"
16931 [(set_attr "type" "fpspc")
16932 (set_attr "mode" "XF")])
16934 ;; When sincos pattern is defined, sin and cos builtin functions will be
16935 ;; expanded to sincos pattern with one of its outputs left unused.
16936 ;; CSE pass will figure out if two sincos patterns can be combined,
16937 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16938 ;; depending on the unused output.
16940 (define_insn "sincosxf3"
16941 [(set (match_operand:XF 0 "register_operand" "=f")
16942 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16943 UNSPEC_SINCOS_COS))
16944 (set (match_operand:XF 1 "register_operand" "=u")
16945 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && flag_unsafe_math_optimizations"
16949 [(set_attr "type" "fpspc")
16950 (set_attr "mode" "XF")])
16953 [(set (match_operand:XF 0 "register_operand" "")
16954 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16955 UNSPEC_SINCOS_COS))
16956 (set (match_operand:XF 1 "register_operand" "")
16957 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16958 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16959 && !(reload_completed || reload_in_progress)"
16960 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16964 [(set (match_operand:XF 0 "register_operand" "")
16965 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16966 UNSPEC_SINCOS_COS))
16967 (set (match_operand:XF 1 "register_operand" "")
16968 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16969 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16970 && !(reload_completed || reload_in_progress)"
16971 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16974 (define_insn "sincos_extend<mode>xf3_i387"
16975 [(set (match_operand:XF 0 "register_operand" "=f")
16976 (unspec:XF [(float_extend:XF
16977 (match_operand:MODEF 2 "register_operand" "0"))]
16978 UNSPEC_SINCOS_COS))
16979 (set (match_operand:XF 1 "register_operand" "=u")
16980 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16981 "TARGET_USE_FANCY_MATH_387
16982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16983 || TARGET_MIX_SSE_I387)
16984 && flag_unsafe_math_optimizations"
16986 [(set_attr "type" "fpspc")
16987 (set_attr "mode" "XF")])
16990 [(set (match_operand:XF 0 "register_operand" "")
16991 (unspec:XF [(float_extend:XF
16992 (match_operand:MODEF 2 "register_operand" ""))]
16993 UNSPEC_SINCOS_COS))
16994 (set (match_operand:XF 1 "register_operand" "")
16995 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16996 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16997 && !(reload_completed || reload_in_progress)"
16998 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17002 [(set (match_operand:XF 0 "register_operand" "")
17003 (unspec:XF [(float_extend:XF
17004 (match_operand:MODEF 2 "register_operand" ""))]
17005 UNSPEC_SINCOS_COS))
17006 (set (match_operand:XF 1 "register_operand" "")
17007 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17008 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17009 && !(reload_completed || reload_in_progress)"
17010 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17013 (define_expand "sincos<mode>3"
17014 [(use (match_operand:MODEF 0 "register_operand" ""))
17015 (use (match_operand:MODEF 1 "register_operand" ""))
17016 (use (match_operand:MODEF 2 "register_operand" ""))]
17017 "TARGET_USE_FANCY_MATH_387
17018 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17019 || TARGET_MIX_SSE_I387)
17020 && flag_unsafe_math_optimizations"
17022 rtx op0 = gen_reg_rtx (XFmode);
17023 rtx op1 = gen_reg_rtx (XFmode);
17025 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17031 (define_insn "fptanxf4_i387"
17032 [(set (match_operand:XF 0 "register_operand" "=f")
17033 (match_operand:XF 3 "const_double_operand" "F"))
17034 (set (match_operand:XF 1 "register_operand" "=u")
17035 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17037 "TARGET_USE_FANCY_MATH_387
17038 && flag_unsafe_math_optimizations
17039 && standard_80387_constant_p (operands[3]) == 2"
17041 [(set_attr "type" "fpspc")
17042 (set_attr "mode" "XF")])
17044 (define_insn "fptan_extend<mode>xf4_i387"
17045 [(set (match_operand:MODEF 0 "register_operand" "=f")
17046 (match_operand:MODEF 3 "const_double_operand" "F"))
17047 (set (match_operand:XF 1 "register_operand" "=u")
17048 (unspec:XF [(float_extend:XF
17049 (match_operand:MODEF 2 "register_operand" "0"))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053 || TARGET_MIX_SSE_I387)
17054 && flag_unsafe_math_optimizations
17055 && standard_80387_constant_p (operands[3]) == 2"
17057 [(set_attr "type" "fpspc")
17058 (set_attr "mode" "XF")])
17060 (define_expand "tanxf2"
17061 [(use (match_operand:XF 0 "register_operand" ""))
17062 (use (match_operand:XF 1 "register_operand" ""))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17066 rtx one = gen_reg_rtx (XFmode);
17067 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17069 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17073 (define_expand "tan<mode>2"
17074 [(use (match_operand:MODEF 0 "register_operand" ""))
17075 (use (match_operand:MODEF 1 "register_operand" ""))]
17076 "TARGET_USE_FANCY_MATH_387
17077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17078 || TARGET_MIX_SSE_I387)
17079 && flag_unsafe_math_optimizations"
17081 rtx op0 = gen_reg_rtx (XFmode);
17083 rtx one = gen_reg_rtx (<MODE>mode);
17084 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17086 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17087 operands[1], op2));
17088 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17092 (define_insn "*fpatanxf3_i387"
17093 [(set (match_operand:XF 0 "register_operand" "=f")
17094 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17095 (match_operand:XF 2 "register_operand" "u")]
17097 (clobber (match_scratch:XF 3 "=2"))]
17098 "TARGET_USE_FANCY_MATH_387
17099 && flag_unsafe_math_optimizations"
17101 [(set_attr "type" "fpspc")
17102 (set_attr "mode" "XF")])
17104 (define_insn "fpatan_extend<mode>xf3_i387"
17105 [(set (match_operand:XF 0 "register_operand" "=f")
17106 (unspec:XF [(float_extend:XF
17107 (match_operand:MODEF 1 "register_operand" "0"))
17109 (match_operand:MODEF 2 "register_operand" "u"))]
17111 (clobber (match_scratch:XF 3 "=2"))]
17112 "TARGET_USE_FANCY_MATH_387
17113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17114 || TARGET_MIX_SSE_I387)
17115 && flag_unsafe_math_optimizations"
17117 [(set_attr "type" "fpspc")
17118 (set_attr "mode" "XF")])
17120 (define_expand "atan2xf3"
17121 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17122 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17123 (match_operand:XF 1 "register_operand" "")]
17125 (clobber (match_scratch:XF 3 ""))])]
17126 "TARGET_USE_FANCY_MATH_387
17127 && flag_unsafe_math_optimizations"
17130 (define_expand "atan2<mode>3"
17131 [(use (match_operand:MODEF 0 "register_operand" ""))
17132 (use (match_operand:MODEF 1 "register_operand" ""))
17133 (use (match_operand:MODEF 2 "register_operand" ""))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17136 || TARGET_MIX_SSE_I387)
17137 && flag_unsafe_math_optimizations"
17139 rtx op0 = gen_reg_rtx (XFmode);
17141 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17146 (define_expand "atanxf2"
17147 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17148 (unspec:XF [(match_dup 2)
17149 (match_operand:XF 1 "register_operand" "")]
17151 (clobber (match_scratch:XF 3 ""))])]
17152 "TARGET_USE_FANCY_MATH_387
17153 && flag_unsafe_math_optimizations"
17155 operands[2] = gen_reg_rtx (XFmode);
17156 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17159 (define_expand "atan<mode>2"
17160 [(use (match_operand:MODEF 0 "register_operand" ""))
17161 (use (match_operand:MODEF 1 "register_operand" ""))]
17162 "TARGET_USE_FANCY_MATH_387
17163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17164 || TARGET_MIX_SSE_I387)
17165 && flag_unsafe_math_optimizations"
17167 rtx op0 = gen_reg_rtx (XFmode);
17169 rtx op2 = gen_reg_rtx (<MODE>mode);
17170 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17172 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17173 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17177 (define_expand "asinxf2"
17178 [(set (match_dup 2)
17179 (mult:XF (match_operand:XF 1 "register_operand" "")
17181 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17182 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17183 (parallel [(set (match_operand:XF 0 "register_operand" "")
17184 (unspec:XF [(match_dup 5) (match_dup 1)]
17186 (clobber (match_scratch:XF 6 ""))])]
17187 "TARGET_USE_FANCY_MATH_387
17188 && flag_unsafe_math_optimizations"
17192 if (optimize_insn_for_size_p ())
17195 for (i = 2; i < 6; i++)
17196 operands[i] = gen_reg_rtx (XFmode);
17198 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17201 (define_expand "asin<mode>2"
17202 [(use (match_operand:MODEF 0 "register_operand" ""))
17203 (use (match_operand:MODEF 1 "general_operand" ""))]
17204 "TARGET_USE_FANCY_MATH_387
17205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17206 || TARGET_MIX_SSE_I387)
17207 && flag_unsafe_math_optimizations"
17209 rtx op0 = gen_reg_rtx (XFmode);
17210 rtx op1 = gen_reg_rtx (XFmode);
17212 if (optimize_insn_for_size_p ())
17215 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17216 emit_insn (gen_asinxf2 (op0, op1));
17217 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17221 (define_expand "acosxf2"
17222 [(set (match_dup 2)
17223 (mult:XF (match_operand:XF 1 "register_operand" "")
17225 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17226 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17227 (parallel [(set (match_operand:XF 0 "register_operand" "")
17228 (unspec:XF [(match_dup 1) (match_dup 5)]
17230 (clobber (match_scratch:XF 6 ""))])]
17231 "TARGET_USE_FANCY_MATH_387
17232 && flag_unsafe_math_optimizations"
17236 if (optimize_insn_for_size_p ())
17239 for (i = 2; i < 6; i++)
17240 operands[i] = gen_reg_rtx (XFmode);
17242 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17245 (define_expand "acos<mode>2"
17246 [(use (match_operand:MODEF 0 "register_operand" ""))
17247 (use (match_operand:MODEF 1 "general_operand" ""))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17250 || TARGET_MIX_SSE_I387)
17251 && flag_unsafe_math_optimizations"
17253 rtx op0 = gen_reg_rtx (XFmode);
17254 rtx op1 = gen_reg_rtx (XFmode);
17256 if (optimize_insn_for_size_p ())
17259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260 emit_insn (gen_acosxf2 (op0, op1));
17261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17265 (define_insn "fyl2xxf3_i387"
17266 [(set (match_operand:XF 0 "register_operand" "=f")
17267 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17268 (match_operand:XF 2 "register_operand" "u")]
17270 (clobber (match_scratch:XF 3 "=2"))]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations"
17274 [(set_attr "type" "fpspc")
17275 (set_attr "mode" "XF")])
17277 (define_insn "fyl2x_extend<mode>xf3_i387"
17278 [(set (match_operand:XF 0 "register_operand" "=f")
17279 (unspec:XF [(float_extend:XF
17280 (match_operand:MODEF 1 "register_operand" "0"))
17281 (match_operand:XF 2 "register_operand" "u")]
17283 (clobber (match_scratch:XF 3 "=2"))]
17284 "TARGET_USE_FANCY_MATH_387
17285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17286 || TARGET_MIX_SSE_I387)
17287 && flag_unsafe_math_optimizations"
17289 [(set_attr "type" "fpspc")
17290 (set_attr "mode" "XF")])
17292 (define_expand "logxf2"
17293 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17294 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17295 (match_dup 2)] UNSPEC_FYL2X))
17296 (clobber (match_scratch:XF 3 ""))])]
17297 "TARGET_USE_FANCY_MATH_387
17298 && flag_unsafe_math_optimizations"
17300 operands[2] = gen_reg_rtx (XFmode);
17301 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17304 (define_expand "log<mode>2"
17305 [(use (match_operand:MODEF 0 "register_operand" ""))
17306 (use (match_operand:MODEF 1 "register_operand" ""))]
17307 "TARGET_USE_FANCY_MATH_387
17308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17309 || TARGET_MIX_SSE_I387)
17310 && flag_unsafe_math_optimizations"
17312 rtx op0 = gen_reg_rtx (XFmode);
17314 rtx op2 = gen_reg_rtx (XFmode);
17315 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17317 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17322 (define_expand "log10xf2"
17323 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17324 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17325 (match_dup 2)] UNSPEC_FYL2X))
17326 (clobber (match_scratch:XF 3 ""))])]
17327 "TARGET_USE_FANCY_MATH_387
17328 && flag_unsafe_math_optimizations"
17330 operands[2] = gen_reg_rtx (XFmode);
17331 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17334 (define_expand "log10<mode>2"
17335 [(use (match_operand:MODEF 0 "register_operand" ""))
17336 (use (match_operand:MODEF 1 "register_operand" ""))]
17337 "TARGET_USE_FANCY_MATH_387
17338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17339 || TARGET_MIX_SSE_I387)
17340 && flag_unsafe_math_optimizations"
17342 rtx op0 = gen_reg_rtx (XFmode);
17344 rtx op2 = gen_reg_rtx (XFmode);
17345 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17347 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17352 (define_expand "log2xf2"
17353 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17354 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17355 (match_dup 2)] UNSPEC_FYL2X))
17356 (clobber (match_scratch:XF 3 ""))])]
17357 "TARGET_USE_FANCY_MATH_387
17358 && flag_unsafe_math_optimizations"
17360 operands[2] = gen_reg_rtx (XFmode);
17361 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17364 (define_expand "log2<mode>2"
17365 [(use (match_operand:MODEF 0 "register_operand" ""))
17366 (use (match_operand:MODEF 1 "register_operand" ""))]
17367 "TARGET_USE_FANCY_MATH_387
17368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17369 || TARGET_MIX_SSE_I387)
17370 && flag_unsafe_math_optimizations"
17372 rtx op0 = gen_reg_rtx (XFmode);
17374 rtx op2 = gen_reg_rtx (XFmode);
17375 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17377 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17382 (define_insn "fyl2xp1xf3_i387"
17383 [(set (match_operand:XF 0 "register_operand" "=f")
17384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17385 (match_operand:XF 2 "register_operand" "u")]
17387 (clobber (match_scratch:XF 3 "=2"))]
17388 "TARGET_USE_FANCY_MATH_387
17389 && flag_unsafe_math_optimizations"
17391 [(set_attr "type" "fpspc")
17392 (set_attr "mode" "XF")])
17394 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17395 [(set (match_operand:XF 0 "register_operand" "=f")
17396 (unspec:XF [(float_extend:XF
17397 (match_operand:MODEF 1 "register_operand" "0"))
17398 (match_operand:XF 2 "register_operand" "u")]
17400 (clobber (match_scratch:XF 3 "=2"))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403 || TARGET_MIX_SSE_I387)
17404 && flag_unsafe_math_optimizations"
17406 [(set_attr "type" "fpspc")
17407 (set_attr "mode" "XF")])
17409 (define_expand "log1pxf2"
17410 [(use (match_operand:XF 0 "register_operand" ""))
17411 (use (match_operand:XF 1 "register_operand" ""))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && flag_unsafe_math_optimizations"
17415 if (optimize_insn_for_size_p ())
17418 ix86_emit_i387_log1p (operands[0], operands[1]);
17422 (define_expand "log1p<mode>2"
17423 [(use (match_operand:MODEF 0 "register_operand" ""))
17424 (use (match_operand:MODEF 1 "register_operand" ""))]
17425 "TARGET_USE_FANCY_MATH_387
17426 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17427 || TARGET_MIX_SSE_I387)
17428 && flag_unsafe_math_optimizations"
17432 if (optimize_insn_for_size_p ())
17435 op0 = gen_reg_rtx (XFmode);
17437 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17439 ix86_emit_i387_log1p (op0, operands[1]);
17440 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17444 (define_insn "fxtractxf3_i387"
17445 [(set (match_operand:XF 0 "register_operand" "=f")
17446 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17447 UNSPEC_XTRACT_FRACT))
17448 (set (match_operand:XF 1 "register_operand" "=u")
17449 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17450 "TARGET_USE_FANCY_MATH_387
17451 && flag_unsafe_math_optimizations"
17453 [(set_attr "type" "fpspc")
17454 (set_attr "mode" "XF")])
17456 (define_insn "fxtract_extend<mode>xf3_i387"
17457 [(set (match_operand:XF 0 "register_operand" "=f")
17458 (unspec:XF [(float_extend:XF
17459 (match_operand:MODEF 2 "register_operand" "0"))]
17460 UNSPEC_XTRACT_FRACT))
17461 (set (match_operand:XF 1 "register_operand" "=u")
17462 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17463 "TARGET_USE_FANCY_MATH_387
17464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17465 || TARGET_MIX_SSE_I387)
17466 && flag_unsafe_math_optimizations"
17468 [(set_attr "type" "fpspc")
17469 (set_attr "mode" "XF")])
17471 (define_expand "logbxf2"
17472 [(parallel [(set (match_dup 2)
17473 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17474 UNSPEC_XTRACT_FRACT))
17475 (set (match_operand:XF 0 "register_operand" "")
17476 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17477 "TARGET_USE_FANCY_MATH_387
17478 && flag_unsafe_math_optimizations"
17480 operands[2] = gen_reg_rtx (XFmode);
17483 (define_expand "logb<mode>2"
17484 [(use (match_operand:MODEF 0 "register_operand" ""))
17485 (use (match_operand:MODEF 1 "register_operand" ""))]
17486 "TARGET_USE_FANCY_MATH_387
17487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17488 || TARGET_MIX_SSE_I387)
17489 && flag_unsafe_math_optimizations"
17491 rtx op0 = gen_reg_rtx (XFmode);
17492 rtx op1 = gen_reg_rtx (XFmode);
17494 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17499 (define_expand "ilogbxf2"
17500 [(use (match_operand:SI 0 "register_operand" ""))
17501 (use (match_operand:XF 1 "register_operand" ""))]
17502 "TARGET_USE_FANCY_MATH_387
17503 && flag_unsafe_math_optimizations"
17507 if (optimize_insn_for_size_p ())
17510 op0 = gen_reg_rtx (XFmode);
17511 op1 = gen_reg_rtx (XFmode);
17513 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17514 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17518 (define_expand "ilogb<mode>2"
17519 [(use (match_operand:SI 0 "register_operand" ""))
17520 (use (match_operand:MODEF 1 "register_operand" ""))]
17521 "TARGET_USE_FANCY_MATH_387
17522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523 || TARGET_MIX_SSE_I387)
17524 && flag_unsafe_math_optimizations"
17528 if (optimize_insn_for_size_p ())
17531 op0 = gen_reg_rtx (XFmode);
17532 op1 = gen_reg_rtx (XFmode);
17534 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17535 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17539 (define_insn "*f2xm1xf2_i387"
17540 [(set (match_operand:XF 0 "register_operand" "=f")
17541 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17543 "TARGET_USE_FANCY_MATH_387
17544 && flag_unsafe_math_optimizations"
17546 [(set_attr "type" "fpspc")
17547 (set_attr "mode" "XF")])
17549 (define_insn "*fscalexf4_i387"
17550 [(set (match_operand:XF 0 "register_operand" "=f")
17551 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17552 (match_operand:XF 3 "register_operand" "1")]
17553 UNSPEC_FSCALE_FRACT))
17554 (set (match_operand:XF 1 "register_operand" "=u")
17555 (unspec:XF [(match_dup 2) (match_dup 3)]
17556 UNSPEC_FSCALE_EXP))]
17557 "TARGET_USE_FANCY_MATH_387
17558 && flag_unsafe_math_optimizations"
17560 [(set_attr "type" "fpspc")
17561 (set_attr "mode" "XF")])
17563 (define_expand "expNcorexf3"
17564 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17565 (match_operand:XF 2 "register_operand" "")))
17566 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17567 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17568 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17569 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17570 (parallel [(set (match_operand:XF 0 "register_operand" "")
17571 (unspec:XF [(match_dup 8) (match_dup 4)]
17572 UNSPEC_FSCALE_FRACT))
17574 (unspec:XF [(match_dup 8) (match_dup 4)]
17575 UNSPEC_FSCALE_EXP))])]
17576 "TARGET_USE_FANCY_MATH_387
17577 && flag_unsafe_math_optimizations"
17581 if (optimize_insn_for_size_p ())
17584 for (i = 3; i < 10; i++)
17585 operands[i] = gen_reg_rtx (XFmode);
17587 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17590 (define_expand "expxf2"
17591 [(use (match_operand:XF 0 "register_operand" ""))
17592 (use (match_operand:XF 1 "register_operand" ""))]
17593 "TARGET_USE_FANCY_MATH_387
17594 && flag_unsafe_math_optimizations"
17598 if (optimize_insn_for_size_p ())
17601 op2 = gen_reg_rtx (XFmode);
17602 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17604 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17608 (define_expand "exp<mode>2"
17609 [(use (match_operand:MODEF 0 "register_operand" ""))
17610 (use (match_operand:MODEF 1 "general_operand" ""))]
17611 "TARGET_USE_FANCY_MATH_387
17612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17613 || TARGET_MIX_SSE_I387)
17614 && flag_unsafe_math_optimizations"
17618 if (optimize_insn_for_size_p ())
17621 op0 = gen_reg_rtx (XFmode);
17622 op1 = gen_reg_rtx (XFmode);
17624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17625 emit_insn (gen_expxf2 (op0, op1));
17626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17630 (define_expand "exp10xf2"
17631 [(use (match_operand:XF 0 "register_operand" ""))
17632 (use (match_operand:XF 1 "register_operand" ""))]
17633 "TARGET_USE_FANCY_MATH_387
17634 && flag_unsafe_math_optimizations"
17638 if (optimize_insn_for_size_p ())
17641 op2 = gen_reg_rtx (XFmode);
17642 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17644 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17648 (define_expand "exp10<mode>2"
17649 [(use (match_operand:MODEF 0 "register_operand" ""))
17650 (use (match_operand:MODEF 1 "general_operand" ""))]
17651 "TARGET_USE_FANCY_MATH_387
17652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17653 || TARGET_MIX_SSE_I387)
17654 && flag_unsafe_math_optimizations"
17658 if (optimize_insn_for_size_p ())
17661 op0 = gen_reg_rtx (XFmode);
17662 op1 = gen_reg_rtx (XFmode);
17664 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17665 emit_insn (gen_exp10xf2 (op0, op1));
17666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17670 (define_expand "exp2xf2"
17671 [(use (match_operand:XF 0 "register_operand" ""))
17672 (use (match_operand:XF 1 "register_operand" ""))]
17673 "TARGET_USE_FANCY_MATH_387
17674 && flag_unsafe_math_optimizations"
17678 if (optimize_insn_for_size_p ())
17681 op2 = gen_reg_rtx (XFmode);
17682 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17684 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17688 (define_expand "exp2<mode>2"
17689 [(use (match_operand:MODEF 0 "register_operand" ""))
17690 (use (match_operand:MODEF 1 "general_operand" ""))]
17691 "TARGET_USE_FANCY_MATH_387
17692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17693 || TARGET_MIX_SSE_I387)
17694 && flag_unsafe_math_optimizations"
17698 if (optimize_insn_for_size_p ())
17701 op0 = gen_reg_rtx (XFmode);
17702 op1 = gen_reg_rtx (XFmode);
17704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17705 emit_insn (gen_exp2xf2 (op0, op1));
17706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17710 (define_expand "expm1xf2"
17711 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17713 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17714 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17715 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17716 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17717 (parallel [(set (match_dup 7)
17718 (unspec:XF [(match_dup 6) (match_dup 4)]
17719 UNSPEC_FSCALE_FRACT))
17721 (unspec:XF [(match_dup 6) (match_dup 4)]
17722 UNSPEC_FSCALE_EXP))])
17723 (parallel [(set (match_dup 10)
17724 (unspec:XF [(match_dup 9) (match_dup 8)]
17725 UNSPEC_FSCALE_FRACT))
17726 (set (match_dup 11)
17727 (unspec:XF [(match_dup 9) (match_dup 8)]
17728 UNSPEC_FSCALE_EXP))])
17729 (set (match_dup 12) (minus:XF (match_dup 10)
17730 (float_extend:XF (match_dup 13))))
17731 (set (match_operand:XF 0 "register_operand" "")
17732 (plus:XF (match_dup 12) (match_dup 7)))]
17733 "TARGET_USE_FANCY_MATH_387
17734 && flag_unsafe_math_optimizations"
17738 if (optimize_insn_for_size_p ())
17741 for (i = 2; i < 13; i++)
17742 operands[i] = gen_reg_rtx (XFmode);
17745 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17747 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17750 (define_expand "expm1<mode>2"
17751 [(use (match_operand:MODEF 0 "register_operand" ""))
17752 (use (match_operand:MODEF 1 "general_operand" ""))]
17753 "TARGET_USE_FANCY_MATH_387
17754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17755 || TARGET_MIX_SSE_I387)
17756 && flag_unsafe_math_optimizations"
17760 if (optimize_insn_for_size_p ())
17763 op0 = gen_reg_rtx (XFmode);
17764 op1 = gen_reg_rtx (XFmode);
17766 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17767 emit_insn (gen_expm1xf2 (op0, op1));
17768 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17772 (define_expand "ldexpxf3"
17773 [(set (match_dup 3)
17774 (float:XF (match_operand:SI 2 "register_operand" "")))
17775 (parallel [(set (match_operand:XF 0 " register_operand" "")
17776 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17778 UNSPEC_FSCALE_FRACT))
17780 (unspec:XF [(match_dup 1) (match_dup 3)]
17781 UNSPEC_FSCALE_EXP))])]
17782 "TARGET_USE_FANCY_MATH_387
17783 && flag_unsafe_math_optimizations"
17785 if (optimize_insn_for_size_p ())
17788 operands[3] = gen_reg_rtx (XFmode);
17789 operands[4] = gen_reg_rtx (XFmode);
17792 (define_expand "ldexp<mode>3"
17793 [(use (match_operand:MODEF 0 "register_operand" ""))
17794 (use (match_operand:MODEF 1 "general_operand" ""))
17795 (use (match_operand:SI 2 "register_operand" ""))]
17796 "TARGET_USE_FANCY_MATH_387
17797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17798 || TARGET_MIX_SSE_I387)
17799 && flag_unsafe_math_optimizations"
17803 if (optimize_insn_for_size_p ())
17806 op0 = gen_reg_rtx (XFmode);
17807 op1 = gen_reg_rtx (XFmode);
17809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17810 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17815 (define_expand "scalbxf3"
17816 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17817 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17818 (match_operand:XF 2 "register_operand" "")]
17819 UNSPEC_FSCALE_FRACT))
17821 (unspec:XF [(match_dup 1) (match_dup 2)]
17822 UNSPEC_FSCALE_EXP))])]
17823 "TARGET_USE_FANCY_MATH_387
17824 && flag_unsafe_math_optimizations"
17826 if (optimize_insn_for_size_p ())
17829 operands[3] = gen_reg_rtx (XFmode);
17832 (define_expand "scalb<mode>3"
17833 [(use (match_operand:MODEF 0 "register_operand" ""))
17834 (use (match_operand:MODEF 1 "general_operand" ""))
17835 (use (match_operand:MODEF 2 "register_operand" ""))]
17836 "TARGET_USE_FANCY_MATH_387
17837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17838 || TARGET_MIX_SSE_I387)
17839 && flag_unsafe_math_optimizations"
17843 if (optimize_insn_for_size_p ())
17846 op0 = gen_reg_rtx (XFmode);
17847 op1 = gen_reg_rtx (XFmode);
17848 op2 = gen_reg_rtx (XFmode);
17850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17851 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17852 emit_insn (gen_scalbxf3 (op0, op1, op2));
17853 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17858 (define_insn "sse4_1_round<mode>2"
17859 [(set (match_operand:MODEF 0 "register_operand" "=x")
17860 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17861 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17864 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17865 [(set_attr "type" "ssecvt")
17866 (set_attr "prefix_extra" "1")
17867 (set_attr "prefix" "maybe_vex")
17868 (set_attr "mode" "<MODE>")])
17870 (define_insn "rintxf2"
17871 [(set (match_operand:XF 0 "register_operand" "=f")
17872 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17874 "TARGET_USE_FANCY_MATH_387
17875 && flag_unsafe_math_optimizations"
17877 [(set_attr "type" "fpspc")
17878 (set_attr "mode" "XF")])
17880 (define_expand "rint<mode>2"
17881 [(use (match_operand:MODEF 0 "register_operand" ""))
17882 (use (match_operand:MODEF 1 "register_operand" ""))]
17883 "(TARGET_USE_FANCY_MATH_387
17884 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17885 || TARGET_MIX_SSE_I387)
17886 && flag_unsafe_math_optimizations)
17887 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17888 && !flag_trapping_math)"
17890 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17891 && !flag_trapping_math)
17893 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17896 emit_insn (gen_sse4_1_round<mode>2
17897 (operands[0], operands[1], GEN_INT (0x04)));
17899 ix86_expand_rint (operand0, operand1);
17903 rtx op0 = gen_reg_rtx (XFmode);
17904 rtx op1 = gen_reg_rtx (XFmode);
17906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17907 emit_insn (gen_rintxf2 (op0, op1));
17909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914 (define_expand "round<mode>2"
17915 [(match_operand:MODEF 0 "register_operand" "")
17916 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17917 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17918 && !flag_trapping_math && !flag_rounding_math"
17920 if (optimize_insn_for_size_p ())
17922 if (TARGET_64BIT || (<MODE>mode != DFmode))
17923 ix86_expand_round (operand0, operand1);
17925 ix86_expand_rounddf_32 (operand0, operand1);
17929 (define_insn_and_split "*fistdi2_1"
17930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17931 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17933 "TARGET_USE_FANCY_MATH_387
17934 && !(reload_completed || reload_in_progress)"
17939 if (memory_operand (operands[0], VOIDmode))
17940 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17943 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17944 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17949 [(set_attr "type" "fpspc")
17950 (set_attr "mode" "DI")])
17952 (define_insn "fistdi2"
17953 [(set (match_operand:DI 0 "memory_operand" "=m")
17954 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17956 (clobber (match_scratch:XF 2 "=&1f"))]
17957 "TARGET_USE_FANCY_MATH_387"
17958 "* return output_fix_trunc (insn, operands, 0);"
17959 [(set_attr "type" "fpspc")
17960 (set_attr "mode" "DI")])
17962 (define_insn "fistdi2_with_temp"
17963 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17964 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17966 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17967 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17968 "TARGET_USE_FANCY_MATH_387"
17970 [(set_attr "type" "fpspc")
17971 (set_attr "mode" "DI")])
17974 [(set (match_operand:DI 0 "register_operand" "")
17975 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17977 (clobber (match_operand:DI 2 "memory_operand" ""))
17978 (clobber (match_scratch 3 ""))]
17980 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17981 (clobber (match_dup 3))])
17982 (set (match_dup 0) (match_dup 2))]
17986 [(set (match_operand:DI 0 "memory_operand" "")
17987 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17989 (clobber (match_operand:DI 2 "memory_operand" ""))
17990 (clobber (match_scratch 3 ""))]
17992 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17993 (clobber (match_dup 3))])]
17996 (define_insn_and_split "*fist<mode>2_1"
17997 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17998 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18000 "TARGET_USE_FANCY_MATH_387
18001 && !(reload_completed || reload_in_progress)"
18006 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18007 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18011 [(set_attr "type" "fpspc")
18012 (set_attr "mode" "<MODE>")])
18014 (define_insn "fist<mode>2"
18015 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18016 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18018 "TARGET_USE_FANCY_MATH_387"
18019 "* return output_fix_trunc (insn, operands, 0);"
18020 [(set_attr "type" "fpspc")
18021 (set_attr "mode" "<MODE>")])
18023 (define_insn "fist<mode>2_with_temp"
18024 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18025 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18027 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18028 "TARGET_USE_FANCY_MATH_387"
18030 [(set_attr "type" "fpspc")
18031 (set_attr "mode" "<MODE>")])
18034 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18035 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18037 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18039 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18040 (set (match_dup 0) (match_dup 2))]
18044 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18045 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18047 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18049 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18052 (define_expand "lrintxf<mode>2"
18053 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18054 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18056 "TARGET_USE_FANCY_MATH_387"
18059 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18060 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18061 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18062 UNSPEC_FIX_NOTRUNC))]
18063 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18064 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18067 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18068 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18069 (match_operand:MODEF 1 "register_operand" "")]
18070 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18071 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18072 && !flag_trapping_math && !flag_rounding_math"
18074 if (optimize_insn_for_size_p ())
18076 ix86_expand_lround (operand0, operand1);
18080 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18081 (define_insn_and_split "frndintxf2_floor"
18082 [(set (match_operand:XF 0 "register_operand" "")
18083 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18084 UNSPEC_FRNDINT_FLOOR))
18085 (clobber (reg:CC FLAGS_REG))]
18086 "TARGET_USE_FANCY_MATH_387
18087 && flag_unsafe_math_optimizations
18088 && !(reload_completed || reload_in_progress)"
18093 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18095 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18096 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18098 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18099 operands[2], operands[3]));
18102 [(set_attr "type" "frndint")
18103 (set_attr "i387_cw" "floor")
18104 (set_attr "mode" "XF")])
18106 (define_insn "frndintxf2_floor_i387"
18107 [(set (match_operand:XF 0 "register_operand" "=f")
18108 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18109 UNSPEC_FRNDINT_FLOOR))
18110 (use (match_operand:HI 2 "memory_operand" "m"))
18111 (use (match_operand:HI 3 "memory_operand" "m"))]
18112 "TARGET_USE_FANCY_MATH_387
18113 && flag_unsafe_math_optimizations"
18114 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18115 [(set_attr "type" "frndint")
18116 (set_attr "i387_cw" "floor")
18117 (set_attr "mode" "XF")])
18119 (define_expand "floorxf2"
18120 [(use (match_operand:XF 0 "register_operand" ""))
18121 (use (match_operand:XF 1 "register_operand" ""))]
18122 "TARGET_USE_FANCY_MATH_387
18123 && flag_unsafe_math_optimizations"
18125 if (optimize_insn_for_size_p ())
18127 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18131 (define_expand "floor<mode>2"
18132 [(use (match_operand:MODEF 0 "register_operand" ""))
18133 (use (match_operand:MODEF 1 "register_operand" ""))]
18134 "(TARGET_USE_FANCY_MATH_387
18135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18136 || TARGET_MIX_SSE_I387)
18137 && flag_unsafe_math_optimizations)
18138 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18139 && !flag_trapping_math)"
18141 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18142 && !flag_trapping_math
18143 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18145 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18148 emit_insn (gen_sse4_1_round<mode>2
18149 (operands[0], operands[1], GEN_INT (0x01)));
18150 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18151 ix86_expand_floorceil (operand0, operand1, true);
18153 ix86_expand_floorceildf_32 (operand0, operand1, true);
18159 if (optimize_insn_for_size_p ())
18162 op0 = gen_reg_rtx (XFmode);
18163 op1 = gen_reg_rtx (XFmode);
18164 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18165 emit_insn (gen_frndintxf2_floor (op0, op1));
18167 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18172 (define_insn_and_split "*fist<mode>2_floor_1"
18173 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18174 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18175 UNSPEC_FIST_FLOOR))
18176 (clobber (reg:CC FLAGS_REG))]
18177 "TARGET_USE_FANCY_MATH_387
18178 && flag_unsafe_math_optimizations
18179 && !(reload_completed || reload_in_progress)"
18184 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18186 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18187 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18188 if (memory_operand (operands[0], VOIDmode))
18189 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18190 operands[2], operands[3]));
18193 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18194 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18195 operands[2], operands[3],
18200 [(set_attr "type" "fistp")
18201 (set_attr "i387_cw" "floor")
18202 (set_attr "mode" "<MODE>")])
18204 (define_insn "fistdi2_floor"
18205 [(set (match_operand:DI 0 "memory_operand" "=m")
18206 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18207 UNSPEC_FIST_FLOOR))
18208 (use (match_operand:HI 2 "memory_operand" "m"))
18209 (use (match_operand:HI 3 "memory_operand" "m"))
18210 (clobber (match_scratch:XF 4 "=&1f"))]
18211 "TARGET_USE_FANCY_MATH_387
18212 && flag_unsafe_math_optimizations"
18213 "* return output_fix_trunc (insn, operands, 0);"
18214 [(set_attr "type" "fistp")
18215 (set_attr "i387_cw" "floor")
18216 (set_attr "mode" "DI")])
18218 (define_insn "fistdi2_floor_with_temp"
18219 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18220 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18221 UNSPEC_FIST_FLOOR))
18222 (use (match_operand:HI 2 "memory_operand" "m,m"))
18223 (use (match_operand:HI 3 "memory_operand" "m,m"))
18224 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18225 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18226 "TARGET_USE_FANCY_MATH_387
18227 && flag_unsafe_math_optimizations"
18229 [(set_attr "type" "fistp")
18230 (set_attr "i387_cw" "floor")
18231 (set_attr "mode" "DI")])
18234 [(set (match_operand:DI 0 "register_operand" "")
18235 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18236 UNSPEC_FIST_FLOOR))
18237 (use (match_operand:HI 2 "memory_operand" ""))
18238 (use (match_operand:HI 3 "memory_operand" ""))
18239 (clobber (match_operand:DI 4 "memory_operand" ""))
18240 (clobber (match_scratch 5 ""))]
18242 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18243 (use (match_dup 2))
18244 (use (match_dup 3))
18245 (clobber (match_dup 5))])
18246 (set (match_dup 0) (match_dup 4))]
18250 [(set (match_operand:DI 0 "memory_operand" "")
18251 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18252 UNSPEC_FIST_FLOOR))
18253 (use (match_operand:HI 2 "memory_operand" ""))
18254 (use (match_operand:HI 3 "memory_operand" ""))
18255 (clobber (match_operand:DI 4 "memory_operand" ""))
18256 (clobber (match_scratch 5 ""))]
18258 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18259 (use (match_dup 2))
18260 (use (match_dup 3))
18261 (clobber (match_dup 5))])]
18264 (define_insn "fist<mode>2_floor"
18265 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18266 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18267 UNSPEC_FIST_FLOOR))
18268 (use (match_operand:HI 2 "memory_operand" "m"))
18269 (use (match_operand:HI 3 "memory_operand" "m"))]
18270 "TARGET_USE_FANCY_MATH_387
18271 && flag_unsafe_math_optimizations"
18272 "* return output_fix_trunc (insn, operands, 0);"
18273 [(set_attr "type" "fistp")
18274 (set_attr "i387_cw" "floor")
18275 (set_attr "mode" "<MODE>")])
18277 (define_insn "fist<mode>2_floor_with_temp"
18278 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18279 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18280 UNSPEC_FIST_FLOOR))
18281 (use (match_operand:HI 2 "memory_operand" "m,m"))
18282 (use (match_operand:HI 3 "memory_operand" "m,m"))
18283 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18284 "TARGET_USE_FANCY_MATH_387
18285 && flag_unsafe_math_optimizations"
18287 [(set_attr "type" "fistp")
18288 (set_attr "i387_cw" "floor")
18289 (set_attr "mode" "<MODE>")])
18292 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18293 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18294 UNSPEC_FIST_FLOOR))
18295 (use (match_operand:HI 2 "memory_operand" ""))
18296 (use (match_operand:HI 3 "memory_operand" ""))
18297 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18299 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18300 UNSPEC_FIST_FLOOR))
18301 (use (match_dup 2))
18302 (use (match_dup 3))])
18303 (set (match_dup 0) (match_dup 4))]
18307 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18308 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18309 UNSPEC_FIST_FLOOR))
18310 (use (match_operand:HI 2 "memory_operand" ""))
18311 (use (match_operand:HI 3 "memory_operand" ""))
18312 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18314 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18315 UNSPEC_FIST_FLOOR))
18316 (use (match_dup 2))
18317 (use (match_dup 3))])]
18320 (define_expand "lfloorxf<mode>2"
18321 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18322 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18323 UNSPEC_FIST_FLOOR))
18324 (clobber (reg:CC FLAGS_REG))])]
18325 "TARGET_USE_FANCY_MATH_387
18326 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18327 && flag_unsafe_math_optimizations"
18330 (define_expand "lfloor<mode>di2"
18331 [(match_operand:DI 0 "nonimmediate_operand" "")
18332 (match_operand:MODEF 1 "register_operand" "")]
18333 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18334 && !flag_trapping_math"
18336 if (optimize_insn_for_size_p ())
18338 ix86_expand_lfloorceil (operand0, operand1, true);
18342 (define_expand "lfloor<mode>si2"
18343 [(match_operand:SI 0 "nonimmediate_operand" "")
18344 (match_operand:MODEF 1 "register_operand" "")]
18345 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18346 && !flag_trapping_math"
18348 if (optimize_insn_for_size_p () && TARGET_64BIT)
18350 ix86_expand_lfloorceil (operand0, operand1, true);
18354 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18355 (define_insn_and_split "frndintxf2_ceil"
18356 [(set (match_operand:XF 0 "register_operand" "")
18357 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18358 UNSPEC_FRNDINT_CEIL))
18359 (clobber (reg:CC FLAGS_REG))]
18360 "TARGET_USE_FANCY_MATH_387
18361 && flag_unsafe_math_optimizations
18362 && !(reload_completed || reload_in_progress)"
18367 ix86_optimize_mode_switching[I387_CEIL] = 1;
18369 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18370 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18372 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18373 operands[2], operands[3]));
18376 [(set_attr "type" "frndint")
18377 (set_attr "i387_cw" "ceil")
18378 (set_attr "mode" "XF")])
18380 (define_insn "frndintxf2_ceil_i387"
18381 [(set (match_operand:XF 0 "register_operand" "=f")
18382 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18383 UNSPEC_FRNDINT_CEIL))
18384 (use (match_operand:HI 2 "memory_operand" "m"))
18385 (use (match_operand:HI 3 "memory_operand" "m"))]
18386 "TARGET_USE_FANCY_MATH_387
18387 && flag_unsafe_math_optimizations"
18388 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18389 [(set_attr "type" "frndint")
18390 (set_attr "i387_cw" "ceil")
18391 (set_attr "mode" "XF")])
18393 (define_expand "ceilxf2"
18394 [(use (match_operand:XF 0 "register_operand" ""))
18395 (use (match_operand:XF 1 "register_operand" ""))]
18396 "TARGET_USE_FANCY_MATH_387
18397 && flag_unsafe_math_optimizations"
18399 if (optimize_insn_for_size_p ())
18401 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18405 (define_expand "ceil<mode>2"
18406 [(use (match_operand:MODEF 0 "register_operand" ""))
18407 (use (match_operand:MODEF 1 "register_operand" ""))]
18408 "(TARGET_USE_FANCY_MATH_387
18409 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18410 || TARGET_MIX_SSE_I387)
18411 && flag_unsafe_math_optimizations)
18412 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18413 && !flag_trapping_math)"
18415 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18416 && !flag_trapping_math
18417 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18420 emit_insn (gen_sse4_1_round<mode>2
18421 (operands[0], operands[1], GEN_INT (0x02)));
18422 else if (optimize_insn_for_size_p ())
18424 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18425 ix86_expand_floorceil (operand0, operand1, false);
18427 ix86_expand_floorceildf_32 (operand0, operand1, false);
18433 if (optimize_insn_for_size_p ())
18436 op0 = gen_reg_rtx (XFmode);
18437 op1 = gen_reg_rtx (XFmode);
18438 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18439 emit_insn (gen_frndintxf2_ceil (op0, op1));
18441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18446 (define_insn_and_split "*fist<mode>2_ceil_1"
18447 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18448 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18450 (clobber (reg:CC FLAGS_REG))]
18451 "TARGET_USE_FANCY_MATH_387
18452 && flag_unsafe_math_optimizations
18453 && !(reload_completed || reload_in_progress)"
18458 ix86_optimize_mode_switching[I387_CEIL] = 1;
18460 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18461 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18462 if (memory_operand (operands[0], VOIDmode))
18463 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18464 operands[2], operands[3]));
18467 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18468 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18469 operands[2], operands[3],
18474 [(set_attr "type" "fistp")
18475 (set_attr "i387_cw" "ceil")
18476 (set_attr "mode" "<MODE>")])
18478 (define_insn "fistdi2_ceil"
18479 [(set (match_operand:DI 0 "memory_operand" "=m")
18480 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18482 (use (match_operand:HI 2 "memory_operand" "m"))
18483 (use (match_operand:HI 3 "memory_operand" "m"))
18484 (clobber (match_scratch:XF 4 "=&1f"))]
18485 "TARGET_USE_FANCY_MATH_387
18486 && flag_unsafe_math_optimizations"
18487 "* return output_fix_trunc (insn, operands, 0);"
18488 [(set_attr "type" "fistp")
18489 (set_attr "i387_cw" "ceil")
18490 (set_attr "mode" "DI")])
18492 (define_insn "fistdi2_ceil_with_temp"
18493 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18494 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18496 (use (match_operand:HI 2 "memory_operand" "m,m"))
18497 (use (match_operand:HI 3 "memory_operand" "m,m"))
18498 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18499 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18500 "TARGET_USE_FANCY_MATH_387
18501 && flag_unsafe_math_optimizations"
18503 [(set_attr "type" "fistp")
18504 (set_attr "i387_cw" "ceil")
18505 (set_attr "mode" "DI")])
18508 [(set (match_operand:DI 0 "register_operand" "")
18509 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18511 (use (match_operand:HI 2 "memory_operand" ""))
18512 (use (match_operand:HI 3 "memory_operand" ""))
18513 (clobber (match_operand:DI 4 "memory_operand" ""))
18514 (clobber (match_scratch 5 ""))]
18516 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18517 (use (match_dup 2))
18518 (use (match_dup 3))
18519 (clobber (match_dup 5))])
18520 (set (match_dup 0) (match_dup 4))]
18524 [(set (match_operand:DI 0 "memory_operand" "")
18525 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18527 (use (match_operand:HI 2 "memory_operand" ""))
18528 (use (match_operand:HI 3 "memory_operand" ""))
18529 (clobber (match_operand:DI 4 "memory_operand" ""))
18530 (clobber (match_scratch 5 ""))]
18532 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18533 (use (match_dup 2))
18534 (use (match_dup 3))
18535 (clobber (match_dup 5))])]
18538 (define_insn "fist<mode>2_ceil"
18539 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18540 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18542 (use (match_operand:HI 2 "memory_operand" "m"))
18543 (use (match_operand:HI 3 "memory_operand" "m"))]
18544 "TARGET_USE_FANCY_MATH_387
18545 && flag_unsafe_math_optimizations"
18546 "* return output_fix_trunc (insn, operands, 0);"
18547 [(set_attr "type" "fistp")
18548 (set_attr "i387_cw" "ceil")
18549 (set_attr "mode" "<MODE>")])
18551 (define_insn "fist<mode>2_ceil_with_temp"
18552 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18553 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18555 (use (match_operand:HI 2 "memory_operand" "m,m"))
18556 (use (match_operand:HI 3 "memory_operand" "m,m"))
18557 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18558 "TARGET_USE_FANCY_MATH_387
18559 && flag_unsafe_math_optimizations"
18561 [(set_attr "type" "fistp")
18562 (set_attr "i387_cw" "ceil")
18563 (set_attr "mode" "<MODE>")])
18566 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18567 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18569 (use (match_operand:HI 2 "memory_operand" ""))
18570 (use (match_operand:HI 3 "memory_operand" ""))
18571 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18573 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18575 (use (match_dup 2))
18576 (use (match_dup 3))])
18577 (set (match_dup 0) (match_dup 4))]
18581 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18582 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18584 (use (match_operand:HI 2 "memory_operand" ""))
18585 (use (match_operand:HI 3 "memory_operand" ""))
18586 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18588 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18590 (use (match_dup 2))
18591 (use (match_dup 3))])]
18594 (define_expand "lceilxf<mode>2"
18595 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18596 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18598 (clobber (reg:CC FLAGS_REG))])]
18599 "TARGET_USE_FANCY_MATH_387
18600 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18601 && flag_unsafe_math_optimizations"
18604 (define_expand "lceil<mode>di2"
18605 [(match_operand:DI 0 "nonimmediate_operand" "")
18606 (match_operand:MODEF 1 "register_operand" "")]
18607 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18608 && !flag_trapping_math"
18610 ix86_expand_lfloorceil (operand0, operand1, false);
18614 (define_expand "lceil<mode>si2"
18615 [(match_operand:SI 0 "nonimmediate_operand" "")
18616 (match_operand:MODEF 1 "register_operand" "")]
18617 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18618 && !flag_trapping_math"
18620 ix86_expand_lfloorceil (operand0, operand1, false);
18624 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18625 (define_insn_and_split "frndintxf2_trunc"
18626 [(set (match_operand:XF 0 "register_operand" "")
18627 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18628 UNSPEC_FRNDINT_TRUNC))
18629 (clobber (reg:CC FLAGS_REG))]
18630 "TARGET_USE_FANCY_MATH_387
18631 && flag_unsafe_math_optimizations
18632 && !(reload_completed || reload_in_progress)"
18637 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18639 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18640 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18642 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18643 operands[2], operands[3]));
18646 [(set_attr "type" "frndint")
18647 (set_attr "i387_cw" "trunc")
18648 (set_attr "mode" "XF")])
18650 (define_insn "frndintxf2_trunc_i387"
18651 [(set (match_operand:XF 0 "register_operand" "=f")
18652 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18653 UNSPEC_FRNDINT_TRUNC))
18654 (use (match_operand:HI 2 "memory_operand" "m"))
18655 (use (match_operand:HI 3 "memory_operand" "m"))]
18656 "TARGET_USE_FANCY_MATH_387
18657 && flag_unsafe_math_optimizations"
18658 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18659 [(set_attr "type" "frndint")
18660 (set_attr "i387_cw" "trunc")
18661 (set_attr "mode" "XF")])
18663 (define_expand "btruncxf2"
18664 [(use (match_operand:XF 0 "register_operand" ""))
18665 (use (match_operand:XF 1 "register_operand" ""))]
18666 "TARGET_USE_FANCY_MATH_387
18667 && flag_unsafe_math_optimizations"
18669 if (optimize_insn_for_size_p ())
18671 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18675 (define_expand "btrunc<mode>2"
18676 [(use (match_operand:MODEF 0 "register_operand" ""))
18677 (use (match_operand:MODEF 1 "register_operand" ""))]
18678 "(TARGET_USE_FANCY_MATH_387
18679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18680 || TARGET_MIX_SSE_I387)
18681 && flag_unsafe_math_optimizations)
18682 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18683 && !flag_trapping_math)"
18685 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18686 && !flag_trapping_math
18687 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18690 emit_insn (gen_sse4_1_round<mode>2
18691 (operands[0], operands[1], GEN_INT (0x03)));
18692 else if (optimize_insn_for_size_p ())
18694 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18695 ix86_expand_trunc (operand0, operand1);
18697 ix86_expand_truncdf_32 (operand0, operand1);
18703 if (optimize_insn_for_size_p ())
18706 op0 = gen_reg_rtx (XFmode);
18707 op1 = gen_reg_rtx (XFmode);
18708 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18709 emit_insn (gen_frndintxf2_trunc (op0, op1));
18711 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18716 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18717 (define_insn_and_split "frndintxf2_mask_pm"
18718 [(set (match_operand:XF 0 "register_operand" "")
18719 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18720 UNSPEC_FRNDINT_MASK_PM))
18721 (clobber (reg:CC FLAGS_REG))]
18722 "TARGET_USE_FANCY_MATH_387
18723 && flag_unsafe_math_optimizations
18724 && !(reload_completed || reload_in_progress)"
18729 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18731 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18732 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18734 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18735 operands[2], operands[3]));
18738 [(set_attr "type" "frndint")
18739 (set_attr "i387_cw" "mask_pm")
18740 (set_attr "mode" "XF")])
18742 (define_insn "frndintxf2_mask_pm_i387"
18743 [(set (match_operand:XF 0 "register_operand" "=f")
18744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18745 UNSPEC_FRNDINT_MASK_PM))
18746 (use (match_operand:HI 2 "memory_operand" "m"))
18747 (use (match_operand:HI 3 "memory_operand" "m"))]
18748 "TARGET_USE_FANCY_MATH_387
18749 && flag_unsafe_math_optimizations"
18750 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18751 [(set_attr "type" "frndint")
18752 (set_attr "i387_cw" "mask_pm")
18753 (set_attr "mode" "XF")])
18755 (define_expand "nearbyintxf2"
18756 [(use (match_operand:XF 0 "register_operand" ""))
18757 (use (match_operand:XF 1 "register_operand" ""))]
18758 "TARGET_USE_FANCY_MATH_387
18759 && flag_unsafe_math_optimizations"
18761 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18766 (define_expand "nearbyint<mode>2"
18767 [(use (match_operand:MODEF 0 "register_operand" ""))
18768 (use (match_operand:MODEF 1 "register_operand" ""))]
18769 "TARGET_USE_FANCY_MATH_387
18770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18771 || TARGET_MIX_SSE_I387)
18772 && flag_unsafe_math_optimizations"
18774 rtx op0 = gen_reg_rtx (XFmode);
18775 rtx op1 = gen_reg_rtx (XFmode);
18777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18778 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18780 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18784 (define_insn "fxam<mode>2_i387"
18785 [(set (match_operand:HI 0 "register_operand" "=a")
18787 [(match_operand:X87MODEF 1 "register_operand" "f")]
18789 "TARGET_USE_FANCY_MATH_387"
18790 "fxam\n\tfnstsw\t%0"
18791 [(set_attr "type" "multi")
18792 (set_attr "unit" "i387")
18793 (set_attr "mode" "<MODE>")])
18795 (define_expand "isinf<mode>2"
18796 [(use (match_operand:SI 0 "register_operand" ""))
18797 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18798 "TARGET_USE_FANCY_MATH_387
18799 && TARGET_C99_FUNCTIONS
18800 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18802 rtx mask = GEN_INT (0x45);
18803 rtx val = GEN_INT (0x05);
18807 rtx scratch = gen_reg_rtx (HImode);
18808 rtx res = gen_reg_rtx (QImode);
18810 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18811 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18812 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18813 cond = gen_rtx_fmt_ee (EQ, QImode,
18814 gen_rtx_REG (CCmode, FLAGS_REG),
18816 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18817 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18821 (define_expand "signbit<mode>2"
18822 [(use (match_operand:SI 0 "register_operand" ""))
18823 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18824 "TARGET_USE_FANCY_MATH_387
18825 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18827 rtx mask = GEN_INT (0x0200);
18829 rtx scratch = gen_reg_rtx (HImode);
18831 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18832 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18836 ;; Block operation instructions
18839 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18842 [(set_attr "length" "1")
18843 (set_attr "length_immediate" "0")
18844 (set_attr "modrm" "0")])
18846 (define_expand "movmemsi"
18847 [(use (match_operand:BLK 0 "memory_operand" ""))
18848 (use (match_operand:BLK 1 "memory_operand" ""))
18849 (use (match_operand:SI 2 "nonmemory_operand" ""))
18850 (use (match_operand:SI 3 "const_int_operand" ""))
18851 (use (match_operand:SI 4 "const_int_operand" ""))
18852 (use (match_operand:SI 5 "const_int_operand" ""))]
18855 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18856 operands[4], operands[5]))
18862 (define_expand "movmemdi"
18863 [(use (match_operand:BLK 0 "memory_operand" ""))
18864 (use (match_operand:BLK 1 "memory_operand" ""))
18865 (use (match_operand:DI 2 "nonmemory_operand" ""))
18866 (use (match_operand:DI 3 "const_int_operand" ""))
18867 (use (match_operand:SI 4 "const_int_operand" ""))
18868 (use (match_operand:SI 5 "const_int_operand" ""))]
18871 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18872 operands[4], operands[5]))
18878 ;; Most CPUs don't like single string operations
18879 ;; Handle this case here to simplify previous expander.
18881 (define_expand "strmov"
18882 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18883 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18884 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18885 (clobber (reg:CC FLAGS_REG))])
18886 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18887 (clobber (reg:CC FLAGS_REG))])]
18890 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18892 /* If .md ever supports :P for Pmode, these can be directly
18893 in the pattern above. */
18894 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18895 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18897 /* Can't use this if the user has appropriated esi or edi. */
18898 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18899 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18901 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18902 operands[2], operands[3],
18903 operands[5], operands[6]));
18907 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18910 (define_expand "strmov_singleop"
18911 [(parallel [(set (match_operand 1 "memory_operand" "")
18912 (match_operand 3 "memory_operand" ""))
18913 (set (match_operand 0 "register_operand" "")
18914 (match_operand 4 "" ""))
18915 (set (match_operand 2 "register_operand" "")
18916 (match_operand 5 "" ""))])]
18918 "ix86_current_function_needs_cld = 1;")
18920 (define_insn "*strmovdi_rex_1"
18921 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18922 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18923 (set (match_operand:DI 0 "register_operand" "=D")
18924 (plus:DI (match_dup 2)
18926 (set (match_operand:DI 1 "register_operand" "=S")
18927 (plus:DI (match_dup 3)
18931 [(set_attr "type" "str")
18932 (set_attr "mode" "DI")
18933 (set_attr "memory" "both")])
18935 (define_insn "*strmovsi_1"
18936 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18937 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18938 (set (match_operand:SI 0 "register_operand" "=D")
18939 (plus:SI (match_dup 2)
18941 (set (match_operand:SI 1 "register_operand" "=S")
18942 (plus:SI (match_dup 3)
18946 [(set_attr "type" "str")
18947 (set_attr "mode" "SI")
18948 (set_attr "memory" "both")])
18950 (define_insn "*strmovsi_rex_1"
18951 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18952 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18953 (set (match_operand:DI 0 "register_operand" "=D")
18954 (plus:DI (match_dup 2)
18956 (set (match_operand:DI 1 "register_operand" "=S")
18957 (plus:DI (match_dup 3)
18961 [(set_attr "type" "str")
18962 (set_attr "mode" "SI")
18963 (set_attr "memory" "both")])
18965 (define_insn "*strmovhi_1"
18966 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18967 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18968 (set (match_operand:SI 0 "register_operand" "=D")
18969 (plus:SI (match_dup 2)
18971 (set (match_operand:SI 1 "register_operand" "=S")
18972 (plus:SI (match_dup 3)
18976 [(set_attr "type" "str")
18977 (set_attr "memory" "both")
18978 (set_attr "mode" "HI")])
18980 (define_insn "*strmovhi_rex_1"
18981 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18982 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18983 (set (match_operand:DI 0 "register_operand" "=D")
18984 (plus:DI (match_dup 2)
18986 (set (match_operand:DI 1 "register_operand" "=S")
18987 (plus:DI (match_dup 3)
18991 [(set_attr "type" "str")
18992 (set_attr "memory" "both")
18993 (set_attr "mode" "HI")])
18995 (define_insn "*strmovqi_1"
18996 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18997 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18998 (set (match_operand:SI 0 "register_operand" "=D")
18999 (plus:SI (match_dup 2)
19001 (set (match_operand:SI 1 "register_operand" "=S")
19002 (plus:SI (match_dup 3)
19006 [(set_attr "type" "str")
19007 (set_attr "memory" "both")
19008 (set_attr "mode" "QI")])
19010 (define_insn "*strmovqi_rex_1"
19011 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19012 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19013 (set (match_operand:DI 0 "register_operand" "=D")
19014 (plus:DI (match_dup 2)
19016 (set (match_operand:DI 1 "register_operand" "=S")
19017 (plus:DI (match_dup 3)
19021 [(set_attr "type" "str")
19022 (set_attr "memory" "both")
19023 (set_attr "mode" "QI")])
19025 (define_expand "rep_mov"
19026 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19027 (set (match_operand 0 "register_operand" "")
19028 (match_operand 5 "" ""))
19029 (set (match_operand 2 "register_operand" "")
19030 (match_operand 6 "" ""))
19031 (set (match_operand 1 "memory_operand" "")
19032 (match_operand 3 "memory_operand" ""))
19033 (use (match_dup 4))])]
19035 "ix86_current_function_needs_cld = 1;")
19037 (define_insn "*rep_movdi_rex64"
19038 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19039 (set (match_operand:DI 0 "register_operand" "=D")
19040 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19042 (match_operand:DI 3 "register_operand" "0")))
19043 (set (match_operand:DI 1 "register_operand" "=S")
19044 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19045 (match_operand:DI 4 "register_operand" "1")))
19046 (set (mem:BLK (match_dup 3))
19047 (mem:BLK (match_dup 4)))
19048 (use (match_dup 5))]
19051 [(set_attr "type" "str")
19052 (set_attr "prefix_rep" "1")
19053 (set_attr "memory" "both")
19054 (set_attr "mode" "DI")])
19056 (define_insn "*rep_movsi"
19057 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19058 (set (match_operand:SI 0 "register_operand" "=D")
19059 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19061 (match_operand:SI 3 "register_operand" "0")))
19062 (set (match_operand:SI 1 "register_operand" "=S")
19063 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19064 (match_operand:SI 4 "register_operand" "1")))
19065 (set (mem:BLK (match_dup 3))
19066 (mem:BLK (match_dup 4)))
19067 (use (match_dup 5))]
19070 [(set_attr "type" "str")
19071 (set_attr "prefix_rep" "1")
19072 (set_attr "memory" "both")
19073 (set_attr "mode" "SI")])
19075 (define_insn "*rep_movsi_rex64"
19076 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19077 (set (match_operand:DI 0 "register_operand" "=D")
19078 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19080 (match_operand:DI 3 "register_operand" "0")))
19081 (set (match_operand:DI 1 "register_operand" "=S")
19082 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19083 (match_operand:DI 4 "register_operand" "1")))
19084 (set (mem:BLK (match_dup 3))
19085 (mem:BLK (match_dup 4)))
19086 (use (match_dup 5))]
19089 [(set_attr "type" "str")
19090 (set_attr "prefix_rep" "1")
19091 (set_attr "memory" "both")
19092 (set_attr "mode" "SI")])
19094 (define_insn "*rep_movqi"
19095 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19096 (set (match_operand:SI 0 "register_operand" "=D")
19097 (plus:SI (match_operand:SI 3 "register_operand" "0")
19098 (match_operand:SI 5 "register_operand" "2")))
19099 (set (match_operand:SI 1 "register_operand" "=S")
19100 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19101 (set (mem:BLK (match_dup 3))
19102 (mem:BLK (match_dup 4)))
19103 (use (match_dup 5))]
19106 [(set_attr "type" "str")
19107 (set_attr "prefix_rep" "1")
19108 (set_attr "memory" "both")
19109 (set_attr "mode" "SI")])
19111 (define_insn "*rep_movqi_rex64"
19112 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19113 (set (match_operand:DI 0 "register_operand" "=D")
19114 (plus:DI (match_operand:DI 3 "register_operand" "0")
19115 (match_operand:DI 5 "register_operand" "2")))
19116 (set (match_operand:DI 1 "register_operand" "=S")
19117 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19118 (set (mem:BLK (match_dup 3))
19119 (mem:BLK (match_dup 4)))
19120 (use (match_dup 5))]
19123 [(set_attr "type" "str")
19124 (set_attr "prefix_rep" "1")
19125 (set_attr "memory" "both")
19126 (set_attr "mode" "SI")])
19128 (define_expand "setmemsi"
19129 [(use (match_operand:BLK 0 "memory_operand" ""))
19130 (use (match_operand:SI 1 "nonmemory_operand" ""))
19131 (use (match_operand 2 "const_int_operand" ""))
19132 (use (match_operand 3 "const_int_operand" ""))
19133 (use (match_operand:SI 4 "const_int_operand" ""))
19134 (use (match_operand:SI 5 "const_int_operand" ""))]
19137 if (ix86_expand_setmem (operands[0], operands[1],
19138 operands[2], operands[3],
19139 operands[4], operands[5]))
19145 (define_expand "setmemdi"
19146 [(use (match_operand:BLK 0 "memory_operand" ""))
19147 (use (match_operand:DI 1 "nonmemory_operand" ""))
19148 (use (match_operand 2 "const_int_operand" ""))
19149 (use (match_operand 3 "const_int_operand" ""))
19150 (use (match_operand 4 "const_int_operand" ""))
19151 (use (match_operand 5 "const_int_operand" ""))]
19154 if (ix86_expand_setmem (operands[0], operands[1],
19155 operands[2], operands[3],
19156 operands[4], operands[5]))
19162 ;; Most CPUs don't like single string operations
19163 ;; Handle this case here to simplify previous expander.
19165 (define_expand "strset"
19166 [(set (match_operand 1 "memory_operand" "")
19167 (match_operand 2 "register_operand" ""))
19168 (parallel [(set (match_operand 0 "register_operand" "")
19170 (clobber (reg:CC FLAGS_REG))])]
19173 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19174 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19176 /* If .md ever supports :P for Pmode, this can be directly
19177 in the pattern above. */
19178 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19179 GEN_INT (GET_MODE_SIZE (GET_MODE
19181 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19183 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19189 (define_expand "strset_singleop"
19190 [(parallel [(set (match_operand 1 "memory_operand" "")
19191 (match_operand 2 "register_operand" ""))
19192 (set (match_operand 0 "register_operand" "")
19193 (match_operand 3 "" ""))])]
19195 "ix86_current_function_needs_cld = 1;")
19197 (define_insn "*strsetdi_rex_1"
19198 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19199 (match_operand:DI 2 "register_operand" "a"))
19200 (set (match_operand:DI 0 "register_operand" "=D")
19201 (plus:DI (match_dup 1)
19205 [(set_attr "type" "str")
19206 (set_attr "memory" "store")
19207 (set_attr "mode" "DI")])
19209 (define_insn "*strsetsi_1"
19210 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19211 (match_operand:SI 2 "register_operand" "a"))
19212 (set (match_operand:SI 0 "register_operand" "=D")
19213 (plus:SI (match_dup 1)
19217 [(set_attr "type" "str")
19218 (set_attr "memory" "store")
19219 (set_attr "mode" "SI")])
19221 (define_insn "*strsetsi_rex_1"
19222 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19223 (match_operand:SI 2 "register_operand" "a"))
19224 (set (match_operand:DI 0 "register_operand" "=D")
19225 (plus:DI (match_dup 1)
19229 [(set_attr "type" "str")
19230 (set_attr "memory" "store")
19231 (set_attr "mode" "SI")])
19233 (define_insn "*strsethi_1"
19234 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19235 (match_operand:HI 2 "register_operand" "a"))
19236 (set (match_operand:SI 0 "register_operand" "=D")
19237 (plus:SI (match_dup 1)
19241 [(set_attr "type" "str")
19242 (set_attr "memory" "store")
19243 (set_attr "mode" "HI")])
19245 (define_insn "*strsethi_rex_1"
19246 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19247 (match_operand:HI 2 "register_operand" "a"))
19248 (set (match_operand:DI 0 "register_operand" "=D")
19249 (plus:DI (match_dup 1)
19253 [(set_attr "type" "str")
19254 (set_attr "memory" "store")
19255 (set_attr "mode" "HI")])
19257 (define_insn "*strsetqi_1"
19258 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19259 (match_operand:QI 2 "register_operand" "a"))
19260 (set (match_operand:SI 0 "register_operand" "=D")
19261 (plus:SI (match_dup 1)
19265 [(set_attr "type" "str")
19266 (set_attr "memory" "store")
19267 (set_attr "mode" "QI")])
19269 (define_insn "*strsetqi_rex_1"
19270 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19271 (match_operand:QI 2 "register_operand" "a"))
19272 (set (match_operand:DI 0 "register_operand" "=D")
19273 (plus:DI (match_dup 1)
19277 [(set_attr "type" "str")
19278 (set_attr "memory" "store")
19279 (set_attr "mode" "QI")])
19281 (define_expand "rep_stos"
19282 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19283 (set (match_operand 0 "register_operand" "")
19284 (match_operand 4 "" ""))
19285 (set (match_operand 2 "memory_operand" "") (const_int 0))
19286 (use (match_operand 3 "register_operand" ""))
19287 (use (match_dup 1))])]
19289 "ix86_current_function_needs_cld = 1;")
19291 (define_insn "*rep_stosdi_rex64"
19292 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19293 (set (match_operand:DI 0 "register_operand" "=D")
19294 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19296 (match_operand:DI 3 "register_operand" "0")))
19297 (set (mem:BLK (match_dup 3))
19299 (use (match_operand:DI 2 "register_operand" "a"))
19300 (use (match_dup 4))]
19303 [(set_attr "type" "str")
19304 (set_attr "prefix_rep" "1")
19305 (set_attr "memory" "store")
19306 (set_attr "mode" "DI")])
19308 (define_insn "*rep_stossi"
19309 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19310 (set (match_operand:SI 0 "register_operand" "=D")
19311 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19313 (match_operand:SI 3 "register_operand" "0")))
19314 (set (mem:BLK (match_dup 3))
19316 (use (match_operand:SI 2 "register_operand" "a"))
19317 (use (match_dup 4))]
19320 [(set_attr "type" "str")
19321 (set_attr "prefix_rep" "1")
19322 (set_attr "memory" "store")
19323 (set_attr "mode" "SI")])
19325 (define_insn "*rep_stossi_rex64"
19326 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19327 (set (match_operand:DI 0 "register_operand" "=D")
19328 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19330 (match_operand:DI 3 "register_operand" "0")))
19331 (set (mem:BLK (match_dup 3))
19333 (use (match_operand:SI 2 "register_operand" "a"))
19334 (use (match_dup 4))]
19337 [(set_attr "type" "str")
19338 (set_attr "prefix_rep" "1")
19339 (set_attr "memory" "store")
19340 (set_attr "mode" "SI")])
19342 (define_insn "*rep_stosqi"
19343 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19344 (set (match_operand:SI 0 "register_operand" "=D")
19345 (plus:SI (match_operand:SI 3 "register_operand" "0")
19346 (match_operand:SI 4 "register_operand" "1")))
19347 (set (mem:BLK (match_dup 3))
19349 (use (match_operand:QI 2 "register_operand" "a"))
19350 (use (match_dup 4))]
19353 [(set_attr "type" "str")
19354 (set_attr "prefix_rep" "1")
19355 (set_attr "memory" "store")
19356 (set_attr "mode" "QI")])
19358 (define_insn "*rep_stosqi_rex64"
19359 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19360 (set (match_operand:DI 0 "register_operand" "=D")
19361 (plus:DI (match_operand:DI 3 "register_operand" "0")
19362 (match_operand:DI 4 "register_operand" "1")))
19363 (set (mem:BLK (match_dup 3))
19365 (use (match_operand:QI 2 "register_operand" "a"))
19366 (use (match_dup 4))]
19369 [(set_attr "type" "str")
19370 (set_attr "prefix_rep" "1")
19371 (set_attr "memory" "store")
19372 (set_attr "mode" "QI")])
19374 (define_expand "cmpstrnsi"
19375 [(set (match_operand:SI 0 "register_operand" "")
19376 (compare:SI (match_operand:BLK 1 "general_operand" "")
19377 (match_operand:BLK 2 "general_operand" "")))
19378 (use (match_operand 3 "general_operand" ""))
19379 (use (match_operand 4 "immediate_operand" ""))]
19382 rtx addr1, addr2, out, outlow, count, countreg, align;
19384 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19387 /* Can't use this if the user has appropriated esi or edi. */
19388 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19393 out = gen_reg_rtx (SImode);
19395 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19396 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19397 if (addr1 != XEXP (operands[1], 0))
19398 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19399 if (addr2 != XEXP (operands[2], 0))
19400 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19402 count = operands[3];
19403 countreg = ix86_zero_extend_to_Pmode (count);
19405 /* %%% Iff we are testing strict equality, we can use known alignment
19406 to good advantage. This may be possible with combine, particularly
19407 once cc0 is dead. */
19408 align = operands[4];
19410 if (CONST_INT_P (count))
19412 if (INTVAL (count) == 0)
19414 emit_move_insn (operands[0], const0_rtx);
19417 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19418 operands[1], operands[2]));
19423 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19425 emit_insn (gen_cmpsi_1 (countreg, countreg));
19426 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19427 operands[1], operands[2]));
19430 outlow = gen_lowpart (QImode, out);
19431 emit_insn (gen_cmpintqi (outlow));
19432 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19434 if (operands[0] != out)
19435 emit_move_insn (operands[0], out);
19440 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19442 (define_expand "cmpintqi"
19443 [(set (match_dup 1)
19444 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19446 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19447 (parallel [(set (match_operand:QI 0 "register_operand" "")
19448 (minus:QI (match_dup 1)
19450 (clobber (reg:CC FLAGS_REG))])]
19452 "operands[1] = gen_reg_rtx (QImode);
19453 operands[2] = gen_reg_rtx (QImode);")
19455 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19456 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19458 (define_expand "cmpstrnqi_nz_1"
19459 [(parallel [(set (reg:CC FLAGS_REG)
19460 (compare:CC (match_operand 4 "memory_operand" "")
19461 (match_operand 5 "memory_operand" "")))
19462 (use (match_operand 2 "register_operand" ""))
19463 (use (match_operand:SI 3 "immediate_operand" ""))
19464 (clobber (match_operand 0 "register_operand" ""))
19465 (clobber (match_operand 1 "register_operand" ""))
19466 (clobber (match_dup 2))])]
19468 "ix86_current_function_needs_cld = 1;")
19470 (define_insn "*cmpstrnqi_nz_1"
19471 [(set (reg:CC FLAGS_REG)
19472 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19473 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19474 (use (match_operand:SI 6 "register_operand" "2"))
19475 (use (match_operand:SI 3 "immediate_operand" "i"))
19476 (clobber (match_operand:SI 0 "register_operand" "=S"))
19477 (clobber (match_operand:SI 1 "register_operand" "=D"))
19478 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19481 [(set_attr "type" "str")
19482 (set_attr "mode" "QI")
19483 (set_attr "prefix_rep" "1")])
19485 (define_insn "*cmpstrnqi_nz_rex_1"
19486 [(set (reg:CC FLAGS_REG)
19487 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19488 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19489 (use (match_operand:DI 6 "register_operand" "2"))
19490 (use (match_operand:SI 3 "immediate_operand" "i"))
19491 (clobber (match_operand:DI 0 "register_operand" "=S"))
19492 (clobber (match_operand:DI 1 "register_operand" "=D"))
19493 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19496 [(set_attr "type" "str")
19497 (set_attr "mode" "QI")
19498 (set_attr "prefix_rep" "1")])
19500 ;; The same, but the count is not known to not be zero.
19502 (define_expand "cmpstrnqi_1"
19503 [(parallel [(set (reg:CC FLAGS_REG)
19504 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19506 (compare:CC (match_operand 4 "memory_operand" "")
19507 (match_operand 5 "memory_operand" ""))
19509 (use (match_operand:SI 3 "immediate_operand" ""))
19510 (use (reg:CC FLAGS_REG))
19511 (clobber (match_operand 0 "register_operand" ""))
19512 (clobber (match_operand 1 "register_operand" ""))
19513 (clobber (match_dup 2))])]
19515 "ix86_current_function_needs_cld = 1;")
19517 (define_insn "*cmpstrnqi_1"
19518 [(set (reg:CC FLAGS_REG)
19519 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19521 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19522 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19524 (use (match_operand:SI 3 "immediate_operand" "i"))
19525 (use (reg:CC FLAGS_REG))
19526 (clobber (match_operand:SI 0 "register_operand" "=S"))
19527 (clobber (match_operand:SI 1 "register_operand" "=D"))
19528 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19531 [(set_attr "type" "str")
19532 (set_attr "mode" "QI")
19533 (set_attr "prefix_rep" "1")])
19535 (define_insn "*cmpstrnqi_rex_1"
19536 [(set (reg:CC FLAGS_REG)
19537 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19539 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19540 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19542 (use (match_operand:SI 3 "immediate_operand" "i"))
19543 (use (reg:CC FLAGS_REG))
19544 (clobber (match_operand:DI 0 "register_operand" "=S"))
19545 (clobber (match_operand:DI 1 "register_operand" "=D"))
19546 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19549 [(set_attr "type" "str")
19550 (set_attr "mode" "QI")
19551 (set_attr "prefix_rep" "1")])
19553 (define_expand "strlensi"
19554 [(set (match_operand:SI 0 "register_operand" "")
19555 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19556 (match_operand:QI 2 "immediate_operand" "")
19557 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19560 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19566 (define_expand "strlendi"
19567 [(set (match_operand:DI 0 "register_operand" "")
19568 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19569 (match_operand:QI 2 "immediate_operand" "")
19570 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19573 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19579 (define_expand "strlenqi_1"
19580 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19581 (clobber (match_operand 1 "register_operand" ""))
19582 (clobber (reg:CC FLAGS_REG))])]
19584 "ix86_current_function_needs_cld = 1;")
19586 (define_insn "*strlenqi_1"
19587 [(set (match_operand:SI 0 "register_operand" "=&c")
19588 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19589 (match_operand:QI 2 "register_operand" "a")
19590 (match_operand:SI 3 "immediate_operand" "i")
19591 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19592 (clobber (match_operand:SI 1 "register_operand" "=D"))
19593 (clobber (reg:CC FLAGS_REG))]
19596 [(set_attr "type" "str")
19597 (set_attr "mode" "QI")
19598 (set_attr "prefix_rep" "1")])
19600 (define_insn "*strlenqi_rex_1"
19601 [(set (match_operand:DI 0 "register_operand" "=&c")
19602 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19603 (match_operand:QI 2 "register_operand" "a")
19604 (match_operand:DI 3 "immediate_operand" "i")
19605 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19606 (clobber (match_operand:DI 1 "register_operand" "=D"))
19607 (clobber (reg:CC FLAGS_REG))]
19610 [(set_attr "type" "str")
19611 (set_attr "mode" "QI")
19612 (set_attr "prefix_rep" "1")])
19614 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19615 ;; handled in combine, but it is not currently up to the task.
19616 ;; When used for their truth value, the cmpstrn* expanders generate
19625 ;; The intermediate three instructions are unnecessary.
19627 ;; This one handles cmpstrn*_nz_1...
19630 (set (reg:CC FLAGS_REG)
19631 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19632 (mem:BLK (match_operand 5 "register_operand" ""))))
19633 (use (match_operand 6 "register_operand" ""))
19634 (use (match_operand:SI 3 "immediate_operand" ""))
19635 (clobber (match_operand 0 "register_operand" ""))
19636 (clobber (match_operand 1 "register_operand" ""))
19637 (clobber (match_operand 2 "register_operand" ""))])
19638 (set (match_operand:QI 7 "register_operand" "")
19639 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19640 (set (match_operand:QI 8 "register_operand" "")
19641 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19642 (set (reg FLAGS_REG)
19643 (compare (match_dup 7) (match_dup 8)))
19645 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19647 (set (reg:CC FLAGS_REG)
19648 (compare:CC (mem:BLK (match_dup 4))
19649 (mem:BLK (match_dup 5))))
19650 (use (match_dup 6))
19651 (use (match_dup 3))
19652 (clobber (match_dup 0))
19653 (clobber (match_dup 1))
19654 (clobber (match_dup 2))])]
19657 ;; ...and this one handles cmpstrn*_1.
19660 (set (reg:CC FLAGS_REG)
19661 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19663 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19664 (mem:BLK (match_operand 5 "register_operand" "")))
19666 (use (match_operand:SI 3 "immediate_operand" ""))
19667 (use (reg:CC FLAGS_REG))
19668 (clobber (match_operand 0 "register_operand" ""))
19669 (clobber (match_operand 1 "register_operand" ""))
19670 (clobber (match_operand 2 "register_operand" ""))])
19671 (set (match_operand:QI 7 "register_operand" "")
19672 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19673 (set (match_operand:QI 8 "register_operand" "")
19674 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19675 (set (reg FLAGS_REG)
19676 (compare (match_dup 7) (match_dup 8)))
19678 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19680 (set (reg:CC FLAGS_REG)
19681 (if_then_else:CC (ne (match_dup 6)
19683 (compare:CC (mem:BLK (match_dup 4))
19684 (mem:BLK (match_dup 5)))
19686 (use (match_dup 3))
19687 (use (reg:CC FLAGS_REG))
19688 (clobber (match_dup 0))
19689 (clobber (match_dup 1))
19690 (clobber (match_dup 2))])]
19695 ;; Conditional move instructions.
19697 (define_expand "movdicc"
19698 [(set (match_operand:DI 0 "register_operand" "")
19699 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19700 (match_operand:DI 2 "general_operand" "")
19701 (match_operand:DI 3 "general_operand" "")))]
19703 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19705 (define_insn "x86_movdicc_0_m1_rex64"
19706 [(set (match_operand:DI 0 "register_operand" "=r")
19707 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19710 (clobber (reg:CC FLAGS_REG))]
19713 ; Since we don't have the proper number of operands for an alu insn,
19714 ; fill in all the blanks.
19715 [(set_attr "type" "alu")
19716 (set_attr "pent_pair" "pu")
19717 (set_attr "memory" "none")
19718 (set_attr "imm_disp" "false")
19719 (set_attr "mode" "DI")
19720 (set_attr "length_immediate" "0")])
19722 (define_insn "*x86_movdicc_0_m1_se"
19723 [(set (match_operand:DI 0 "register_operand" "=r")
19724 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19727 (clobber (reg:CC FLAGS_REG))]
19730 [(set_attr "type" "alu")
19731 (set_attr "pent_pair" "pu")
19732 (set_attr "memory" "none")
19733 (set_attr "imm_disp" "false")
19734 (set_attr "mode" "DI")
19735 (set_attr "length_immediate" "0")])
19737 (define_insn "*movdicc_c_rex64"
19738 [(set (match_operand:DI 0 "register_operand" "=r,r")
19739 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19740 [(reg FLAGS_REG) (const_int 0)])
19741 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19742 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19743 "TARGET_64BIT && TARGET_CMOVE
19744 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19746 cmov%O2%C1\t{%2, %0|%0, %2}
19747 cmov%O2%c1\t{%3, %0|%0, %3}"
19748 [(set_attr "type" "icmov")
19749 (set_attr "mode" "DI")])
19751 (define_expand "movsicc"
19752 [(set (match_operand:SI 0 "register_operand" "")
19753 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19754 (match_operand:SI 2 "general_operand" "")
19755 (match_operand:SI 3 "general_operand" "")))]
19757 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19759 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19760 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19761 ;; So just document what we're doing explicitly.
19763 (define_insn "x86_movsicc_0_m1"
19764 [(set (match_operand:SI 0 "register_operand" "=r")
19765 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19768 (clobber (reg:CC FLAGS_REG))]
19771 ; Since we don't have the proper number of operands for an alu insn,
19772 ; fill in all the blanks.
19773 [(set_attr "type" "alu")
19774 (set_attr "pent_pair" "pu")
19775 (set_attr "memory" "none")
19776 (set_attr "imm_disp" "false")
19777 (set_attr "mode" "SI")
19778 (set_attr "length_immediate" "0")])
19780 (define_insn "*x86_movsicc_0_m1_se"
19781 [(set (match_operand:SI 0 "register_operand" "=r")
19782 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19785 (clobber (reg:CC FLAGS_REG))]
19788 [(set_attr "type" "alu")
19789 (set_attr "pent_pair" "pu")
19790 (set_attr "memory" "none")
19791 (set_attr "imm_disp" "false")
19792 (set_attr "mode" "SI")
19793 (set_attr "length_immediate" "0")])
19795 (define_insn "*movsicc_noc"
19796 [(set (match_operand:SI 0 "register_operand" "=r,r")
19797 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19798 [(reg FLAGS_REG) (const_int 0)])
19799 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19800 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19802 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19804 cmov%O2%C1\t{%2, %0|%0, %2}
19805 cmov%O2%c1\t{%3, %0|%0, %3}"
19806 [(set_attr "type" "icmov")
19807 (set_attr "mode" "SI")])
19809 (define_expand "movhicc"
19810 [(set (match_operand:HI 0 "register_operand" "")
19811 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19812 (match_operand:HI 2 "general_operand" "")
19813 (match_operand:HI 3 "general_operand" "")))]
19814 "TARGET_HIMODE_MATH"
19815 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19817 (define_insn "*movhicc_noc"
19818 [(set (match_operand:HI 0 "register_operand" "=r,r")
19819 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19820 [(reg FLAGS_REG) (const_int 0)])
19821 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19822 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19824 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19826 cmov%O2%C1\t{%2, %0|%0, %2}
19827 cmov%O2%c1\t{%3, %0|%0, %3}"
19828 [(set_attr "type" "icmov")
19829 (set_attr "mode" "HI")])
19831 (define_expand "movqicc"
19832 [(set (match_operand:QI 0 "register_operand" "")
19833 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19834 (match_operand:QI 2 "general_operand" "")
19835 (match_operand:QI 3 "general_operand" "")))]
19836 "TARGET_QIMODE_MATH"
19837 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19839 (define_insn_and_split "*movqicc_noc"
19840 [(set (match_operand:QI 0 "register_operand" "=r,r")
19841 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19842 [(match_operand 4 "flags_reg_operand" "")
19844 (match_operand:QI 2 "register_operand" "r,0")
19845 (match_operand:QI 3 "register_operand" "0,r")))]
19846 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19848 "&& reload_completed"
19849 [(set (match_dup 0)
19850 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19853 "operands[0] = gen_lowpart (SImode, operands[0]);
19854 operands[2] = gen_lowpart (SImode, operands[2]);
19855 operands[3] = gen_lowpart (SImode, operands[3]);"
19856 [(set_attr "type" "icmov")
19857 (set_attr "mode" "SI")])
19859 (define_expand "mov<mode>cc"
19860 [(set (match_operand:X87MODEF 0 "register_operand" "")
19861 (if_then_else:X87MODEF
19862 (match_operand 1 "comparison_operator" "")
19863 (match_operand:X87MODEF 2 "register_operand" "")
19864 (match_operand:X87MODEF 3 "register_operand" "")))]
19865 "(TARGET_80387 && TARGET_CMOVE)
19866 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19867 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19869 (define_insn "*movsfcc_1_387"
19870 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19871 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19872 [(reg FLAGS_REG) (const_int 0)])
19873 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19874 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19875 "TARGET_80387 && TARGET_CMOVE
19876 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19878 fcmov%F1\t{%2, %0|%0, %2}
19879 fcmov%f1\t{%3, %0|%0, %3}
19880 cmov%O2%C1\t{%2, %0|%0, %2}
19881 cmov%O2%c1\t{%3, %0|%0, %3}"
19882 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19883 (set_attr "mode" "SF,SF,SI,SI")])
19885 (define_insn "*movdfcc_1"
19886 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19887 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19888 [(reg FLAGS_REG) (const_int 0)])
19889 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19890 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19891 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19892 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19894 fcmov%F1\t{%2, %0|%0, %2}
19895 fcmov%f1\t{%3, %0|%0, %3}
19898 [(set_attr "type" "fcmov,fcmov,multi,multi")
19899 (set_attr "mode" "DF")])
19901 (define_insn "*movdfcc_1_rex64"
19902 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19903 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19904 [(reg FLAGS_REG) (const_int 0)])
19905 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19906 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19907 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19908 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19910 fcmov%F1\t{%2, %0|%0, %2}
19911 fcmov%f1\t{%3, %0|%0, %3}
19912 cmov%O2%C1\t{%2, %0|%0, %2}
19913 cmov%O2%c1\t{%3, %0|%0, %3}"
19914 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19915 (set_attr "mode" "DF")])
19918 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19919 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19920 [(match_operand 4 "flags_reg_operand" "")
19922 (match_operand:DF 2 "nonimmediate_operand" "")
19923 (match_operand:DF 3 "nonimmediate_operand" "")))]
19924 "!TARGET_64BIT && reload_completed"
19925 [(set (match_dup 2)
19926 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19930 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19933 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19934 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19936 (define_insn "*movxfcc_1"
19937 [(set (match_operand:XF 0 "register_operand" "=f,f")
19938 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19939 [(reg FLAGS_REG) (const_int 0)])
19940 (match_operand:XF 2 "register_operand" "f,0")
19941 (match_operand:XF 3 "register_operand" "0,f")))]
19942 "TARGET_80387 && TARGET_CMOVE"
19944 fcmov%F1\t{%2, %0|%0, %2}
19945 fcmov%f1\t{%3, %0|%0, %3}"
19946 [(set_attr "type" "fcmov")
19947 (set_attr "mode" "XF")])
19949 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19950 ;; the scalar versions to have only XMM registers as operands.
19952 ;; SSE5 conditional move
19953 (define_insn "*sse5_pcmov_<mode>"
19954 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19955 (if_then_else:MODEF
19956 (match_operand:MODEF 1 "register_operand" "x,0")
19957 (match_operand:MODEF 2 "register_operand" "0,x")
19958 (match_operand:MODEF 3 "register_operand" "x,x")))]
19959 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19960 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19961 [(set_attr "type" "sse4arg")])
19963 ;; These versions of the min/max patterns are intentionally ignorant of
19964 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19965 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19966 ;; are undefined in this condition, we're certain this is correct.
19968 (define_insn "*avx_<code><mode>3"
19969 [(set (match_operand:MODEF 0 "register_operand" "=x")
19971 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19972 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19973 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19974 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19975 [(set_attr "type" "sseadd")
19976 (set_attr "prefix" "vex")
19977 (set_attr "mode" "<MODE>")])
19979 (define_insn "<code><mode>3"
19980 [(set (match_operand:MODEF 0 "register_operand" "=x")
19982 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19983 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19984 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19985 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19986 [(set_attr "type" "sseadd")
19987 (set_attr "mode" "<MODE>")])
19989 ;; These versions of the min/max patterns implement exactly the operations
19990 ;; min = (op1 < op2 ? op1 : op2)
19991 ;; max = (!(op1 < op2) ? op1 : op2)
19992 ;; Their operands are not commutative, and thus they may be used in the
19993 ;; presence of -0.0 and NaN.
19995 (define_insn "*avx_ieee_smin<mode>3"
19996 [(set (match_operand:MODEF 0 "register_operand" "=x")
19998 [(match_operand:MODEF 1 "register_operand" "x")
19999 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20001 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20002 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20003 [(set_attr "type" "sseadd")
20004 (set_attr "prefix" "vex")
20005 (set_attr "mode" "<MODE>")])
20007 (define_insn "*ieee_smin<mode>3"
20008 [(set (match_operand:MODEF 0 "register_operand" "=x")
20010 [(match_operand:MODEF 1 "register_operand" "0")
20011 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20013 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20014 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20015 [(set_attr "type" "sseadd")
20016 (set_attr "mode" "<MODE>")])
20018 (define_insn "*avx_ieee_smax<mode>3"
20019 [(set (match_operand:MODEF 0 "register_operand" "=x")
20021 [(match_operand:MODEF 1 "register_operand" "0")
20022 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20024 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20025 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20026 [(set_attr "type" "sseadd")
20027 (set_attr "prefix" "vex")
20028 (set_attr "mode" "<MODE>")])
20030 (define_insn "*ieee_smax<mode>3"
20031 [(set (match_operand:MODEF 0 "register_operand" "=x")
20033 [(match_operand:MODEF 1 "register_operand" "0")
20034 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20036 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20037 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20038 [(set_attr "type" "sseadd")
20039 (set_attr "mode" "<MODE>")])
20041 ;; Make two stack loads independent:
20043 ;; fld %st(0) -> fld bb
20044 ;; fmul bb fmul %st(1), %st
20046 ;; Actually we only match the last two instructions for simplicity.
20048 [(set (match_operand 0 "fp_register_operand" "")
20049 (match_operand 1 "fp_register_operand" ""))
20051 (match_operator 2 "binary_fp_operator"
20053 (match_operand 3 "memory_operand" "")]))]
20054 "REGNO (operands[0]) != REGNO (operands[1])"
20055 [(set (match_dup 0) (match_dup 3))
20056 (set (match_dup 0) (match_dup 4))]
20058 ;; The % modifier is not operational anymore in peephole2's, so we have to
20059 ;; swap the operands manually in the case of addition and multiplication.
20060 "if (COMMUTATIVE_ARITH_P (operands[2]))
20061 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20062 operands[0], operands[1]);
20064 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20065 operands[1], operands[0]);")
20067 ;; Conditional addition patterns
20068 (define_expand "add<mode>cc"
20069 [(match_operand:SWI 0 "register_operand" "")
20070 (match_operand 1 "comparison_operator" "")
20071 (match_operand:SWI 2 "register_operand" "")
20072 (match_operand:SWI 3 "const_int_operand" "")]
20074 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20077 ;; Misc patterns (?)
20079 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20080 ;; Otherwise there will be nothing to keep
20082 ;; [(set (reg ebp) (reg esp))]
20083 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20084 ;; (clobber (eflags)]
20085 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20087 ;; in proper program order.
20088 (define_insn "pro_epilogue_adjust_stack_1"
20089 [(set (match_operand:SI 0 "register_operand" "=r,r")
20090 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20091 (match_operand:SI 2 "immediate_operand" "i,i")))
20092 (clobber (reg:CC FLAGS_REG))
20093 (clobber (mem:BLK (scratch)))]
20096 switch (get_attr_type (insn))
20099 return "mov{l}\t{%1, %0|%0, %1}";
20102 if (CONST_INT_P (operands[2])
20103 && (INTVAL (operands[2]) == 128
20104 || (INTVAL (operands[2]) < 0
20105 && INTVAL (operands[2]) != -128)))
20107 operands[2] = GEN_INT (-INTVAL (operands[2]));
20108 return "sub{l}\t{%2, %0|%0, %2}";
20110 return "add{l}\t{%2, %0|%0, %2}";
20113 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20114 return "lea{l}\t{%a2, %0|%0, %a2}";
20117 gcc_unreachable ();
20120 [(set (attr "type")
20121 (cond [(eq_attr "alternative" "0")
20122 (const_string "alu")
20123 (match_operand:SI 2 "const0_operand" "")
20124 (const_string "imov")
20126 (const_string "lea")))
20127 (set_attr "mode" "SI")])
20129 (define_insn "pro_epilogue_adjust_stack_rex64"
20130 [(set (match_operand:DI 0 "register_operand" "=r,r")
20131 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20132 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20133 (clobber (reg:CC FLAGS_REG))
20134 (clobber (mem:BLK (scratch)))]
20137 switch (get_attr_type (insn))
20140 return "mov{q}\t{%1, %0|%0, %1}";
20143 if (CONST_INT_P (operands[2])
20144 /* Avoid overflows. */
20145 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20146 && (INTVAL (operands[2]) == 128
20147 || (INTVAL (operands[2]) < 0
20148 && INTVAL (operands[2]) != -128)))
20150 operands[2] = GEN_INT (-INTVAL (operands[2]));
20151 return "sub{q}\t{%2, %0|%0, %2}";
20153 return "add{q}\t{%2, %0|%0, %2}";
20156 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20157 return "lea{q}\t{%a2, %0|%0, %a2}";
20160 gcc_unreachable ();
20163 [(set (attr "type")
20164 (cond [(eq_attr "alternative" "0")
20165 (const_string "alu")
20166 (match_operand:DI 2 "const0_operand" "")
20167 (const_string "imov")
20169 (const_string "lea")))
20170 (set_attr "mode" "DI")])
20172 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20173 [(set (match_operand:DI 0 "register_operand" "=r,r")
20174 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20175 (match_operand:DI 3 "immediate_operand" "i,i")))
20176 (use (match_operand:DI 2 "register_operand" "r,r"))
20177 (clobber (reg:CC FLAGS_REG))
20178 (clobber (mem:BLK (scratch)))]
20181 switch (get_attr_type (insn))
20184 return "add{q}\t{%2, %0|%0, %2}";
20187 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20188 return "lea{q}\t{%a2, %0|%0, %a2}";
20191 gcc_unreachable ();
20194 [(set_attr "type" "alu,lea")
20195 (set_attr "mode" "DI")])
20197 (define_insn "allocate_stack_worker_32"
20198 [(set (match_operand:SI 0 "register_operand" "=a")
20199 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20200 UNSPECV_STACK_PROBE))
20201 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
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_operand:DI 1 "register_operand" "0")]
20211 UNSPECV_STACK_PROBE))
20212 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20213 (clobber (reg:DI R10_REG))
20214 (clobber (reg:DI R11_REG))
20215 (clobber (reg:CC FLAGS_REG))]
20216 "TARGET_64BIT && TARGET_STACK_PROBE"
20218 [(set_attr "type" "multi")
20219 (set_attr "length" "5")])
20221 (define_expand "allocate_stack"
20222 [(match_operand 0 "register_operand" "")
20223 (match_operand 1 "general_operand" "")]
20224 "TARGET_STACK_PROBE"
20228 #ifndef CHECK_STACK_LIMIT
20229 #define CHECK_STACK_LIMIT 0
20232 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20233 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20235 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20236 stack_pointer_rtx, 0, OPTAB_DIRECT);
20237 if (x != stack_pointer_rtx)
20238 emit_move_insn (stack_pointer_rtx, x);
20242 x = copy_to_mode_reg (Pmode, operands[1]);
20244 x = gen_allocate_stack_worker_64 (x, x);
20246 x = gen_allocate_stack_worker_32 (x, x);
20250 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20254 (define_expand "builtin_setjmp_receiver"
20255 [(label_ref (match_operand 0 "" ""))]
20256 "!TARGET_64BIT && flag_pic"
20262 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20263 rtx label_rtx = gen_label_rtx ();
20264 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20265 xops[0] = xops[1] = picreg;
20266 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20267 ix86_expand_binary_operator (MINUS, SImode, xops);
20271 emit_insn (gen_set_got (pic_offset_table_rtx));
20275 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20278 [(set (match_operand 0 "register_operand" "")
20279 (match_operator 3 "promotable_binary_operator"
20280 [(match_operand 1 "register_operand" "")
20281 (match_operand 2 "aligned_operand" "")]))
20282 (clobber (reg:CC FLAGS_REG))]
20283 "! TARGET_PARTIAL_REG_STALL && reload_completed
20284 && ((GET_MODE (operands[0]) == HImode
20285 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20286 /* ??? next two lines just !satisfies_constraint_K (...) */
20287 || !CONST_INT_P (operands[2])
20288 || satisfies_constraint_K (operands[2])))
20289 || (GET_MODE (operands[0]) == QImode
20290 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20291 [(parallel [(set (match_dup 0)
20292 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20293 (clobber (reg:CC FLAGS_REG))])]
20294 "operands[0] = gen_lowpart (SImode, operands[0]);
20295 operands[1] = gen_lowpart (SImode, operands[1]);
20296 if (GET_CODE (operands[3]) != ASHIFT)
20297 operands[2] = gen_lowpart (SImode, operands[2]);
20298 PUT_MODE (operands[3], SImode);")
20300 ; Promote the QImode tests, as i386 has encoding of the AND
20301 ; instruction with 32-bit sign-extended immediate and thus the
20302 ; instruction size is unchanged, except in the %eax case for
20303 ; which it is increased by one byte, hence the ! optimize_size.
20305 [(set (match_operand 0 "flags_reg_operand" "")
20306 (match_operator 2 "compare_operator"
20307 [(and (match_operand 3 "aligned_operand" "")
20308 (match_operand 4 "const_int_operand" ""))
20310 (set (match_operand 1 "register_operand" "")
20311 (and (match_dup 3) (match_dup 4)))]
20312 "! TARGET_PARTIAL_REG_STALL && reload_completed
20313 && optimize_insn_for_speed_p ()
20314 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20315 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20316 /* Ensure that the operand will remain sign-extended immediate. */
20317 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20318 [(parallel [(set (match_dup 0)
20319 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20322 (and:SI (match_dup 3) (match_dup 4)))])]
20325 = gen_int_mode (INTVAL (operands[4])
20326 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20327 operands[1] = gen_lowpart (SImode, operands[1]);
20328 operands[3] = gen_lowpart (SImode, operands[3]);
20331 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20332 ; the TEST instruction with 32-bit sign-extended immediate and thus
20333 ; the instruction size would at least double, which is not what we
20334 ; want even with ! optimize_size.
20336 [(set (match_operand 0 "flags_reg_operand" "")
20337 (match_operator 1 "compare_operator"
20338 [(and (match_operand:HI 2 "aligned_operand" "")
20339 (match_operand:HI 3 "const_int_operand" ""))
20341 "! TARGET_PARTIAL_REG_STALL && reload_completed
20342 && ! TARGET_FAST_PREFIX
20343 && optimize_insn_for_speed_p ()
20344 /* Ensure that the operand will remain sign-extended immediate. */
20345 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20346 [(set (match_dup 0)
20347 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20351 = gen_int_mode (INTVAL (operands[3])
20352 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20353 operands[2] = gen_lowpart (SImode, operands[2]);
20357 [(set (match_operand 0 "register_operand" "")
20358 (neg (match_operand 1 "register_operand" "")))
20359 (clobber (reg:CC FLAGS_REG))]
20360 "! TARGET_PARTIAL_REG_STALL && reload_completed
20361 && (GET_MODE (operands[0]) == HImode
20362 || (GET_MODE (operands[0]) == QImode
20363 && (TARGET_PROMOTE_QImode
20364 || optimize_insn_for_size_p ())))"
20365 [(parallel [(set (match_dup 0)
20366 (neg:SI (match_dup 1)))
20367 (clobber (reg:CC FLAGS_REG))])]
20368 "operands[0] = gen_lowpart (SImode, operands[0]);
20369 operands[1] = gen_lowpart (SImode, operands[1]);")
20372 [(set (match_operand 0 "register_operand" "")
20373 (not (match_operand 1 "register_operand" "")))]
20374 "! TARGET_PARTIAL_REG_STALL && reload_completed
20375 && (GET_MODE (operands[0]) == HImode
20376 || (GET_MODE (operands[0]) == QImode
20377 && (TARGET_PROMOTE_QImode
20378 || optimize_insn_for_size_p ())))"
20379 [(set (match_dup 0)
20380 (not:SI (match_dup 1)))]
20381 "operands[0] = gen_lowpart (SImode, operands[0]);
20382 operands[1] = gen_lowpart (SImode, operands[1]);")
20385 [(set (match_operand 0 "register_operand" "")
20386 (if_then_else (match_operator 1 "comparison_operator"
20387 [(reg FLAGS_REG) (const_int 0)])
20388 (match_operand 2 "register_operand" "")
20389 (match_operand 3 "register_operand" "")))]
20390 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20391 && (GET_MODE (operands[0]) == HImode
20392 || (GET_MODE (operands[0]) == QImode
20393 && (TARGET_PROMOTE_QImode
20394 || optimize_insn_for_size_p ())))"
20395 [(set (match_dup 0)
20396 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20397 "operands[0] = gen_lowpart (SImode, operands[0]);
20398 operands[2] = gen_lowpart (SImode, operands[2]);
20399 operands[3] = gen_lowpart (SImode, operands[3]);")
20402 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20403 ;; transform a complex memory operation into two memory to register operations.
20405 ;; Don't push memory operands
20407 [(set (match_operand:SI 0 "push_operand" "")
20408 (match_operand:SI 1 "memory_operand" ""))
20409 (match_scratch:SI 2 "r")]
20410 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20411 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20412 [(set (match_dup 2) (match_dup 1))
20413 (set (match_dup 0) (match_dup 2))]
20417 [(set (match_operand:DI 0 "push_operand" "")
20418 (match_operand:DI 1 "memory_operand" ""))
20419 (match_scratch:DI 2 "r")]
20420 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20421 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20422 [(set (match_dup 2) (match_dup 1))
20423 (set (match_dup 0) (match_dup 2))]
20426 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20429 [(set (match_operand:SF 0 "push_operand" "")
20430 (match_operand:SF 1 "memory_operand" ""))
20431 (match_scratch:SF 2 "r")]
20432 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20433 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20434 [(set (match_dup 2) (match_dup 1))
20435 (set (match_dup 0) (match_dup 2))]
20439 [(set (match_operand:HI 0 "push_operand" "")
20440 (match_operand:HI 1 "memory_operand" ""))
20441 (match_scratch:HI 2 "r")]
20442 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20443 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20444 [(set (match_dup 2) (match_dup 1))
20445 (set (match_dup 0) (match_dup 2))]
20449 [(set (match_operand:QI 0 "push_operand" "")
20450 (match_operand:QI 1 "memory_operand" ""))
20451 (match_scratch:QI 2 "q")]
20452 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20453 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20454 [(set (match_dup 2) (match_dup 1))
20455 (set (match_dup 0) (match_dup 2))]
20458 ;; Don't move an immediate directly to memory when the instruction
20461 [(match_scratch:SI 1 "r")
20462 (set (match_operand:SI 0 "memory_operand" "")
20464 "optimize_insn_for_speed_p ()
20465 && ! TARGET_USE_MOV0
20466 && TARGET_SPLIT_LONG_MOVES
20467 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20468 && peep2_regno_dead_p (0, FLAGS_REG)"
20469 [(parallel [(set (match_dup 1) (const_int 0))
20470 (clobber (reg:CC FLAGS_REG))])
20471 (set (match_dup 0) (match_dup 1))]
20475 [(match_scratch:HI 1 "r")
20476 (set (match_operand:HI 0 "memory_operand" "")
20478 "optimize_insn_for_speed_p ()
20479 && ! TARGET_USE_MOV0
20480 && TARGET_SPLIT_LONG_MOVES
20481 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20482 && peep2_regno_dead_p (0, FLAGS_REG)"
20483 [(parallel [(set (match_dup 2) (const_int 0))
20484 (clobber (reg:CC FLAGS_REG))])
20485 (set (match_dup 0) (match_dup 1))]
20486 "operands[2] = gen_lowpart (SImode, operands[1]);")
20489 [(match_scratch:QI 1 "q")
20490 (set (match_operand:QI 0 "memory_operand" "")
20492 "optimize_insn_for_speed_p ()
20493 && ! TARGET_USE_MOV0
20494 && TARGET_SPLIT_LONG_MOVES
20495 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20496 && peep2_regno_dead_p (0, FLAGS_REG)"
20497 [(parallel [(set (match_dup 2) (const_int 0))
20498 (clobber (reg:CC FLAGS_REG))])
20499 (set (match_dup 0) (match_dup 1))]
20500 "operands[2] = gen_lowpart (SImode, operands[1]);")
20503 [(match_scratch:SI 2 "r")
20504 (set (match_operand:SI 0 "memory_operand" "")
20505 (match_operand:SI 1 "immediate_operand" ""))]
20506 "optimize_insn_for_speed_p ()
20507 && TARGET_SPLIT_LONG_MOVES
20508 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20509 [(set (match_dup 2) (match_dup 1))
20510 (set (match_dup 0) (match_dup 2))]
20514 [(match_scratch:HI 2 "r")
20515 (set (match_operand:HI 0 "memory_operand" "")
20516 (match_operand:HI 1 "immediate_operand" ""))]
20517 "optimize_insn_for_speed_p ()
20518 && TARGET_SPLIT_LONG_MOVES
20519 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20520 [(set (match_dup 2) (match_dup 1))
20521 (set (match_dup 0) (match_dup 2))]
20525 [(match_scratch:QI 2 "q")
20526 (set (match_operand:QI 0 "memory_operand" "")
20527 (match_operand:QI 1 "immediate_operand" ""))]
20528 "optimize_insn_for_speed_p ()
20529 && TARGET_SPLIT_LONG_MOVES
20530 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20531 [(set (match_dup 2) (match_dup 1))
20532 (set (match_dup 0) (match_dup 2))]
20535 ;; Don't compare memory with zero, load and use a test instead.
20537 [(set (match_operand 0 "flags_reg_operand" "")
20538 (match_operator 1 "compare_operator"
20539 [(match_operand:SI 2 "memory_operand" "")
20541 (match_scratch:SI 3 "r")]
20542 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20543 [(set (match_dup 3) (match_dup 2))
20544 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20547 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20548 ;; Don't split NOTs with a displacement operand, because resulting XOR
20549 ;; will not be pairable anyway.
20551 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20552 ;; represented using a modRM byte. The XOR replacement is long decoded,
20553 ;; so this split helps here as well.
20555 ;; Note: Can't do this as a regular split because we can't get proper
20556 ;; lifetime information then.
20559 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20560 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20561 "optimize_insn_for_speed_p ()
20562 && ((TARGET_NOT_UNPAIRABLE
20563 && (!MEM_P (operands[0])
20564 || !memory_displacement_operand (operands[0], SImode)))
20565 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20566 && peep2_regno_dead_p (0, FLAGS_REG)"
20567 [(parallel [(set (match_dup 0)
20568 (xor:SI (match_dup 1) (const_int -1)))
20569 (clobber (reg:CC FLAGS_REG))])]
20573 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20574 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20575 "optimize_insn_for_speed_p ()
20576 && ((TARGET_NOT_UNPAIRABLE
20577 && (!MEM_P (operands[0])
20578 || !memory_displacement_operand (operands[0], HImode)))
20579 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20580 && peep2_regno_dead_p (0, FLAGS_REG)"
20581 [(parallel [(set (match_dup 0)
20582 (xor:HI (match_dup 1) (const_int -1)))
20583 (clobber (reg:CC FLAGS_REG))])]
20587 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20588 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20589 "optimize_insn_for_speed_p ()
20590 && ((TARGET_NOT_UNPAIRABLE
20591 && (!MEM_P (operands[0])
20592 || !memory_displacement_operand (operands[0], QImode)))
20593 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20594 && peep2_regno_dead_p (0, FLAGS_REG)"
20595 [(parallel [(set (match_dup 0)
20596 (xor:QI (match_dup 1) (const_int -1)))
20597 (clobber (reg:CC FLAGS_REG))])]
20600 ;; Non pairable "test imm, reg" instructions can be translated to
20601 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20602 ;; byte opcode instead of two, have a short form for byte operands),
20603 ;; so do it for other CPUs as well. Given that the value was dead,
20604 ;; this should not create any new dependencies. Pass on the sub-word
20605 ;; versions if we're concerned about partial register stalls.
20608 [(set (match_operand 0 "flags_reg_operand" "")
20609 (match_operator 1 "compare_operator"
20610 [(and:SI (match_operand:SI 2 "register_operand" "")
20611 (match_operand:SI 3 "immediate_operand" ""))
20613 "ix86_match_ccmode (insn, CCNOmode)
20614 && (true_regnum (operands[2]) != AX_REG
20615 || satisfies_constraint_K (operands[3]))
20616 && peep2_reg_dead_p (1, operands[2])"
20618 [(set (match_dup 0)
20619 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20622 (and:SI (match_dup 2) (match_dup 3)))])]
20625 ;; We don't need to handle HImode case, because it will be promoted to SImode
20626 ;; on ! TARGET_PARTIAL_REG_STALL
20629 [(set (match_operand 0 "flags_reg_operand" "")
20630 (match_operator 1 "compare_operator"
20631 [(and:QI (match_operand:QI 2 "register_operand" "")
20632 (match_operand:QI 3 "immediate_operand" ""))
20634 "! TARGET_PARTIAL_REG_STALL
20635 && ix86_match_ccmode (insn, CCNOmode)
20636 && true_regnum (operands[2]) != AX_REG
20637 && peep2_reg_dead_p (1, operands[2])"
20639 [(set (match_dup 0)
20640 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20643 (and:QI (match_dup 2) (match_dup 3)))])]
20647 [(set (match_operand 0 "flags_reg_operand" "")
20648 (match_operator 1 "compare_operator"
20651 (match_operand 2 "ext_register_operand" "")
20654 (match_operand 3 "const_int_operand" ""))
20656 "! TARGET_PARTIAL_REG_STALL
20657 && ix86_match_ccmode (insn, CCNOmode)
20658 && true_regnum (operands[2]) != AX_REG
20659 && peep2_reg_dead_p (1, operands[2])"
20660 [(parallel [(set (match_dup 0)
20669 (set (zero_extract:SI (match_dup 2)
20680 ;; Don't do logical operations with memory inputs.
20682 [(match_scratch:SI 2 "r")
20683 (parallel [(set (match_operand:SI 0 "register_operand" "")
20684 (match_operator:SI 3 "arith_or_logical_operator"
20686 (match_operand:SI 1 "memory_operand" "")]))
20687 (clobber (reg:CC FLAGS_REG))])]
20688 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20689 [(set (match_dup 2) (match_dup 1))
20690 (parallel [(set (match_dup 0)
20691 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20692 (clobber (reg:CC FLAGS_REG))])]
20696 [(match_scratch:SI 2 "r")
20697 (parallel [(set (match_operand:SI 0 "register_operand" "")
20698 (match_operator:SI 3 "arith_or_logical_operator"
20699 [(match_operand:SI 1 "memory_operand" "")
20701 (clobber (reg:CC FLAGS_REG))])]
20702 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20703 [(set (match_dup 2) (match_dup 1))
20704 (parallel [(set (match_dup 0)
20705 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20706 (clobber (reg:CC FLAGS_REG))])]
20709 ; Don't do logical operations with memory outputs
20711 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20712 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20713 ; the same decoder scheduling characteristics as the original.
20716 [(match_scratch:SI 2 "r")
20717 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20718 (match_operator:SI 3 "arith_or_logical_operator"
20720 (match_operand:SI 1 "nonmemory_operand" "")]))
20721 (clobber (reg:CC FLAGS_REG))])]
20722 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20723 [(set (match_dup 2) (match_dup 0))
20724 (parallel [(set (match_dup 2)
20725 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20726 (clobber (reg:CC FLAGS_REG))])
20727 (set (match_dup 0) (match_dup 2))]
20731 [(match_scratch:SI 2 "r")
20732 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20733 (match_operator:SI 3 "arith_or_logical_operator"
20734 [(match_operand:SI 1 "nonmemory_operand" "")
20736 (clobber (reg:CC FLAGS_REG))])]
20737 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20738 [(set (match_dup 2) (match_dup 0))
20739 (parallel [(set (match_dup 2)
20740 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20741 (clobber (reg:CC FLAGS_REG))])
20742 (set (match_dup 0) (match_dup 2))]
20745 ;; Attempt to always use XOR for zeroing registers.
20747 [(set (match_operand 0 "register_operand" "")
20748 (match_operand 1 "const0_operand" ""))]
20749 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20750 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20751 && GENERAL_REG_P (operands[0])
20752 && peep2_regno_dead_p (0, FLAGS_REG)"
20753 [(parallel [(set (match_dup 0) (const_int 0))
20754 (clobber (reg:CC FLAGS_REG))])]
20756 operands[0] = gen_lowpart (word_mode, operands[0]);
20760 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20762 "(GET_MODE (operands[0]) == QImode
20763 || GET_MODE (operands[0]) == HImode)
20764 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20765 && peep2_regno_dead_p (0, FLAGS_REG)"
20766 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20767 (clobber (reg:CC FLAGS_REG))])])
20769 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20771 [(set (match_operand 0 "register_operand" "")
20773 "(GET_MODE (operands[0]) == HImode
20774 || GET_MODE (operands[0]) == SImode
20775 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20776 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20777 && peep2_regno_dead_p (0, FLAGS_REG)"
20778 [(parallel [(set (match_dup 0) (const_int -1))
20779 (clobber (reg:CC FLAGS_REG))])]
20780 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20783 ;; Attempt to convert simple leas to adds. These can be created by
20786 [(set (match_operand:SI 0 "register_operand" "")
20787 (plus:SI (match_dup 0)
20788 (match_operand:SI 1 "nonmemory_operand" "")))]
20789 "peep2_regno_dead_p (0, FLAGS_REG)"
20790 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20791 (clobber (reg:CC FLAGS_REG))])]
20795 [(set (match_operand:SI 0 "register_operand" "")
20796 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20797 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20798 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20799 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20800 (clobber (reg:CC FLAGS_REG))])]
20801 "operands[2] = gen_lowpart (SImode, operands[2]);")
20804 [(set (match_operand:DI 0 "register_operand" "")
20805 (plus:DI (match_dup 0)
20806 (match_operand:DI 1 "x86_64_general_operand" "")))]
20807 "peep2_regno_dead_p (0, FLAGS_REG)"
20808 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20809 (clobber (reg:CC FLAGS_REG))])]
20813 [(set (match_operand:SI 0 "register_operand" "")
20814 (mult:SI (match_dup 0)
20815 (match_operand:SI 1 "const_int_operand" "")))]
20816 "exact_log2 (INTVAL (operands[1])) >= 0
20817 && peep2_regno_dead_p (0, FLAGS_REG)"
20818 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20819 (clobber (reg:CC FLAGS_REG))])]
20820 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20823 [(set (match_operand:DI 0 "register_operand" "")
20824 (mult:DI (match_dup 0)
20825 (match_operand:DI 1 "const_int_operand" "")))]
20826 "exact_log2 (INTVAL (operands[1])) >= 0
20827 && peep2_regno_dead_p (0, FLAGS_REG)"
20828 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20829 (clobber (reg:CC FLAGS_REG))])]
20830 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20833 [(set (match_operand:SI 0 "register_operand" "")
20834 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20835 (match_operand:DI 2 "const_int_operand" "")) 0))]
20836 "exact_log2 (INTVAL (operands[2])) >= 0
20837 && REGNO (operands[0]) == REGNO (operands[1])
20838 && peep2_regno_dead_p (0, FLAGS_REG)"
20839 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20840 (clobber (reg:CC FLAGS_REG))])]
20841 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20843 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20844 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20845 ;; many CPUs it is also faster, since special hardware to avoid esp
20846 ;; dependencies is present.
20848 ;; While some of these conversions may be done using splitters, we use peepholes
20849 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20851 ;; Convert prologue esp subtractions to push.
20852 ;; We need register to push. In order to keep verify_flow_info happy we have
20854 ;; - use scratch and clobber it in order to avoid dependencies
20855 ;; - use already live register
20856 ;; We can't use the second way right now, since there is no reliable way how to
20857 ;; verify that given register is live. First choice will also most likely in
20858 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20859 ;; call clobbered registers are dead. We may want to use base pointer as an
20860 ;; alternative when no register is available later.
20863 [(match_scratch:SI 0 "r")
20864 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20865 (clobber (reg:CC FLAGS_REG))
20866 (clobber (mem:BLK (scratch)))])]
20867 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20868 [(clobber (match_dup 0))
20869 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20870 (clobber (mem:BLK (scratch)))])])
20873 [(match_scratch:SI 0 "r")
20874 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20875 (clobber (reg:CC FLAGS_REG))
20876 (clobber (mem:BLK (scratch)))])]
20877 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20878 [(clobber (match_dup 0))
20879 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20880 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20881 (clobber (mem:BLK (scratch)))])])
20883 ;; Convert esp subtractions to push.
20885 [(match_scratch:SI 0 "r")
20886 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20887 (clobber (reg:CC FLAGS_REG))])]
20888 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20889 [(clobber (match_dup 0))
20890 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20893 [(match_scratch:SI 0 "r")
20894 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20895 (clobber (reg:CC FLAGS_REG))])]
20896 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20897 [(clobber (match_dup 0))
20898 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20899 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20901 ;; Convert epilogue deallocator to pop.
20903 [(match_scratch:SI 0 "r")
20904 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20905 (clobber (reg:CC FLAGS_REG))
20906 (clobber (mem:BLK (scratch)))])]
20907 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20908 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20909 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20910 (clobber (mem:BLK (scratch)))])]
20913 ;; Two pops case is tricky, since pop causes dependency on destination register.
20914 ;; We use two registers if available.
20916 [(match_scratch:SI 0 "r")
20917 (match_scratch:SI 1 "r")
20918 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20919 (clobber (reg:CC FLAGS_REG))
20920 (clobber (mem:BLK (scratch)))])]
20921 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20922 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20923 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20924 (clobber (mem:BLK (scratch)))])
20925 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20926 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20930 [(match_scratch:SI 0 "r")
20931 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20932 (clobber (reg:CC FLAGS_REG))
20933 (clobber (mem:BLK (scratch)))])]
20934 "optimize_insn_for_size_p ()"
20935 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20936 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20937 (clobber (mem:BLK (scratch)))])
20938 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20939 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20942 ;; Convert esp additions to pop.
20944 [(match_scratch:SI 0 "r")
20945 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20946 (clobber (reg:CC FLAGS_REG))])]
20948 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20949 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20952 ;; Two pops case is tricky, since pop causes dependency on destination register.
20953 ;; We use two registers if available.
20955 [(match_scratch:SI 0 "r")
20956 (match_scratch:SI 1 "r")
20957 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20958 (clobber (reg:CC FLAGS_REG))])]
20960 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20961 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20962 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20963 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20967 [(match_scratch:SI 0 "r")
20968 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20969 (clobber (reg:CC FLAGS_REG))])]
20970 "optimize_insn_for_size_p ()"
20971 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20972 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20973 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20974 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20977 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20978 ;; required and register dies. Similarly for 128 to -128.
20980 [(set (match_operand 0 "flags_reg_operand" "")
20981 (match_operator 1 "compare_operator"
20982 [(match_operand 2 "register_operand" "")
20983 (match_operand 3 "const_int_operand" "")]))]
20984 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20985 && incdec_operand (operands[3], GET_MODE (operands[3])))
20986 || (!TARGET_FUSE_CMP_AND_BRANCH
20987 && INTVAL (operands[3]) == 128))
20988 && ix86_match_ccmode (insn, CCGCmode)
20989 && peep2_reg_dead_p (1, operands[2])"
20990 [(parallel [(set (match_dup 0)
20991 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20992 (clobber (match_dup 2))])]
20996 [(match_scratch:DI 0 "r")
20997 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20998 (clobber (reg:CC FLAGS_REG))
20999 (clobber (mem:BLK (scratch)))])]
21000 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21001 [(clobber (match_dup 0))
21002 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21003 (clobber (mem:BLK (scratch)))])])
21006 [(match_scratch:DI 0 "r")
21007 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21008 (clobber (reg:CC FLAGS_REG))
21009 (clobber (mem:BLK (scratch)))])]
21010 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21011 [(clobber (match_dup 0))
21012 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21013 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21014 (clobber (mem:BLK (scratch)))])])
21016 ;; Convert esp subtractions to push.
21018 [(match_scratch:DI 0 "r")
21019 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21020 (clobber (reg:CC FLAGS_REG))])]
21021 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21022 [(clobber (match_dup 0))
21023 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21026 [(match_scratch:DI 0 "r")
21027 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21028 (clobber (reg:CC FLAGS_REG))])]
21029 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21030 [(clobber (match_dup 0))
21031 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21032 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21034 ;; Convert epilogue deallocator to pop.
21036 [(match_scratch:DI 0 "r")
21037 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21038 (clobber (reg:CC FLAGS_REG))
21039 (clobber (mem:BLK (scratch)))])]
21040 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21041 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21042 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21043 (clobber (mem:BLK (scratch)))])]
21046 ;; Two pops case is tricky, since pop causes dependency on destination register.
21047 ;; We use two registers if available.
21049 [(match_scratch:DI 0 "r")
21050 (match_scratch:DI 1 "r")
21051 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21052 (clobber (reg:CC FLAGS_REG))
21053 (clobber (mem:BLK (scratch)))])]
21054 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21055 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21056 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21057 (clobber (mem:BLK (scratch)))])
21058 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21059 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21063 [(match_scratch:DI 0 "r")
21064 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21065 (clobber (reg:CC FLAGS_REG))
21066 (clobber (mem:BLK (scratch)))])]
21067 "optimize_insn_for_size_p ()"
21068 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21069 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21070 (clobber (mem:BLK (scratch)))])
21071 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21072 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21075 ;; Convert esp additions to pop.
21077 [(match_scratch:DI 0 "r")
21078 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21079 (clobber (reg:CC FLAGS_REG))])]
21081 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21082 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21085 ;; Two pops case is tricky, since pop causes dependency on destination register.
21086 ;; We use two registers if available.
21088 [(match_scratch:DI 0 "r")
21089 (match_scratch:DI 1 "r")
21090 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21091 (clobber (reg:CC FLAGS_REG))])]
21093 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21094 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21095 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21096 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21100 [(match_scratch:DI 0 "r")
21101 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21102 (clobber (reg:CC FLAGS_REG))])]
21103 "optimize_insn_for_size_p ()"
21104 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21105 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21106 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21107 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21110 ;; Convert imul by three, five and nine into lea
21113 [(set (match_operand:SI 0 "register_operand" "")
21114 (mult:SI (match_operand:SI 1 "register_operand" "")
21115 (match_operand:SI 2 "const_int_operand" "")))
21116 (clobber (reg:CC FLAGS_REG))])]
21117 "INTVAL (operands[2]) == 3
21118 || INTVAL (operands[2]) == 5
21119 || INTVAL (operands[2]) == 9"
21120 [(set (match_dup 0)
21121 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21123 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21127 [(set (match_operand:SI 0 "register_operand" "")
21128 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21129 (match_operand:SI 2 "const_int_operand" "")))
21130 (clobber (reg:CC FLAGS_REG))])]
21131 "optimize_insn_for_speed_p ()
21132 && (INTVAL (operands[2]) == 3
21133 || INTVAL (operands[2]) == 5
21134 || INTVAL (operands[2]) == 9)"
21135 [(set (match_dup 0) (match_dup 1))
21137 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21139 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21143 [(set (match_operand:DI 0 "register_operand" "")
21144 (mult:DI (match_operand:DI 1 "register_operand" "")
21145 (match_operand:DI 2 "const_int_operand" "")))
21146 (clobber (reg:CC FLAGS_REG))])]
21148 && (INTVAL (operands[2]) == 3
21149 || INTVAL (operands[2]) == 5
21150 || INTVAL (operands[2]) == 9)"
21151 [(set (match_dup 0)
21152 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21154 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21158 [(set (match_operand:DI 0 "register_operand" "")
21159 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21160 (match_operand:DI 2 "const_int_operand" "")))
21161 (clobber (reg:CC FLAGS_REG))])]
21163 && optimize_insn_for_speed_p ()
21164 && (INTVAL (operands[2]) == 3
21165 || INTVAL (operands[2]) == 5
21166 || INTVAL (operands[2]) == 9)"
21167 [(set (match_dup 0) (match_dup 1))
21169 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21171 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21173 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21174 ;; imul $32bit_imm, reg, reg is direct decoded.
21176 [(match_scratch:DI 3 "r")
21177 (parallel [(set (match_operand:DI 0 "register_operand" "")
21178 (mult:DI (match_operand:DI 1 "memory_operand" "")
21179 (match_operand:DI 2 "immediate_operand" "")))
21180 (clobber (reg:CC FLAGS_REG))])]
21181 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21182 && !satisfies_constraint_K (operands[2])"
21183 [(set (match_dup 3) (match_dup 1))
21184 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21185 (clobber (reg:CC FLAGS_REG))])]
21189 [(match_scratch:SI 3 "r")
21190 (parallel [(set (match_operand:SI 0 "register_operand" "")
21191 (mult:SI (match_operand:SI 1 "memory_operand" "")
21192 (match_operand:SI 2 "immediate_operand" "")))
21193 (clobber (reg:CC FLAGS_REG))])]
21194 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21195 && !satisfies_constraint_K (operands[2])"
21196 [(set (match_dup 3) (match_dup 1))
21197 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21198 (clobber (reg:CC FLAGS_REG))])]
21202 [(match_scratch:SI 3 "r")
21203 (parallel [(set (match_operand:DI 0 "register_operand" "")
21205 (mult:SI (match_operand:SI 1 "memory_operand" "")
21206 (match_operand:SI 2 "immediate_operand" ""))))
21207 (clobber (reg:CC FLAGS_REG))])]
21208 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21209 && !satisfies_constraint_K (operands[2])"
21210 [(set (match_dup 3) (match_dup 1))
21211 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21212 (clobber (reg:CC FLAGS_REG))])]
21215 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21216 ;; Convert it into imul reg, reg
21217 ;; It would be better to force assembler to encode instruction using long
21218 ;; immediate, but there is apparently no way to do so.
21220 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21221 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21222 (match_operand:DI 2 "const_int_operand" "")))
21223 (clobber (reg:CC FLAGS_REG))])
21224 (match_scratch:DI 3 "r")]
21225 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21226 && satisfies_constraint_K (operands[2])"
21227 [(set (match_dup 3) (match_dup 2))
21228 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21229 (clobber (reg:CC FLAGS_REG))])]
21231 if (!rtx_equal_p (operands[0], operands[1]))
21232 emit_move_insn (operands[0], operands[1]);
21236 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21237 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21238 (match_operand:SI 2 "const_int_operand" "")))
21239 (clobber (reg:CC FLAGS_REG))])
21240 (match_scratch:SI 3 "r")]
21241 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21242 && satisfies_constraint_K (operands[2])"
21243 [(set (match_dup 3) (match_dup 2))
21244 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21245 (clobber (reg:CC FLAGS_REG))])]
21247 if (!rtx_equal_p (operands[0], operands[1]))
21248 emit_move_insn (operands[0], operands[1]);
21252 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21253 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21254 (match_operand:HI 2 "immediate_operand" "")))
21255 (clobber (reg:CC FLAGS_REG))])
21256 (match_scratch:HI 3 "r")]
21257 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21258 [(set (match_dup 3) (match_dup 2))
21259 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21260 (clobber (reg:CC FLAGS_REG))])]
21262 if (!rtx_equal_p (operands[0], operands[1]))
21263 emit_move_insn (operands[0], operands[1]);
21266 ;; After splitting up read-modify operations, array accesses with memory
21267 ;; operands might end up in form:
21269 ;; movl 4(%esp), %edx
21271 ;; instead of pre-splitting:
21273 ;; addl 4(%esp), %eax
21275 ;; movl 4(%esp), %edx
21276 ;; leal (%edx,%eax,4), %eax
21279 [(parallel [(set (match_operand 0 "register_operand" "")
21280 (ashift (match_operand 1 "register_operand" "")
21281 (match_operand 2 "const_int_operand" "")))
21282 (clobber (reg:CC FLAGS_REG))])
21283 (set (match_operand 3 "register_operand")
21284 (match_operand 4 "x86_64_general_operand" ""))
21285 (parallel [(set (match_operand 5 "register_operand" "")
21286 (plus (match_operand 6 "register_operand" "")
21287 (match_operand 7 "register_operand" "")))
21288 (clobber (reg:CC FLAGS_REG))])]
21289 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21290 /* Validate MODE for lea. */
21291 && ((!TARGET_PARTIAL_REG_STALL
21292 && (GET_MODE (operands[0]) == QImode
21293 || GET_MODE (operands[0]) == HImode))
21294 || GET_MODE (operands[0]) == SImode
21295 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21296 /* We reorder load and the shift. */
21297 && !rtx_equal_p (operands[1], operands[3])
21298 && !reg_overlap_mentioned_p (operands[0], operands[4])
21299 /* Last PLUS must consist of operand 0 and 3. */
21300 && !rtx_equal_p (operands[0], operands[3])
21301 && (rtx_equal_p (operands[3], operands[6])
21302 || rtx_equal_p (operands[3], operands[7]))
21303 && (rtx_equal_p (operands[0], operands[6])
21304 || rtx_equal_p (operands[0], operands[7]))
21305 /* The intermediate operand 0 must die or be same as output. */
21306 && (rtx_equal_p (operands[0], operands[5])
21307 || peep2_reg_dead_p (3, operands[0]))"
21308 [(set (match_dup 3) (match_dup 4))
21309 (set (match_dup 0) (match_dup 1))]
21311 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21312 int scale = 1 << INTVAL (operands[2]);
21313 rtx index = gen_lowpart (Pmode, operands[1]);
21314 rtx base = gen_lowpart (Pmode, operands[3]);
21315 rtx dest = gen_lowpart (mode, operands[5]);
21317 operands[1] = gen_rtx_PLUS (Pmode, base,
21318 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21320 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21321 operands[0] = dest;
21324 ;; Call-value patterns last so that the wildcard operand does not
21325 ;; disrupt insn-recog's switch tables.
21327 (define_insn "*call_value_pop_0"
21328 [(set (match_operand 0 "" "")
21329 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21330 (match_operand:SI 2 "" "")))
21331 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21332 (match_operand:SI 3 "immediate_operand" "")))]
21335 if (SIBLING_CALL_P (insn))
21338 return "call\t%P1";
21340 [(set_attr "type" "callv")])
21342 (define_insn "*call_value_pop_1"
21343 [(set (match_operand 0 "" "")
21344 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21345 (match_operand:SI 2 "" "")))
21346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21347 (match_operand:SI 3 "immediate_operand" "i")))]
21350 if (constant_call_address_operand (operands[1], Pmode))
21352 if (SIBLING_CALL_P (insn))
21355 return "call\t%P1";
21357 if (SIBLING_CALL_P (insn))
21360 return "call\t%A1";
21362 [(set_attr "type" "callv")])
21364 (define_insn "*call_value_0"
21365 [(set (match_operand 0 "" "")
21366 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21367 (match_operand:SI 2 "" "")))]
21370 if (SIBLING_CALL_P (insn))
21373 return "call\t%P1";
21375 [(set_attr "type" "callv")])
21377 (define_insn "*call_value_0_rex64"
21378 [(set (match_operand 0 "" "")
21379 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21380 (match_operand:DI 2 "const_int_operand" "")))]
21383 if (SIBLING_CALL_P (insn))
21386 return "call\t%P1";
21388 [(set_attr "type" "callv")])
21390 (define_insn "*call_value_0_rex64_ms_sysv"
21391 [(set (match_operand 0 "" "")
21392 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21393 (match_operand:DI 2 "const_int_operand" "")))
21394 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21395 (clobber (reg:TI 27))
21396 (clobber (reg:TI 28))
21397 (clobber (reg:TI 45))
21398 (clobber (reg:TI 46))
21399 (clobber (reg:TI 47))
21400 (clobber (reg:TI 48))
21401 (clobber (reg:TI 49))
21402 (clobber (reg:TI 50))
21403 (clobber (reg:TI 51))
21404 (clobber (reg:TI 52))
21405 (clobber (reg:DI SI_REG))
21406 (clobber (reg:DI DI_REG))]
21407 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21409 if (SIBLING_CALL_P (insn))
21412 return "call\t%P1";
21414 [(set_attr "type" "callv")])
21416 (define_insn "*call_value_1"
21417 [(set (match_operand 0 "" "")
21418 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21419 (match_operand:SI 2 "" "")))]
21420 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21422 if (constant_call_address_operand (operands[1], Pmode))
21423 return "call\t%P1";
21424 return "call\t%A1";
21426 [(set_attr "type" "callv")])
21428 (define_insn "*sibcall_value_1"
21429 [(set (match_operand 0 "" "")
21430 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21431 (match_operand:SI 2 "" "")))]
21432 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21434 if (constant_call_address_operand (operands[1], Pmode))
21438 [(set_attr "type" "callv")])
21440 (define_insn "*call_value_1_rex64"
21441 [(set (match_operand 0 "" "")
21442 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21443 (match_operand:DI 2 "" "")))]
21444 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21445 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21447 if (constant_call_address_operand (operands[1], Pmode))
21448 return "call\t%P1";
21449 return "call\t%A1";
21451 [(set_attr "type" "callv")])
21453 (define_insn "*call_value_1_rex64_ms_sysv"
21454 [(set (match_operand 0 "" "")
21455 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21456 (match_operand:DI 2 "" "")))
21457 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21458 (clobber (reg:TI 27))
21459 (clobber (reg:TI 28))
21460 (clobber (reg:TI 45))
21461 (clobber (reg:TI 46))
21462 (clobber (reg:TI 47))
21463 (clobber (reg:TI 48))
21464 (clobber (reg:TI 49))
21465 (clobber (reg:TI 50))
21466 (clobber (reg:TI 51))
21467 (clobber (reg:TI 52))
21468 (clobber (reg:DI SI_REG))
21469 (clobber (reg:DI DI_REG))]
21470 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21472 if (constant_call_address_operand (operands[1], Pmode))
21473 return "call\t%P1";
21474 return "call\t%A1";
21476 [(set_attr "type" "callv")])
21478 (define_insn "*call_value_1_rex64_large"
21479 [(set (match_operand 0 "" "")
21480 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21481 (match_operand:DI 2 "" "")))]
21482 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21484 [(set_attr "type" "callv")])
21486 (define_insn "*sibcall_value_1_rex64"
21487 [(set (match_operand 0 "" "")
21488 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21489 (match_operand:DI 2 "" "")))]
21490 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21492 [(set_attr "type" "callv")])
21494 (define_insn "*sibcall_value_1_rex64_v"
21495 [(set (match_operand 0 "" "")
21496 (call (mem:QI (reg:DI R11_REG))
21497 (match_operand:DI 1 "" "")))]
21498 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21500 [(set_attr "type" "callv")])
21502 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21503 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21504 ;; caught for use by garbage collectors and the like. Using an insn that
21505 ;; maps to SIGILL makes it more likely the program will rightfully die.
21506 ;; Keeping with tradition, "6" is in honor of #UD.
21507 (define_insn "trap"
21508 [(trap_if (const_int 1) (const_int 6))]
21510 { return ASM_SHORT "0x0b0f"; }
21511 [(set_attr "length" "2")])
21513 (define_expand "sse_prologue_save"
21514 [(parallel [(set (match_operand:BLK 0 "" "")
21515 (unspec:BLK [(reg:DI 21)
21522 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21523 (use (match_operand:DI 1 "register_operand" ""))
21524 (use (match_operand:DI 2 "immediate_operand" ""))
21525 (use (label_ref:DI (match_operand 3 "" "")))])]
21529 (define_insn "*sse_prologue_save_insn"
21530 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21531 (match_operand:DI 4 "const_int_operand" "n")))
21532 (unspec:BLK [(reg:DI 21)
21539 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21540 (use (match_operand:DI 1 "register_operand" "r"))
21541 (use (match_operand:DI 2 "const_int_operand" "i"))
21542 (use (label_ref:DI (match_operand 3 "" "X")))]
21544 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21545 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21548 operands[0] = gen_rtx_MEM (Pmode,
21549 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21550 /* VEX instruction with a REX prefix will #UD. */
21551 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21552 gcc_unreachable ();
21554 output_asm_insn ("jmp\t%A1", operands);
21555 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21557 operands[4] = adjust_address (operands[0], DImode, i*16);
21558 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21559 PUT_MODE (operands[4], TImode);
21560 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21561 output_asm_insn ("rex", operands);
21562 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21564 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21565 CODE_LABEL_NUMBER (operands[3]));
21568 [(set_attr "type" "other")
21569 (set_attr "length_immediate" "0")
21570 (set_attr "length_address" "0")
21571 (set (attr "length")
21573 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21574 (const_string "34")
21575 (const_string "42")))
21576 (set_attr "memory" "store")
21577 (set_attr "modrm" "0")
21578 (set_attr "prefix" "maybe_vex")
21579 (set_attr "mode" "DI")])
21581 (define_expand "prefetch"
21582 [(prefetch (match_operand 0 "address_operand" "")
21583 (match_operand:SI 1 "const_int_operand" "")
21584 (match_operand:SI 2 "const_int_operand" ""))]
21585 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21587 int rw = INTVAL (operands[1]);
21588 int locality = INTVAL (operands[2]);
21590 gcc_assert (rw == 0 || rw == 1);
21591 gcc_assert (locality >= 0 && locality <= 3);
21592 gcc_assert (GET_MODE (operands[0]) == Pmode
21593 || GET_MODE (operands[0]) == VOIDmode);
21595 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21596 supported by SSE counterpart or the SSE prefetch is not available
21597 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21599 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21600 operands[2] = GEN_INT (3);
21602 operands[1] = const0_rtx;
21605 (define_insn "*prefetch_sse"
21606 [(prefetch (match_operand:SI 0 "address_operand" "p")
21608 (match_operand:SI 1 "const_int_operand" ""))]
21609 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21611 static const char * const patterns[4] = {
21612 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21615 int locality = INTVAL (operands[1]);
21616 gcc_assert (locality >= 0 && locality <= 3);
21618 return patterns[locality];
21620 [(set_attr "type" "sse")
21621 (set_attr "memory" "none")])
21623 (define_insn "*prefetch_sse_rex"
21624 [(prefetch (match_operand:DI 0 "address_operand" "p")
21626 (match_operand:SI 1 "const_int_operand" ""))]
21627 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21629 static const char * const patterns[4] = {
21630 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21633 int locality = INTVAL (operands[1]);
21634 gcc_assert (locality >= 0 && locality <= 3);
21636 return patterns[locality];
21638 [(set_attr "type" "sse")
21639 (set_attr "memory" "none")])
21641 (define_insn "*prefetch_3dnow"
21642 [(prefetch (match_operand:SI 0 "address_operand" "p")
21643 (match_operand:SI 1 "const_int_operand" "n")
21645 "TARGET_3DNOW && !TARGET_64BIT"
21647 if (INTVAL (operands[1]) == 0)
21648 return "prefetch\t%a0";
21650 return "prefetchw\t%a0";
21652 [(set_attr "type" "mmx")
21653 (set_attr "memory" "none")])
21655 (define_insn "*prefetch_3dnow_rex"
21656 [(prefetch (match_operand:DI 0 "address_operand" "p")
21657 (match_operand:SI 1 "const_int_operand" "n")
21659 "TARGET_3DNOW && TARGET_64BIT"
21661 if (INTVAL (operands[1]) == 0)
21662 return "prefetch\t%a0";
21664 return "prefetchw\t%a0";
21666 [(set_attr "type" "mmx")
21667 (set_attr "memory" "none")])
21669 (define_expand "stack_protect_set"
21670 [(match_operand 0 "memory_operand" "")
21671 (match_operand 1 "memory_operand" "")]
21674 #ifdef TARGET_THREAD_SSP_OFFSET
21676 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21677 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21679 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21680 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21683 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21685 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21690 (define_insn "stack_protect_set_si"
21691 [(set (match_operand:SI 0 "memory_operand" "=m")
21692 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21693 (set (match_scratch:SI 2 "=&r") (const_int 0))
21694 (clobber (reg:CC FLAGS_REG))]
21696 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21697 [(set_attr "type" "multi")])
21699 (define_insn "stack_protect_set_di"
21700 [(set (match_operand:DI 0 "memory_operand" "=m")
21701 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21702 (set (match_scratch:DI 2 "=&r") (const_int 0))
21703 (clobber (reg:CC FLAGS_REG))]
21705 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21706 [(set_attr "type" "multi")])
21708 (define_insn "stack_tls_protect_set_si"
21709 [(set (match_operand:SI 0 "memory_operand" "=m")
21710 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21711 (set (match_scratch:SI 2 "=&r") (const_int 0))
21712 (clobber (reg:CC FLAGS_REG))]
21714 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21715 [(set_attr "type" "multi")])
21717 (define_insn "stack_tls_protect_set_di"
21718 [(set (match_operand:DI 0 "memory_operand" "=m")
21719 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21720 (set (match_scratch:DI 2 "=&r") (const_int 0))
21721 (clobber (reg:CC FLAGS_REG))]
21724 /* The kernel uses a different segment register for performance reasons; a
21725 system call would not have to trash the userspace segment register,
21726 which would be expensive */
21727 if (ix86_cmodel != CM_KERNEL)
21728 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21730 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21732 [(set_attr "type" "multi")])
21734 (define_expand "stack_protect_test"
21735 [(match_operand 0 "memory_operand" "")
21736 (match_operand 1 "memory_operand" "")
21737 (match_operand 2 "" "")]
21740 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21741 ix86_compare_op0 = operands[0];
21742 ix86_compare_op1 = operands[1];
21743 ix86_compare_emitted = flags;
21745 #ifdef TARGET_THREAD_SSP_OFFSET
21747 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21748 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21750 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21751 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21754 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21756 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21758 emit_jump_insn (gen_beq (operands[2]));
21762 (define_insn "stack_protect_test_si"
21763 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21764 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21765 (match_operand:SI 2 "memory_operand" "m")]
21767 (clobber (match_scratch:SI 3 "=&r"))]
21769 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21770 [(set_attr "type" "multi")])
21772 (define_insn "stack_protect_test_di"
21773 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21774 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21775 (match_operand:DI 2 "memory_operand" "m")]
21777 (clobber (match_scratch:DI 3 "=&r"))]
21779 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21780 [(set_attr "type" "multi")])
21782 (define_insn "stack_tls_protect_test_si"
21783 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21784 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21785 (match_operand:SI 2 "const_int_operand" "i")]
21786 UNSPEC_SP_TLS_TEST))
21787 (clobber (match_scratch:SI 3 "=r"))]
21789 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21790 [(set_attr "type" "multi")])
21792 (define_insn "stack_tls_protect_test_di"
21793 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21794 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21795 (match_operand:DI 2 "const_int_operand" "i")]
21796 UNSPEC_SP_TLS_TEST))
21797 (clobber (match_scratch:DI 3 "=r"))]
21800 /* The kernel uses a different segment register for performance reasons; a
21801 system call would not have to trash the userspace segment register,
21802 which would be expensive */
21803 if (ix86_cmodel != CM_KERNEL)
21804 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21806 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21808 [(set_attr "type" "multi")])
21810 (define_mode_iterator CRC32MODE [QI HI SI])
21811 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21812 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21814 (define_insn "sse4_2_crc32<mode>"
21815 [(set (match_operand:SI 0 "register_operand" "=r")
21817 [(match_operand:SI 1 "register_operand" "0")
21818 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21821 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21822 [(set_attr "type" "sselog1")
21823 (set_attr "prefix_rep" "1")
21824 (set_attr "prefix_extra" "1")
21825 (set_attr "mode" "SI")])
21827 (define_insn "sse4_2_crc32di"
21828 [(set (match_operand:DI 0 "register_operand" "=r")
21830 [(match_operand:DI 1 "register_operand" "0")
21831 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21833 "TARGET_SSE4_2 && TARGET_64BIT"
21834 "crc32q\t{%2, %0|%0, %2}"
21835 [(set_attr "type" "sselog1")
21836 (set_attr "prefix_rep" "1")
21837 (set_attr "prefix_extra" "1")
21838 (set_attr "mode" "DI")])
21842 (include "sync.md")